CrossPHP
  • Namespace
  • Class
  • Download

Namespaces

  • Cross
    • Auth
    • Cache
      • Driver
      • Request
    • Core
    • DB
      • Connecter
      • Drivers
      • SQLAssembler
    • Exception
    • Http
    • I
    • Lib
      • Document
    • Module
    • MVC
    • Runtime
  • None

Classes

  • Cross\Auth\CookieAuth
  • Cross\Auth\SessionAuth
  • Cross\Cache\Driver\FileCacheDriver
  • Cross\Cache\Driver\MemcacheDriver
  • Cross\Cache\Driver\RedisDriver
  • Cross\Cache\Request\FileCache
  • Cross\Cache\Request\Memcache
  • Cross\Cache\Request\RedisCache
  • Cross\Cache\RequestCache
  • Cross\Core\Annotate
  • Cross\Core\Application
  • Cross\Core\ArrayMap
  • Cross\Core\Config
  • Cross\Core\CrossArray
  • Cross\Core\Delegate
  • Cross\Core\FrameBase
  • Cross\Core\Helper
  • Cross\Core\HttpAuth
  • Cross\Core\Loader
  • Cross\Core\Rest
  • Cross\Core\Router
  • Cross\DB\Connecter\BaseConnecter
  • Cross\DB\Connecter\MySQLConnecter
  • Cross\DB\Connecter\PgSQLConnecter
  • Cross\DB\Connecter\SQLiteConnecter
  • Cross\DB\DBFactory
  • Cross\DB\Drivers\CouchDriver
  • Cross\DB\Drivers\MongoDriver
  • Cross\DB\Drivers\PDOSqlDriver
  • Cross\DB\SQLAssembler\MySQLAssembler
  • Cross\DB\SQLAssembler\PgSQLAssembler
  • Cross\DB\SQLAssembler\SQLAssembler
  • Cross\DB\SQLAssembler\SQLiteAssembler
  • Cross\Http\Request
  • Cross\Http\Response
  • Cross\Lib\Array2XML
  • Cross\Lib\Document\CallTree
  • Cross\Lib\Document\CallTreeToHTML
  • Cross\Lib\Document\HTML
  • Cross\Lib\StringToPHPStream
  • Cross\Module\SQLModule
  • Cross\MVC\Controller
  • Cross\MVC\Module
  • Cross\MVC\View
  • Cross\Runtime\ClosureContainer

Interfaces

  • Cross\I\CacheInterface
  • Cross\I\HttpAuthInterface
  • Cross\I\PDOConnecter
  • Cross\I\RequestCacheInterface
  • Cross\I\RouterInterface
  • Cross\I\SqlInterface

Exceptions

  • Cross\Exception\CacheException
  • Cross\Exception\CoreException
  • Cross\Exception\CrossException
  • Cross\Exception\FrontException

