找不到路线。 PHP

Posted

技术标签:

【中文标题】找不到路线。 PHP【英文标题】:Route not found. PHP 【发布时间】:2018-02-24 21:12:43 【问题描述】:

我正在尝试在我自己的 mvc 框架中进行路由。像 /controller/action 这样的简单路由在以下情况下正常工作: index.php

$router = new Core\Router();

//添加路由

$router->add('controller/action');

路由器:

public function add($route, $params = [])
    
        // Convert the route to a regular expression: escape forward slashes
        $route = preg_replace('/\//', '\\/', $route);

        // Convert variables e.g. controller
        $route = preg_replace('/\([a-z]+)\/', '(?P<\1>[a-z-]+)', $route);

        // Convert variables with custom regular expressions e.g. id:\d+
        $route = preg_replace('/\([a-z]+):([^\]+)\/', '(?P<\1>\2)', $route);

        // Add start and end delimiters, and case insensitive flag
        $route = '/^' . $route . '$/i';

        $this->routes[$route] = $params;
    

    /**
     * Get all the routes from the routing table
     *
     * @return array
     */
    public function getRoutes()
    
        return $this->routes;
    

    /**
     * Match the route to the routes in the routing table, setting the $params
     * property if a route is found.
     *
     * @param string $url The route URL
     *
     * @return boolean  true if a match found, false otherwise
     */
    public function match($url)
    
        foreach ($this->routes as $route => $params) 
            if (preg_match($route, $url, $matches)) 
                // Get named capture group values
                foreach ($matches as $key => $match) 
                    if (is_string($key)) 
                        $params[$key] = $match;
                    
                

                $this->params = $params;
                return true;
            
        

        return false;
    

    /**
     * Get the currently matched parameters
     *
     * @return array
     */
    public function getParams()
    
        return $this->params;
    

    /**
     * Dispatch the route, creating the controller object and running the
     * action method
     *
     * @param string $url The route URL
     *
     * @return void
     */
    public function dispatch($url)
    
        $url = $this->removeQueryStringVariables($url);

        if ($this->match($url)) 
            $controller = $this->params['controller'];
            $controller = $this->convertToStudlyCaps($controller);
            $controller = $this->getNamespace() . $controller;

            if (class_exists($controller)) 
                $controller_object = new $controller($this->params);

                $action = $this->params['action'];
                $action = $this->convertToCamelCase($action);

                if (is_callable([$controller_object, $action])) 
                    $controller_object->$action();

                 else 
                    throw new \Exception("Method $action (in controller $controller) not found");
                
             else 
                throw new \Exception("Controller class $controller not found");
            
         else 
            throw new \Exception('No route matched.', 404);
        
    

但是当我尝试在我的 index.php 中添加另一条路线时:/controller/id/action 与:

$router->add('controller/id:\d/action');

显示找不到路由异常。我在这里做错了什么。谁能告诉我如何解决这个问题?

【问题讨论】:

如果你想一路走下去,请记住大多数路由系统需要容纳相当任意数量的路由,甚至数千个,并且仍然表现良好。这通常意味着将所有路由编译成一个紧凑的状态机,或者一个非常复杂的单数正则表达式。 所以生成的正则表达式是:^(?P&lt;controller&gt;[a-z-]+)\/(?P&lt;id&gt;\d)\/(?P&lt;action&gt;[a-z-]+)$。我认为应该是\d+。无论如何,快速的解决方案 - 以已经工作的路由器为例,我喜欢这个 one 您尝试路由到的示例 url 是什么?它会抛出“没有匹配的路线”。例外?另外,你能显示你的 removeQueryStringVariables 函数吗,也许它弄乱了 url? 【参考方案1】:

我遇到了同样的问题。我认为 add 方法中的 if 和 list 是必需的,而在 match 方法中 $param 参数需要 $this-&gt;$params = $param 这是我编写该代码时的错误。

class Router 

    protected $routes = [];
    protected $params  = [];

    public function add($route,$action) 

        $route = preg_replace('/^\//','',$route);
        $route = preg_replace('/\//','\\/',$route);
        $route = preg_replace('/\([a-z]+)\/','(?<\1>[a-z0-9-]+)',$route);
        $route = '/^'. $route .'\/?$/i';

        $action = is_array($action) ? $action ['uses'] : $action;

        list($params['controller'] , $params['method']) = explode('@',$action);

        $this->routes[$route] = $params;
    

      
    public function match($url) 
        foreach ($this->routes as $route => $param) 

            if(preg_match($route , $url , $matchess)) 

                    foreach ($matchess as $key => $match)
                        if(!is_numeric($key)) 
                            $param [$key] = $match;
                        
                    
                $this->params = $param;
                return true;
            
        
        return false;
    

    public function getRoutes(): array 
        return $this->routes;
    

    public function getParams() 
        return $this->params;
    

【讨论】:

我正在学习 MVC,我有同样的问题,我认为 add 方法中的 if 和 list 是必需的,并且在 match 方法中 $param 参数需要 $this->$params = $param 那是我的我写那段代码时的错误。 谢谢,我只是将它添加到您的答案中!

以上是关于找不到路线。 PHP的主要内容,如果未能解决你的问题,请参考以下文章

车队推车在路线中使用中间件,但我在项目中找不到任何 $routemiddleware...甚至在 kernel.php 中也找不到...我在哪里可以找到它?

找不到路线返回页面 Laravel 5.3

Aurelia:找不到路线的名称

在日本找不到公交路线

Rails 路线有时找不到错误

如果在 Laravel 5.1 中找不到路由,则显示 404 页面