I am building simple php route But I I have the following, which is working
Route::add('/', function(){ echo 'Hello world message'; });
My challange is that… I want to be able to load the function directly from a controller which I am calling
use ControllersLoginController; Route::add('/', LoginController::login());
the login() is a function i created inside LoginController class I get this error
<b>Warning</b>: call_user_func_array() expects parameter 1 to be a valid callback, no array or string given in <b>C:xampphtdocsConfigRoute.php</b> on line <b>75</b><br />
My Route.php
<?php namespace Config; class Route{ private static $routes = Array(); private static $pathNotFound = null; private static $methodNotAllowed = null; public static function add($expression, $function, $method = 'get') { array_push(self::$routes,Array( 'expression' => $expression, 'function' => $function, 'method' => $method )); } public static function pathNotFound($function){ self::$pathNotFound = $function; } public static function methodNotAllowed($function){ self::$methodNotAllowed = $function; } public static function run($basepath = '/') { // Parse current url $parsed_url = parse_url($_SERVER['REQUEST_URI']);//Parse Uri if(isset($parsed_url['path'])){ $path = $parsed_url['path']; }else{ $path = '/'; } // Get current request method $method = $_SERVER['REQUEST_METHOD']; $path_match_found = false; $route_match_found = false; foreach(self::$routes as $route){ // If the method matches check the path // Add basepath to matching string if($basepath!=''&&$basepath!='/'){ $route['expression'] = '('.$basepath.')'.$route['expression']; } // Add 'find string start' automatically //$route['expression'] = '^'.$route['expression']; // Add 'find string end' automatically $route['expression'] = $route['expression'].'$'; //echo $path.'<br/>'; // Check path match if(preg_match('#'.$route['expression'].'#',$path,$matches)){ $path_match_found = true; // Check method match if(strtolower($method) == strtolower($route['method'])){ array_shift($matches);// Always remove first element. This contains the whole string if($basepath!=''&&$basepath!='/'){ array_shift($matches);// Remove basepath } call_user_func_array($route['function'], $matches); $route_match_found = true; // Do not check other routes break; } } } // No matching route was found if(!$route_match_found){ // But a matching path exists if($path_match_found){ header("HTTP/1.0 405 Method Not Allowed"); if(self::$methodNotAllowed){ call_user_func_array(self::$methodNotAllowed, Array($path,$method)); } }else{ header("HTTP/1.0 404 Not Found"); if(self::$pathNotFound){ call_user_func_array(self::$pathNotFound, Array($path)); } } } } }
Is there anyway i can make use of external function inside the route?
Advertisement
Answer
It wants a callback, so you need to pass a function itself. In your case using the parenthesis ()
invokes (calls) the function and returns the result of it instead of passing the function itself.
So here is a simple example of how you could do it:
Route::add('/', LoginController::login);
Wrapping it into a another function enables you to even pass arguments.
// shorthand function syntax since 7.4 Route::add('/', fn() => LoginController::login()); // example arguments (just a prototype) Route::add('/', fn() => LoginController::login($username, $password));
or
Route::add('/', function() { LoginController::login() }); // example arguments (just a prototype) Route::add('/', function() { LoginController::login($username, $password) });