Easiest way to map route in PHP

前端 未结 3 1556
孤城傲影
孤城傲影 2021-01-23 02:05

I was browsing Symfony\'s website. I didn\'t really feel like I need all the functionality the framework offers, but I did like the routing part. It allows you to specify URL pa

3条回答
  •  无人及你
    2021-01-23 02:28

    I have made my own mini-framework with the same routing syntax. Here's what I do:

    1. Use MOD_REWRITE to store the parameters (like /some/path/{info}) in a $_GET variable I call params:

      RewriteRule ^(.+)(\?.+)?$ index.php?params=$1 [L,QSA]

    2. Parse the parameters and store them globally using this function:

    public static function parseAndGetParams() {
    
            // get the original query string
    
            $params = !empty($_GET['params']) ? $_GET['params'] : false;
    
            // if there are no params, set to false and return
            if(empty($params)) {
                return false;
            }
    
            // append '/' if none found
            if(strrpos($params, '/') === false) $params .= '/';
    
            $params = explode('/', $params);
            // take out the empty element at the end
            if(empty($params[count($params) - 1])) array_pop($params);
    
            return $params;
        }
    
    1. Route to the proper page dynamically:

      // get the base page string, must be done after params are parsed
      public static function getCurPage() {
          global $params;
      
          // default is home
          if(empty($params))
          return self::PAGE_HOME;
          // see if it is an ajax request
          else if($params[0] == self::PAGE_AJAX)
          return self::PAGE_AJAX;
          // see if it is a multi param page, and if not, return error
          else {
              // store this, as we are going to use it in the loop condition
              $numParams = count($params);
      
              // initialize to full params array
              $testParams = $params;
              // $i = number of params to include in the current page name being checked, {1, .., n}
              for($i = $numParams; $i > 0; $i--) {
                  // get test page name
                  $page = strtolower(implode('/', $testParams));
      
                  // if the page exists, return it
                  if(self::pageExists($page))
                      return $page;
      
                  // pop the last param off
                  array_pop($testParams);
              }
      
              // page DNE go to error page
              return self::PAGE_ERROR;
          }
      }
      

    The value here is that it looks for the most specific page to the least specific page. Also, workout outside of a framework gives you complete control so if there's a bug somewhere, you know you can fix it - you don't have to look up some weird workaround in your framework.

    So now that $params is global, any page that uses a parameter simply calls $params[X] to work with it. Friendly URLs without a framework.

    The way I add pages then is I put them into an array that is looked at in the pageExists($page) call.

    For AJAX calls, I put in a special IF:

    // if ajax, include it and finish
    if($page == PageHelper::PAGE_AJAX) {
        PageHelper::includeAjaxPage();
        $db->disconnect();
        exit;
    }
    

    And voila - your own micro routing framework.

提交回复
热议问题