社交网站的PHP路由系统


PHP routing system for social site

我一直在阅读有关社交网站的文章,我见过Twitter、LinkedIn、Facebook等。这些网站和其他网站一样,根据网站url使用某种类型的路由来加载不同的模块。

例如。http://www.something.com/notificiation/{id}

上面的url将加载负责通知的模块,并给定{id},它将呈现并返回具有更详细信息的特定通知。

有人能指导我完成路线安排吗?或者给我指一个真正教授这一点的网站。非常感谢,我真的很感谢大家提前给予我的支持和帮助。

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

.htaccess文件和重写将是您的朋友。这将类似于:

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

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

但对于一些好的片段,我建议这样做:)

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

将尝试解释。假设:

  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是在_SERVER变量包含的数据的基础上生成的(make_uri)。假设BASE_URLhttp://www.example.com,则make_uri将返回空字符串''

  6. CCD_ 14与预设规则(也称为CCD_ 15)相匹配。示例,Routes.php

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

这有两个阶段。

第1阶段

虚荣URLS可以通过.htaccess重写规则来实现。例如,我们获取虚荣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;
   }
}

然而

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

  • Laravel
  • Phalcon