Functions

  • ascLogo
  • line
  • tBody
  • th
  • tHead
  1 <?php
  2 /**
  3  * Cross - a micro PHP 5 framework
  4  *
  5  * @link        http://www.crossphp.com
  6  * @license     MIT License
  7  */
  8 
  9 namespace Cross\Core;
 10 
 11 use Cross\I\RouterInterface;
 12 use Cross\Exception\FrontException;
 13 use Cross\Exception\CoreException;
 14 use Cross\Http\Request;
 15 
 16 /**
 17  * @author wonli <wonli@live.com>
 18  * Class Router
 19  * @package Cross\Core
 20  */
 21 class Router implements RouterInterface
 22 {
 23     /**
 24      * Action名称
 25      *
 26      * @var string
 27      */
 28     private $action;
 29 
 30     /**
 31      * 控制器名称
 32      *
 33      * @var string
 34      */
 35     private $controller;
 36 
 37     /**
 38      * url参数
 39      *
 40      * @var array
 41      */
 42     private $params = array();
 43 
 44     /**
 45      * @var string
 46      */
 47     private $uriRequest;
 48 
 49     /**
 50      * @var string
 51      */
 52     private $originUriRequest;
 53 
 54     /**
 55      * @var Config
 56      */
 57     private $config;
 58 
 59     /**
 60      * @var Delegate
 61      */
 62     private $delegate;
 63 
 64     /**
 65      * @var array
 66      */
 67     private $defaultRouter = array();
 68 
 69     /**
 70      * 默认Action名称
 71      */
 72     const DEFAULT_ACTION = 'index';
 73 
 74     /**
 75      * Router constructor.
 76      * @param Delegate $delegate
 77      */
 78     function __construct(Delegate &$delegate)
 79     {
 80         $this->delegate = $delegate;
 81         $this->config = $delegate->getConfig();
 82     }
 83 
 84     /**
 85      * Router
 86      *
 87      * @return $this
 88      * @throws CoreException
 89      * @throws FrontException
 90      */
 91     public function getRouter()
 92     {
 93         $rs = $this->getUriRequest('', $url_config);
 94         if (!empty($rs)) {
 95             $request = $this->parseRequestString($rs, $url_config);
 96             $closure = $this->delegate->getClosureContainer();
 97             if ($closure->has('router')) {
 98                 $closure->run('router', array($request, $this));
 99             }
100 
101             if (empty($this->controller) || empty($this->action)) {
102                 $this->parseRouter($request, $url_config);
103             }
104         } else {
105             $router = $this->parseDefaultRouter($url_config['*']);
106             $this->setController($router[0]);
107             $this->setAction($router[1]);
108 
109             $params = $this->parseParams(array(), $url_config);
110             $this->setParams($params);
111         }
112 
113         return $this;
114     }
115 
116     /**
117      * 使用默认路由
118      *
119      * @throws CoreException
120      */
121     function useDefaulterRouter()
122     {
123         $router = $this->getDefaultRouter();
124         $this->setController($router[0]);
125         $this->setAction($router[1]);
126     }
127 
128     /**
129      * 获取默认控制器
130      *
131      * @return array
132      * @throws CoreException
133      */
134     function getDefaultRouter()
135     {
136         if (empty($this->defaultRouter)) {
137             $url_config = $this->config->get('url');
138             $this->parseDefaultRouter($url_config['*']);
139         }
140 
141         return $this->defaultRouter;
142     }
143 
144     /**
145      * 返回控制器名称
146      *
147      * @return mixed
148      */
149     public function getController()
150     {
151         return $this->controller;
152     }
153 
154     /**
155      * 返回action名称
156      *
157      * @return mixed
158      */
159     public function getAction()
160     {
161         return $this->action;
162     }
163 
164     /**
165      * 返回参数
166      *
167      * @return mixed
168      */
169     public function getParams()
170     {
171         return $this->params;
172     }
173 
174     /**
175      * 按类型解析请求字符串
176      *
177      * @param string $prefix
178      * @param array $url_config
179      * @param bool $clear_ampersand
180      * @param bool $convert_html_entities
181      * @return string
182      * @throws CoreException
183      */
184     public function getUriRequest($prefix = '/', &$url_config = array(), $clear_ampersand = true, $convert_html_entities = true)
185     {
186         $url_config = $this->config->get('url');
187         if (!empty($this->uriRequest)) {
188             return $this->uriRequest;
189         }
190 
191         switch ($url_config['type']) {
192             case 1:
193             case 3:
194                 $request = Request::getInstance()->getQueryString();
195                 $this->originUriRequest = $request;
196 
197                 if ($clear_ampersand) {
198                     //rewrite下带问号的请求参数追加到$_GET数组
199                     $request_uri = Request::getInstance()->getRequestURI();
200                     if ($url_config['rewrite'] && $request_uri && false !== strpos($request_uri, '?')) {
201                         $query_string = parse_url($request_uri, PHP_URL_QUERY);
202                         parse_str($query_string, $addition_params);
203                         $_GET += $addition_params;
204 
205                         if ($query_string == $request) {
206                             $request = '';
207                         }
208                     }
209 
210                     if (false !== ($l = strpos($request, '&'))) {
211                         $request = substr($request, 0, $l);
212                     }
213 
214                     if (false !== strpos($request, '=')) {
215                         $request = '';
216                     }
217 
218                     if (isset($request[0]) && $request[0] != '&') {
219                         array_shift($_GET);
220                     }
221                 }
222                 break;
223 
224             case 2:
225             case 4:
226             case 5:
227                 $request = Request::getInstance()->getPathInfo();
228                 $this->originUriRequest = $request;
229                 break;
230 
231             default:
232                 throw new CoreException('Not support URL type!');
233         }
234 
235         if ($request) {
236             $request = urldecode(ltrim($request, '/'));
237             if ($convert_html_entities) {
238                 $request = htmlspecialchars($request, ENT_QUOTES);
239             }
240         }
241 
242         return $prefix . $request;
243     }
244 
245     /**
246      * 解析router别名配置
247      *
248      * @param array $request
249      * @param array $url_config
250      * @internal param $router
251      */
252     function parseRouter(array $request, array $url_config)
253     {
254         $combine_alias_key = '';
255         $ori_controller = $controller = array_shift($request);
256         if (isset($request[0])) {
257             $combine_alias_key = $controller . ':' . $request[0];
258         }
259 
260         $controller_alias = '';
261         $router_config = $this->config->get('router');
262         if (isset($router_config [$combine_alias_key])) {
263             array_shift($request);
264             $controller_alias = $router_config [$combine_alias_key];
265         } elseif (isset($router_config [$controller])) {
266             $controller_alias = $router_config [$controller];
267         }
268 
269         if (!empty($controller_alias)) {
270             if (false !== strpos($controller_alias, ':')) {
271                 list($controller, $action) = explode(':', $controller_alias);
272             } else {
273                 $controller = $controller_alias;
274             }
275         }
276 
277         $ori_action = '';
278         if (!isset($action)) {
279             if (isset($request[0]) && !empty($request[0])) {
280                 $ori_action = $action = array_shift($request);
281             } else {
282                 $action = self::DEFAULT_ACTION;
283             }
284         }
285 
286         $addition_params = array();
287         $params = $this->parseParams($request, $url_config, $addition_params);
288         $this->config->set('ori_router', array(
289             'request' => $this->originUriRequest,
290             'addition_params' => $addition_params,
291             'controller' => $ori_controller,
292             'action' => $ori_action,
293             'params' => $request,
294         ));
295 
296         $this->setController($controller);
297         $this->setAction($action);
298         $this->setParams($params);
299     }
300 
301     /**
302      * 设置controller
303      *
304      * @param $controller
305      */
306     function setController($controller)
307     {
308         $this->controller = $controller;
309     }
310 
311     /**
312      * 设置Action
313      *
314      * @param $action
315      */
316     function setAction($action)
317     {
318         $this->action = $action;
319     }
320 
321     /**
322      * 设置参数
323      *
324      * @param $params
325      */
326     function setParams($params)
327     {
328         $this->params = $params;
329     }
330 
331     /**
332      * 将字符串参数解析成数组
333      *
334      * @param string $query_string
335      * @param array $url_config
336      * @return array
337      * @throws FrontException
338      */
339     private static function parseRequestString($query_string, $url_config)
340     {
341         $url_suffix = &$url_config['ext'];
342         if (isset($url_suffix[0]) && ($url_suffix_length = strlen(trim($url_suffix))) > 0) {
343             if (0 === strcasecmp($url_suffix, substr($query_string, -$url_suffix_length))) {
344                 $query_string = substr($query_string, 0, -$url_suffix_length);
345             } else {
346                 throw new FrontException('Page not found !');
347             }
348         }
349 
350         $url_dot = &$url_config['dot'];
351         if ($url_dot && false !== strpos($query_string, $url_dot)) {
352             $router_params = explode($url_dot, $query_string);
353             $end_params = array_pop($router_params);
354         } else {
355             $router_params = array();
356             $end_params = $query_string;
357         }
358 
359         $params_dot = &$url_config['params_dot'];
360         if ($params_dot && $params_dot != $url_dot && false !== strpos($end_params, $params_dot)) {
361             $params_data = explode($params_dot, $end_params);
362             foreach ($params_data as $p) {
363                 $router_params[] = $p;
364             }
365         } else {
366             $router_params[] = $end_params;
367         }
368 
369         return $router_params;
370     }
371 
372     /**
373      * 解析默认控制器和方法
374      *
375      * @param string $default_router
376      * @return array
377      * @throws CoreException
378      */
379     private function parseDefaultRouter($default_router)
380     {
381         if (empty($default_router)) {
382             throw new CoreException('Undefined default router!');
383         }
384 
385         if (empty($this->defaultRouter)) {
386             if (false !== strpos($default_router, ':')) {
387                 list($controller, $action) = explode(':', $default_router);
388             } else {
389                 $controller = $default_router;
390                 $action = self::DEFAULT_ACTION;
391             }
392 
393             $this->defaultRouter = array($controller, $action);
394         }
395 
396         return $this->defaultRouter;
397     }
398 
399     /**
400      * 解析参数并处理附加参数
401      *
402      * @param array $params
403      * @param array $url_config
404      * @param array $addition_params
405      * @return array
406      */
407     private function parseParams(array $params, array $url_config, array &$addition_params = array())
408     {
409         $addition_params = $_GET;
410         if (empty($params)) {
411             $params = $addition_params;
412         } elseif (is_array($params) && !empty($addition_params)) {
413             if ($url_config['type'] == 2) {
414                 $params = array_merge($params, $addition_params);
415             } else {
416                 $params += $addition_params;
417             }
418         }
419 
420         return $params;
421     }
422 }
423 
424 
CrossPHP API documentation generated by ApiGen