无法加载功能

时间:2016-03-25 12:23:23

标签: php routes

我尝试生成带有另一个类的URL 错误消息是:

  

注意:未定义的变量:用户输入   第260行/var/www/html/lab/system/core/Router.php

     

警告:call_user_func_array()期望参数1有效   回调,第一个数组成员不是有效的类名或对象   第260行/var/www/html/lab/system/core/Router.php

Router.php:

<?php
require_once 'class.php';
class AltoRouter {
    /**
     * @var array Array of all routes (incl. named routes).
     */
    protected $routes = array();
    /**
     * @var array Array of all named routes.
     */
    protected $namedRoutes = array();
    /**
     * @var string Can be used to ignore leading part of the Request URL (if main file lives in subdirectory of host)
     */
    protected $basePath = '';
    /**
     * @var array Array of default match types (regex helpers)
     */
    protected $matchTypes = array(
        'i'  => '[0-9]++',
        'a'  => '[0-9A-Za-z]++',
        'h'  => '[0-9A-Fa-f]++',
        '*'  => '.+?',
        '**' => '.++',
        ''   => '[^/\.]++'
    );
    /**
      * Create router in one call from config.
      *
      * @param array $routes
      * @param string $basePath
      * @param array $matchTypes
      */
    public function __construct( $routes = array(), $basePath = '', $matchTypes = array() ) {
        $this->addRoutes($routes);
        $this->setBasePath($basePath);
        $this->addMatchTypes($matchTypes);
    }

