简体   繁体   English

如何在 php 路由中使用外部 function

[英]How to use external function in php route

I am building simple php route But II have the following, which is working我正在构建简单的 php 路线但是我有以下,这是工作

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我的挑战是......我希望能够直接从我正在调用的 controller 加载 function

use Controllers\LoginController;

Route::add('/', LoginController::login());

the login() is a function i created inside LoginController class I get this error login() 是我在 LoginController class 中创建的 function 我收到此错误

<b>Warning</b>:  call_user_func_array() expects parameter 1 to be a valid callback, no array or string given in <b>C:\xampp\htdocs\Config\Route.php</b> on line <b>75</b><br />

My Route.php我的路线.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?无论如何我可以在路线内使用外部 function 吗?

It wants a callback, so you need to pass a function itself.它需要一个回调,所以你需要传递一个 function 本身。 In your case using the parenthesis () invokes (calls) the function and returns the result of it instead of passing the function itself.在您的情况下,使用括号()调用(调用) function 并返回它的结果,而不是传递 function 本身。

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.将其包装到另一个 function 中,您甚至可以通过 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) });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM