社交网站的PHP路由系统

时间:2015-04-07 10:37:44

标签: php mysql url

我一直在阅读社交网站,我看过Twitter,LinkedIn,Facebook等等。像其他站点一样,这些站点使用某种类型的路由来加载不同的模块,具体取决于站点URL。

E.g。 http://www.something.com/notificiation/ {ID}

上面的url会加载处理通知的模块,并给出一个{id}它将呈现并返回具有更深入细节的特定通知。

任何人都可以指导我通过路由或指向我实际教这个的网站。非常感谢,我非常感谢您的所有支持和帮助。

编辑:好的网址.htaccess不是问题,我已经知道这部分了。我对路由部分本身很好奇。

4 个答案:

答案 0 :(得分:2)

.htaccess文件和重写将成为你的朋友。这将是:

RewriteEngine On

RewriteRule ^/notification/(.*)$ getNotification.php?id=$1 [L]

对于.htaccess文件的基础知识,你可以使用谷歌 - 那里有很多。

但是对于一些好的片段,我建议this:)

答案 1 :(得分:1)

您清理ID值并将其放入变量中。然后在switch语句中使用此变量来加载模块或重定向到另一个URL。 ID可以是$ _GET变量。

答案 2 :(得分:1)

会尽力解释。假设:

  1. 请求http://www.example.com/index.php
  2. 如果启用mod_rewrite(Apache)并且将重写URL,例如http://www.example.com
  3. index.php仍有请求可用,处理

    $uri = Router::make_uri();
    
    if ($params = Router::match_uri($uri))
    {
        $controller = ucwords($params['controller']).'_Controller';
        $method = $params['method'];
    
        unset($params['controller'], $params['method']);
    
        if (class_exists($controller) && method_exists($controller, $method))
        {
            call_user_func_array(array(new $controller, $method), $params);
        }
    }
    
  4. Router

    private static $routes;
    
    public static $uri;
    
    public static $segment;
    
    public static function make_uri()
    {
        if(!empty($_SERVER['PATH_INFO']))
        {
            self::$uri = $_SERVER['PATH_INFO'];
        }
        elseif (!empty($_SERVER['REQUEST_URI']))
        {
            self::$uri = $_SERVER['REQUEST_URI'];
    
            if (defined('INDEX') && is_file(INDEX))
            {
                $index_file = INDEX;
            }
            else
            {
                $index_file = 'index.php';
            }
    
            //removing index
            if (strpos(self::$uri, $index_file) !== FALSE)
            {
                self::$uri = str_replace(self::$uri, $index_file, '');
            }
        }
    
        return parse_url(trim(self::$uri, '/'), PHP_URL_PATH);
    }
    
    public static function match_uri($uri)
    {
        require(APP_DIR.DIR_SEP.'system'.DIR_SEP.'config'.DIR_SEP.'Routes.php');
    
        if (empty($routes))
        {
            Error::throw_error('Routes must not be empty');
        }
    
        self::$routes = $routes;
    
        $params = array();
    
        foreach ($routes as $route)
        {
            //we keep our route uri in the [0] position
            $route_uri = array_shift($route);
    
            $regex_uri = self::make_regex_uri($route_uri);
    
            if (!preg_match($regex_uri, $uri, $match))
            {
                continue;
            }
            else
            {               
                foreach ($match as $key => $value)
                {
                    if (is_int($key))
                    {
                        //removing preg_match digit keys
                        continue;
                    }
    
                    $params[$key] = $value;
                }
    
                //if no values are set, load default ones
                foreach ($route as $key => $value)
                {
                    if (!isset($params[$key]))
                    {
                        $params[$key] = $value;
                    }
                }
    
                break;
            }
        }
    
        return $params;
    }
    
    private static function make_regex_uri($uri)
    {
        $reg_escape = '[.\\+*?[^\\]${}=!|]';
        $expression = preg_replace('#'.$reg_escape.'#', '\\\\$0', $uri);
    
        if (strpos($expression, '(') !== FALSE)
        {
            $expression = str_replace(array('(', ')'), array('(?:', ')?'), $expression);
        }
    
        $reg_segment = '[^/.,;?\n]++';
        $expression = str_replace(array('<', '>'), array('(?P<', '>'.$reg_segment.')'), $expression);
    
        return '#^'.$expression.'$#uD';
    }
    
    public static function make_url($route_name = '', $params = array())
    {
        if (!$routes = self::$routes)
        {
            require(APP_DIR.DIR_SEP.'system'.DIR_SEP.'config'.DIR_SEP.'Routes.php');
        }
    
        if (!in_array($route_name, array_keys($routes)))
        {
            return BASE_URL;
        }
        else
        {
            $route = $routes[$route_name];
            $uri = array_shift($route);
    
            //replace given params
            foreach ($params as $key => $value)
            {
                $string = '<'.$key.'>';
                if (strpos($uri, $string) !== FALSE)
                {
                    $uri = str_replace($string, $value, $uri);
                }
            }
    
            //replace initial params
            if (strpos($uri, '<') !== FALSE)
            {
                foreach ($route as $key => $value)
                {
                    $string = '<'.$key.'>';
                    if (strpos($uri, $string) !== FALSE)
                    {
                        $uri = str_replace($string, $value, $uri);
                    }
                }
            }
    
            //if any undefined variable exists return BASE_URL
            if (strpos($uri, '<') !== FALSE)
            {
                return BASE_URL;
            }
            else
            {
                return rtrim(BASE_URL.str_replace(array('(', ')'), '', $uri), '/');
            }
        }
    }
    
    public static function get_segment($segment = TRUE)
    {
        if (isset($_SERVER['REQUEST_URI']))
        {
            $segments = explode('/', self::make_uri());
    
            $segments_count = count($segments);
    
            if ($segment === TRUE || $segment >= $segments_count || $segment < 0)
            {
                return self::$segment = $segments[$segments_count - 1];
            }
            else
            {
                return self::$segment = $segments[$segment];
            }
        }
        else
        {
            return FALSE;
        }
    }
    
  5. 说明:基于数据uri变量包含的当前make_uri_SERVER)。假设BASE_URLhttp://www.example.commake_uri将返回空字符串''

  6. uri与预设规则Routes匹配。例如,Routes.php

    $routes['home'] = array(
    '',
    'controller' => 'main',
    'method' => 'home'
    );
    
  7. 如果找到匹配的路由(针对此特定情况,''模式),params将被清理(删除preg_match个冗余)并返回(控制器数组) ,方法和方法参数)以enter code here为准。在这种情况下,http://www.example.com将由Main_Controller处理,方法home未提供方法参数。

答案 3 :(得分:0)

这有两个阶段。

第1阶段

可以使用.htaccess重写规则实现的虚荣URL。例如,我们获取虚荣URL并重写它以加载我们的控制器 - 这反过来加载我们的模型和视图。

RewriteEngine On
RewriteRule ^/notification/(0-9*)$ index.php?controller=notification&action=getNotification&id=$1 [L]

第2阶段

一个好的设计模式 - 比如MVC - 将能够很好地路由我们的请求。我们的路由器看起来像这样(这将是更多的PHP伪代码,但你明白了。)

<?php

if( isset($_GET['controller']) ) {
  if( Utils::ControllerExists( $_GET['controller'].'Controller.php' ) ) {
      $objController = Utils::LoadController( $_GET['controller'].'Controller.php' );

      //Check the method exists 
      if( method_exists($objController, $_GET['action']) ) {
          //Simple method. But will need to know the parameters needed.
          $strOutput = $objController->{$_GET['action']}({$_GET['id']});
          Utils::LoadView('HTML', $strOutput);
          die;
      }

  } 
}

//Redirect to default page?
Utils::Redirect('home');
die;

我们的控制器看起来像;

<?php

class notificationController {

   public function getNotification($intNotificationId) {
        //Query database for notification
        return $return_value;
   }
}

然而...

使用处理路由(以及其他关键元素)的现有框架可能对您有益,例如;