    /**
     * Retrieves all routes.
     * Useful if you want to process or display routes.
     * @return array All routes.
     */
    public function getRoutes() {
        return $this->routes;
    }
    /**
     * Add multiple routes at once from array in the following format:
     *
     *   $routes = array(
     *      array($method, $route, $target, $name)
     *   );
     *
     * @param array $routes
     * @return void
     * @author Koen Punt
     * @throws Exception
     */
    public function addRoutes($routes){
        if(!is_array($routes) && !$routes instanceof Traversable) {
            throw new \Exception('Routes should be an array or an instance of Traversable');
        }
        foreach($routes as $route) {
            call_user_func_array(array($this, 'map'), $route);
        }
    }
    /**
     * Set the base path.
     * Useful if you are running your application from a subdirectory.
     */
    public function setBasePath($basePath) {
        $this->basePath = $basePath;
    }
    /**
     * Add named match types. It uses array_merge so keys can be overwritten.
     *
     * @param array $matchTypes The key is the name and the value is the regex.
     */
    public function addMatchTypes($matchTypes) {
        $this->matchTypes = array_merge($this->matchTypes, $matchTypes);
    }
    /**
     * Map a route to a target
     *
     * @param string $method One of 5 HTTP Methods, or a pipe-separated list of multiple HTTP Methods (GET|POST|PATCH|PUT|DELETE)
     * @param string $route The route regex, custom regex must start with an @. You can use multiple pre-set regex filters, like [i:id]
     * @param mixed $target The target where this route should point to. Can be anything.
     * @param string $name Optional name of this route. Supply if you want to reverse route this url in your application.
     * @throws Exception
     */
    public function map($method, $route, $target, $name = null) {
        $this->routes[] = array($method, $route, $target, $name);
        if($name) {
            if(isset($this->namedRoutes[$name])) {
                throw new \Exception("Can not redeclare route '{$name}'");
            } else {
                $this->namedRoutes[$name] = $route;
            }
        }
        return;
    }
    /**
     * Reversed routing
     *
     * Generate the URL for a named route. Replace regexes with supplied parameters
     *
     * @param string $routeName The name of the route.
     * @param array @params Associative array of parameters to replace placeholders with.
     * @return string The URL of the route with named parameters in place.
     * @throws Exception
     */
    public function generate($routeName, array $params = array()) {
        // Check if named route exists
        if(!isset($this->namedRoutes[$routeName])) {
            throw new \Exception("Route '{$routeName}' does not exist.");
        }
        // Replace named parameters
        $route = $this->namedRoutes[$routeName];

        // prepend base path to route url again
        $url = $this->basePath . $route;
        if (preg_match_all('`(/|\.|)\[([^:\]]*+)(?::([^:\]]*+))?\](\?|)`', $route, $matches, PREG_SET_ORDER)) {
            foreach($matches as $match) {
                list($block, $pre, $type, $param, $optional) = $match;
                if ($pre) {
                    $block = substr($block, 1);
                }
                if(isset($params[$param])) {
                    $url = str_replace($block, $params[$param], $url);
                } elseif ($optional) {
                    $url = str_replace($pre . $block, '', $url);
                }
            }
        }
        return $url;
    }
    /**
     * Match a given Request Url against stored routes
     * @param string $requestUrl
     * @param string $requestMethod
     * @return array|boolean Array with route information on success, false on failure (no match).
     */
    public function match($requestUrl = null, $requestMethod = null) {
        $params = array();
        $match = false;
        // set Request Url if it isn't passed as parameter
        if($requestUrl === null) {
            $requestUrl = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '/';
        }
        // strip base path from request url
        $requestUrl = substr($requestUrl, strlen($this->basePath));
        // Strip query string (?a=b) from Request Url
        if (($strpos = strpos($requestUrl, '?')) !== false) {
            $requestUrl = substr($requestUrl, 0, $strpos);
        }
        // set Request Method if it isn't passed as a parameter
        if($requestMethod === null) {
            $requestMethod = isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : 'GET';
        }
        foreach($this->routes as $handler) {
            list($method, $_route, $target, $name) = $handler;
            $methods = explode('|', $method);
            $method_match = false;
            // Check if request method matches. If not, abandon early. (CHEAP)
            foreach($methods as $method) {
                if (strcasecmp($requestMethod, $method) === 0) {
                    $method_match = true;
                    break;
                }
            }
            // Method did not match, continue to next route.
            if(!$method_match) continue;
            // Check for a wildcard (matches all)
            if ($_route === '*') {
                $match = true;
            } elseif (isset($_route[0]) && $_route[0] === '@') {
                $pattern = '`' . substr($_route, 1) . '`u';
                $match = preg_match($pattern, $requestUrl, $params);
            } else {
                $route = null;
                $regex = false;
                $j = 0;
                $n = isset($_route[0]) ? $_route[0] : null;
                $i = 0;
                // Find the longest non-regex substring and match it against the URI
                while (true) {
                    if (!isset($_route[$i])) {
                        break;
                    } elseif (false === $regex) {
                        $c = $n;
                        $regex = $c === '[' || $c === '(' || $c === '.';
                        if (false === $regex && false !== isset($_route[$i+1])) {
                            $n = $_route[$i + 1];
                            $regex = $n === '?' || $n === '+' || $n === '*' || $n === '{';
                        }
                        if (false === $regex && $c !== '/' && (!isset($requestUrl[$j]) || $c !== $requestUrl[$j])) {
                            continue 2;
                        }
                        $j++;
                    }
                    $route .= $_route[$i++];
                }
                $regex = $this->compileRoute($route);
                $match = preg_match($regex, $requestUrl, $params);
            }
            if(($match == true || $match > 0)) {
                if($params) {
                    foreach($params as $key => $value) {
                        if(is_numeric($key)) unset($params[$key]);
                    }
                }
                return array(
                    'target' => $target,
                    'params' => $params,
                    'name' => $name
                );
            }
        }
        return false;
    }
    /**
     * Compile the regex for a given route (EXPENSIVE)
     */
    private function compileRoute($route) {
        if (preg_match_all('`(/|\.|)\[([^:\]]*+)(?::([^:\]]*+))?\](\?|)`', $route, $matches, PREG_SET_ORDER)) {
            $matchTypes = $this->matchTypes;
            foreach($matches as $match) {
                list($block, $pre, $type, $param, $optional) = $match;
                if (isset($matchTypes[$type])) {
                    $type = $matchTypes[$type];
                }
                if ($pre === '.') {
                    $pre = '\.';
                }
                //Older versions of PCRE require the 'P' in (?P<named>)
                $pattern = '(?:'
                        . ($pre !== '' ? $pre : null)
                        . '('
                        . ($param !== '' ? "?P<$param>" : null)
                        . $type
                        . '))'
                        . ($optional !== '' ? '?' : null);
                $route = str_replace($block, $pattern, $route);
            }
        }
        return "`^$route$`u";
    }
}
$router = new AltoRouter();
$user = new Users();
$router->setBasePath('/lab/system/core/Router.php');
############################################################
$router->map('GET', '/home', function()
{
    echo 'Home page';
}, 'home');
$router->map('GET', '/user', function()
{
    call_user_func_array(array($user, 'user'), array());
}, 'user');
############################################################
$match = $router->match();
if($match && is_callable($match['target']))
{
    call_user_func_array($match['target'], $match['params']);
}
else
{
    echo "404 Not Found";
}
?>

class.php

<?php
class Users
{
    function user()
    {
        echo "User page";
    }
}
?>
任何人都可以解释一下吗?感谢

1 个答案:

答案 0 :(得分:-1)

你试过这个吗?

$router->map('GET', '/user', function($user)
{
    call_user_func_array(array($user, 'user'), array());
}, 'user');