PHP MVC"路由未找到"

时间:2017-11-06 15:34:34

标签: php url-routing

我正在使用php mvc,当我尝试编辑特定行时,它说,"没有路由匹配"但路线定义明确。 这是匹配的路线 $路由器 - >添加(' {控制器} / {ID:\ d +} / {动作}&#39);

这里是 Router.php。

  <?php
  namespace Core;
  /**
  *Router
  */
  class Router
  {
    protected  $routes = [];

    //saves the parameter from the matched route
    protected  $params = [];

    /**
    *Below, params=[] indicates that the paramentes in the url can be empty
    */
   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;
      }

    /**
    *matches the route and sets the parameters
    * $url: The route URL
    * returns true is match is found else flase
    */
    public function match($url)
    {
      //Matches to the fixed URL format /controller/action
      //$reg_exp = "/^(?P<controller>[a-z-]+)\/(?P<action>[a-z-]+)$/";

      foreach ($this->routes as $route => $params) {
        if (preg_match($route, $url, $matches))
        {
          //get named capture group values
          //$params = [];

          foreach ($matches as $key => $match) {
            if (is_string($key))
            {
              $params[$key] = $match;
            }
          }
          $this->params = $params;
          return true;
        }
      }
      return false;
    }
    // foreach ($this->routes as $route => $params) {
    //   if ($url == $route) {
    //     $this->params = $params;
    //     return true;
    //   }
    // }
    //   return false;


    // if (preg_match($reg_exp, $url, $matches))
    // {
    //
    //
    // }


    //gets the currently matched parameters
    public function getParams()
    {
      return $this->params;
    }

    public function dispatch($url)
    {
      $url = $this->removeQueryStringVariables($url);

      if($this->match($url)){
        $controller = $this->params['controller'];
        $controller = $this->convertToStudlyCaps($controller); //Text can easily be converted from uppercase or lowercase to sTudLYcAPs

        //$controller = "App\Controllers\\$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");
      }
    }



    /**
    *Convert the string with hypens to StudlyCaps,
    *e.g. post-authors => PostAuthors
    */
    protected function convertToStudlyCaps($string)
    {
      return str_replace(' ', '', ucwords(str_replace('-', ' ', $string)));
    }

    /**
    *Convert the string with hypens to camelCase,
    *e.g. add-new => addNew
    */
    protected function convertToCamelCase($string)
    {
      return lcfirst($this->convertToStudlyCaps($string));
    }


    /**
    *This removes query string variable i.e. posts/index&page=1 => posts/index
    *
    */
    protected function removeQueryStringVariables($url)
    {
      if($url != '')
      {
        $parts = explode('&', $url, 2);

        if(strpos($parts[0], '=') === false){
          $url = $parts[0];
        }
        else{
          $url = '';
        }
      }
      return $url;
    }


    /*
    *Get the namespace for the controller class. The namespace defined in the
    *route parameters is added if present.
    */
    protected function getNameSpace()
    {
      $namespace = 'App\Controllers\\';

      if(array_key_exists('namespace', $this->params))
      {
        $namespace .= $this->params['namespace'] . '\\';
      }
      return $namespace;
    }

  }

  ?>

P.S。我可以向数据库添加值但不能编辑它,因为它表示路由不匹配。如果它有帮助,这里是index.php:

  <?php

  /**
  * FIRST CONTROLLER
  *
  */
  /**
  *Twig
  */
  require_once dirname(__DIR__) . '/vendor/Twig/lib/Twig/autoload.php';
  Twig_Autoloader::register();

  /**
  *AutoLoader
  *
  */
  spl_autoload_register(function ($class){
      $root = dirname(__DIR__); //gets the parent directory
      $file = $root . '/' . str_replace('\\', '/', $class) . '.php';
      if (is_readable($file))
      {
        require $root . '/' . str_replace('\\', '/', $class) . '.php';
      }
    });


  /**
  *Error and Exception handling
  *
  */
  error_reporting(E_ALL);
  set_error_handler('Core\Error::errorHandler');
  set_exception_handler('Core\Error::exceptionHandler');
  /**
  *Routing
  *
  */
  //require '../Core/Router.php';
  $router = new Core\Router();

  //Routes
  $router->add('', ['controller' => 'Home', 'action' => 'index']);
  $router->add('{controller}/{action}');


  $router->add('admin/{controller}/{action}', ['namespace' => 'Admin']);
  $router->add('{controller}/{id:\d+}/{action}');

  $router ->dispatch($_SERVER['QUERY_STRING']);


  /*
  // Display the routing table
  echo '<pre>';
  //var_dump($router->getRoutes());
  echo htmlspecialchars(print_r($router->getRoutes(),true));
  echo '<pre>';

  //Match the requested route
  $url = $_SERVER['QUERY_STRING'];

  if ($router->match($url)) {
    echo '<pre>';
    var_dump($router->getParams());
    echo '<pre>';
  }else{
    echo "No Route Found For URL '$url'";
  }
  */
  ?>

0 个答案:

没有答案