PageRenderTime 54ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/qeephp/library/core/context.php

http://enaj.googlecode.com/
PHP | 1395 lines | 694 code | 79 blank | 622 comment | 75 complexity | 882684c911cca8b709611ad6c51d69fe MD5 | raw file
Possible License(s): BSD-3-Clause
  1. <?php
  2. // $Id: context.php 2421 2009-04-14 08:59:23Z jerry $
  3. /**
  4. * ?? QContext ?
  5. *
  6. * @link http://qeephp.com/
  7. * @copyright Copyright (c) 2006-2009 Qeeyuan Inc. {@link http://www.qeeyuan.com}
  8. * @license New BSD License {@link http://qeephp.com/license/}
  9. * @version $Id: context.php 2421 2009-04-14 08:59:23Z jerry $
  10. * @package core
  11. */
  12. /**
  13. * QContext ?????????
  14. *
  15. * ?????????? QeePHP ????????????
  16. * QContext ????????????????? URL ??????
  17. *
  18. * QContext ???????????????? QContext::instance() ???
  19. * QContext ????????
  20. *
  21. * QContext ??? ArrayAccess ?????? QContext ???????????
  22. *
  23. * @code php
  24. * if (isset($context['title']))
  25. * {
  26. * echo $context['title'];
  27. * }
  28. * @endcode
  29. *
  30. * @author YuLei Liao <liaoyulei@qeeyuan.com>
  31. * @version $Id: context.php 2421 2009-04-14 08:59:23Z jerry $
  32. * @package core
  33. */
  34. class QContext implements ArrayAccess
  35. {
  36. /**
  37. * ?? UDI ????
  38. */
  39. // UDI ??????
  40. const UDI_ALL = 'all';
  41. // UDI ?????
  42. const UDI_CONTROLLER = 'controller';
  43. // UDI ????
  44. const UDI_ACTION = 'action';
  45. // UDI ??????
  46. const UDI_NAMESPACE = 'namespace';
  47. // UDI ????
  48. const UDI_MODULE = 'module';
  49. /**
  50. * ?? UDI ????
  51. */
  52. // ?????
  53. const UDI_DEFAULT_CONTROLLER = 'default';
  54. // ????
  55. const UDI_DEFAULT_ACTION = 'index';
  56. // ?????
  57. const UDI_DEFAULT_MODULE = 'default';
  58. // ???????
  59. const UDI_DEFAULT_NAMESPACE = 'default';
  60. /**
  61. * ?? URL ??
  62. */
  63. // ?? URL ??
  64. const URL_MODE_STANDARD = 'standard';
  65. // ?? PATHINFO
  66. const URL_MODE_PATHINFO = 'pathinfo';
  67. // ?? URL ??
  68. const URL_MODE_REWRITE = 'rewrite';
  69. /**
  70. * ????????
  71. *
  72. * ???????$module_name ???? public ?????
  73. * ???????? changeRequestUDI() ????? $module_name ????
  74. *
  75. * @var string
  76. */
  77. public $module_name;
  78. /**
  79. * ?????????
  80. *
  81. * @var string
  82. */
  83. public $namespace;
  84. /**
  85. * ??????????
  86. *
  87. * @var string
  88. */
  89. public $controller_name;
  90. /**
  91. * ????????
  92. *
  93. * @var string
  94. */
  95. public $action_name;
  96. /**
  97. * ?????
  98. *
  99. * @var array
  100. */
  101. private $_params = array();
  102. /**
  103. * ????
  104. *
  105. * @var QRouter
  106. */
  107. private $_router;
  108. /**
  109. * ???? URL
  110. *
  111. * @var string
  112. */
  113. static private $_request_uri;
  114. /**
  115. * ???? URL ??????????
  116. *
  117. * @var string
  118. */
  119. static private $_base_uri;
  120. /**
  121. * ???? URL ?????
  122. *
  123. * @var string
  124. */
  125. static private $_base_dir;
  126. /**
  127. * ????
  128. *
  129. * @var string
  130. */
  131. static private $_url_mode;
  132. /**
  133. * UDI ????
  134. */
  135. private static $_udi_defaults = array(
  136. self::UDI_MODULE => self::UDI_DEFAULT_MODULE,
  137. self::UDI_NAMESPACE => self::UDI_DEFAULT_NAMESPACE,
  138. self::UDI_CONTROLLER => self::UDI_DEFAULT_CONTROLLER,
  139. self::UDI_ACTION => self::UDI_DEFAULT_ACTION,
  140. );
  141. /**
  142. * ????
  143. */
  144. private function __construct()
  145. {
  146. $this->reinit();
  147. }
  148. /**
  149. * ??????????????? QContext ??
  150. *
  151. * @param boolean $full_init ??????????
  152. */
  153. function reinit($full_init = false)
  154. {
  155. if ($full_init)
  156. {
  157. $this->_params = array();
  158. $this->_router = null;
  159. }
  160. self::$_request_uri = null;
  161. self::$_base_uri = null;
  162. self::$_base_dir = null;
  163. self::$_url_mode = null;
  164. // ?????????????
  165. $url_mode = strtolower(Q::ini('dispatcher_url_mode'));
  166. if (is_null($this->_router)
  167. && ($url_mode == self::URL_MODE_PATHINFO || $url_mode == self::URL_MODE_REWRITE))
  168. {
  169. $this->_router = new QRouter();
  170. $this->_router->import(Q::ini('routes'), 'global_default_routes');
  171. $result = $this->_router->match('/' . ltrim($this->pathinfo(), '/'));
  172. if ($result)
  173. {
  174. foreach ($result as $var => $value)
  175. {
  176. if (empty($value) && $value !== '0') continue;
  177. if (empty($_GET[$var]))
  178. {
  179. $_GET[$var] = $_REQUEST[$var] = $value;
  180. }
  181. }
  182. }
  183. }
  184. self::$_url_mode = $url_mode;
  185. // ? $_GET ???????
  186. $keys = array_keys($_GET);
  187. if (!empty($keys))
  188. {
  189. $keys = array_combine($keys, $keys);
  190. $keys = array_change_key_case($keys);
  191. }
  192. $udi = array();
  193. $udi[self::UDI_CONTROLLER] = (isset($keys[self::UDI_CONTROLLER]))
  194. ? $_GET[$keys[self::UDI_CONTROLLER]] : null;
  195. $udi[self::UDI_ACTION] = (isset($keys[self::UDI_ACTION]))
  196. ? $_GET[$keys[self::UDI_ACTION]] : null;
  197. $udi[self::UDI_MODULE] = (isset($keys[self::UDI_MODULE]))
  198. ? $_GET[$keys[self::UDI_MODULE]] : null;
  199. $udi[self::UDI_NAMESPACE] = (isset($keys[self::UDI_NAMESPACE]))
  200. ? $_GET[$keys[self::UDI_NAMESPACE]] : null;
  201. $this->changeRequestUDI($udi);
  202. }
  203. /**
  204. * ?? QContext ???????
  205. *
  206. * @code php
  207. * $context = QContext::instance();
  208. * @endcode
  209. *
  210. * @return QContext QContext ???????
  211. */
  212. static function instance()
  213. {
  214. static $instance;
  215. if (is_null($instance)) $instance = new QContext();
  216. return $instance;
  217. }
  218. /**
  219. * ???????????
  220. *
  221. * __get() ??????????? $context->parameter ??????????
  222. * ?????????????? null?
  223. *
  224. * @code php
  225. * $title = $context->title;
  226. * @endcode
  227. *
  228. * ?????????? $_GET?$_POST ? QContext ???????
  229. *
  230. * @param string $parameter ????????
  231. *
  232. * @return mixed ???
  233. */
  234. function __get($parameter)
  235. {
  236. return $this->query($parameter);
  237. }
  238. /**
  239. * ???????????
  240. *
  241. * ? __get() ???????__set() ???? QContext ???????
  242. * ??? $_GET ? $_POST ?????????? __set() ??????
  243. * ???? QContext::param() ??????
  244. *
  245. * @code php
  246. * $context->title = $title;
  247. * echo $context->param('title');
  248. * @endcode
  249. *
  250. * @param string $parameter ????????
  251. * @param mixed $value ???
  252. */
  253. function __set($parameter, $value)
  254. {
  255. $this->changeParam($parameter, $value);
  256. }
  257. /**
  258. * ????????????????
  259. *
  260. * @param string $parameter ??????
  261. *
  262. * @return boolean ????????
  263. */
  264. function __isset($parameter)
  265. {
  266. return $this->offsetExists($parameter);
  267. }
  268. /**
  269. * ?????????
  270. *
  271. * __unset() ??????? QContext ????????
  272. *
  273. * @code php
  274. * unset($context['title']);
  275. * // ???? title ??????? null
  276. * echo $context->param('title');
  277. * @endcode
  278. *
  279. * @param string $parameter ??????
  280. */
  281. function __unset($parameter)
  282. {
  283. unset($this->_params[$parameter]);
  284. }
  285. /**
  286. * ?????????????? ArrayAccess ??
  287. *
  288. * @code php
  289. * echo isset($context['title']);
  290. * @endcode
  291. *
  292. * @param string $parameter ??????
  293. *
  294. * @return boolean ??????
  295. */
  296. function offsetExists($parameter)
  297. {
  298. if (isset($_GET[$parameter]))
  299. return true;
  300. elseif (isset($_POST[$parameter]))
  301. return true;
  302. else
  303. return isset($this->_params[$parameter]);
  304. }
  305. /**
  306. * ????????? ArrayAccess ??
  307. *
  308. * ?????? __set() ?????
  309. *
  310. * @code php
  311. * $context['title'] = $title;
  312. * echo $context->param('title');
  313. * @endcode
  314. *
  315. * @param string $parameter ??????
  316. * @param mixed $value ???
  317. */
  318. function offsetSet($parameter, $value)
  319. {
  320. $this->changeParam($parameter, $value);
  321. }
  322. /**
  323. * ????????? ArrayAccess ??
  324. *
  325. * @code php
  326. * $title = $context['title'];
  327. * @endcode
  328. *
  329. * @param string $parameter ????????
  330. *
  331. * @return mixed ???
  332. */
  333. function offsetGet($parameter)
  334. {
  335. return $this->query($parameter);
  336. }
  337. /**
  338. * ????????? ArrayAccess ??
  339. *
  340. * ? __unset() ???QContext::offsetUnset() ??? QContext ????????
  341. *
  342. * @code php
  343. * unset($context['title']);
  344. * @endcode
  345. *
  346. * @param string $parameter ????????
  347. */
  348. function offsetUnset($parameter)
  349. {
  350. unset($this->_params[$parameter]);
  351. }
  352. /**
  353. * ???????????
  354. *
  355. * QContext::get() ????????? $context->parameter ??????????
  356. * ?????????????? $default ?????????
  357. *
  358. * @code php
  359. * $title = $context->query('title', 'default title');
  360. * @endcode
  361. *
  362. * ?????????? $_GET?$_POST ? QContext ???????
  363. *
  364. * @param string $parameter ????????
  365. * @param mixed $default ?????????????
  366. *
  367. * @return mixed ???
  368. */
  369. function query($parameter, $default = null)
  370. {
  371. if (isset($_GET[$parameter]))
  372. return $_GET[$parameter];
  373. elseif (isset($_POST[$parameter]))
  374. return $_POST[$parameter];
  375. elseif (isset($this->_params[$parameter]))
  376. return $this->_params[$parameter];
  377. else
  378. return $default;
  379. }
  380. /**
  381. * ?? GET ??
  382. *
  383. * ? $_GET ?????????????????? $default ???????
  384. *
  385. * @code php
  386. * $title = $context->get('title', 'default title');
  387. * @endcode
  388. *
  389. * ?? $parameter ??? null?????? $_GET ????
  390. *
  391. * @param string $parameter ???????
  392. * @param mixed $default ?????????????
  393. *
  394. * @return mixed ???
  395. */
  396. function get($parameter = null, $default = null)
  397. {
  398. if (is_null($parameter))
  399. return $_GET;
  400. return isset($_GET[$parameter]) ? $_GET[$parameter] : $default;
  401. }
  402. /**
  403. * ?? POST ??
  404. *
  405. * ? $_POST ?????????????????? $default ???????
  406. *
  407. * @code php
  408. * $body = $context->post('body', 'default body');
  409. * @endcode
  410. *
  411. * ?? $parameter ??? null?????? $_POST ????
  412. *
  413. * @param string $parameter ???????
  414. * @param mixed $default ?????????????
  415. *
  416. * @return mixed ???
  417. */
  418. function post($parameter = null, $default = null)
  419. {
  420. if (is_null($parameter))
  421. return $_POST;
  422. return isset($_POST[$parameter]) ? $_POST[$parameter] : $default;
  423. }
  424. /**
  425. * ?? Cookie ??
  426. *
  427. * ? $_COOKIE ?????????????????? $default ???????
  428. *
  429. * @code php
  430. * $auto_login = $context->cookie('auto_login');
  431. * @endcode
  432. *
  433. * ?? $parameter ??? null?????? $_COOKIE ????
  434. *
  435. * @param string $parameter ???????
  436. * @param mixed $default ?????????????
  437. *
  438. * @return mixed ???
  439. */
  440. function cookie($parameter = null, $default = null)
  441. {
  442. if (is_null($parameter))
  443. return $_COOKIE;
  444. return isset($_COOKIE[$parameter]) ? $_COOKIE[$parameter] : $default;
  445. }
  446. /**
  447. * ? $_SERVER ???????????
  448. *
  449. * ?????????? $default ???????
  450. *
  451. * @code php
  452. * $request_time = $context->server('REQUEST_TIME');
  453. * @endcode
  454. *
  455. * ?? $parameter ??? null?????? $_SERVER ????
  456. *
  457. * @param string $parameter ???????
  458. * @param mixed $default ?????????????
  459. *
  460. * @return mixed ???
  461. */
  462. function server($parameter = null, $default = null)
  463. {
  464. if (is_null($parameter))
  465. return $_SERVER;
  466. return isset($_SERVER[$parameter]) ? $_SERVER[$parameter] : $default;
  467. }
  468. /**
  469. * ? $_ENV ???????????
  470. *
  471. * ?????????? $default ???????
  472. *
  473. * @code php
  474. * $os_type = $context->env('OS', 'non-win');
  475. * @endcode
  476. *
  477. * ?? $parameter ??? null?????? $_ENV ????
  478. *
  479. * @param string $parameter ???????
  480. * @param mixed $default ?????????????
  481. *
  482. * @return mixed ???
  483. */
  484. function env($parameter = null, $default = null)
  485. {
  486. if (is_null($parameter))
  487. return $_ENV;
  488. return isset($_ENV[$parameter]) ? $_ENV[$parameter] : $default;
  489. }
  490. /**
  491. * ?? QContext ???????
  492. *
  493. * @code php
  494. * $context->changeParam('arg', $value);
  495. * @endcode
  496. *
  497. * @param string $parameter ???????
  498. * @param mixed $value ???
  499. *
  500. * @return QContext ?? QContext ???????????
  501. */
  502. function changeParam($parameter, $value)
  503. {
  504. $this->_params[$parameter] = $value;
  505. }
  506. /**
  507. * ?? QContext ???????
  508. *
  509. * ?????????? $default ???????
  510. *
  511. * @code php
  512. * $value = $context->param('arg', 'default value');
  513. * @endcode
  514. *
  515. * ?? $parameter ??? null??????????????
  516. *
  517. * @param string $parameter ???????
  518. * @param mixed $default ?????????????
  519. *
  520. * @return mixed ???
  521. */
  522. function param($parameter, $default = null)
  523. {
  524. if (is_null($parameter))
  525. return $this->_params;
  526. return isset($this->_params[$parameter]) ? $this->_params[$parameter] : $default;
  527. }
  528. /**
  529. * ?????????
  530. *
  531. */
  532. function params()
  533. {
  534. return $this->_params;
  535. }
  536. /**
  537. * ???????????
  538. *
  539. * ??????????????????? HTTP?
  540. *
  541. * @code php
  542. * $protocol = $context->protocol();
  543. * echo $protocol;
  544. * @endcode
  545. *
  546. * @return string ?????????
  547. */
  548. function protocol()
  549. {
  550. static $protocol;
  551. if (is_null($protocol))
  552. {
  553. list ($protocol) = explode('/', $_SERVER['SERVER_PROTOCOL']);
  554. }
  555. return strtolower($protocol);
  556. }
  557. /**
  558. * ?? REQUEST_URI
  559. *
  560. * ???????? $_SERVER ???????? QContext::requestUri() ??????
  561. * ????? QContext::baseUri() ? QContext::baseDir() ??????
  562. *
  563. * @param string $request_uri ?? REQUEST_URI ?
  564. *
  565. * @return QContext ?? QContext ???????????
  566. */
  567. function changeRequestUri($request_uri)
  568. {
  569. self::$_request_uri = $request_uri;
  570. self::$_base_uri = self::$_base_dir = null;
  571. return $this;
  572. }
  573. /**
  574. * ??????? URL
  575. *
  576. * ?????
  577. *
  578. * <ul>
  579. * <li>?? http://www.example.com/index.php?controller=posts&action=create</li>
  580. * <li>?? /index.php?controller=posts&action=create</li>
  581. * </ul>
  582. * <ul>
  583. * <li>?? http://www.example.com/news/index.php?controller=posts&action=create</li>
  584. * <li>?? /news/index.php?controller=posts&action=create</li>
  585. * </ul>
  586. * <ul>
  587. * <li>?? http://www.example.com/index.php/posts/create</li>
  588. * <li>?? /index.php/posts/create</li>
  589. * </ul>
  590. * <ul>
  591. * <li>?? http://www.example.com/news/show/id/1</li>
  592. * <li>?? /news/show/id/1</li>
  593. * </ul>
  594. *
  595. * ????? Zend Framework ???
  596. *
  597. * @return string ????? URL
  598. */
  599. function requestUri()
  600. {
  601. if (self::$_request_uri) return self::$_request_uri;
  602. if (isset($_SERVER['HTTP_X_REWRITE_URL']))
  603. {
  604. $uri = $_SERVER['HTTP_X_REWRITE_URL'];
  605. }
  606. elseif (isset($_SERVER['REQUEST_URI']))
  607. {
  608. $uri = $_SERVER['REQUEST_URI'];
  609. }
  610. elseif (isset($_SERVER['ORIG_PATH_INFO']))
  611. {
  612. $uri = $_SERVER['ORIG_PATH_INFO'];
  613. if (! empty($_SERVER['QUERY_STRING']))
  614. {
  615. $uri .= '?' . $_SERVER['QUERY_STRING'];
  616. }
  617. }
  618. else
  619. {
  620. $uri = '';
  621. }
  622. self::$_request_uri = $uri;
  623. return $uri;
  624. }
  625. /**
  626. * ???????????? URI?????????
  627. *
  628. * ?????
  629. *
  630. * <ul>
  631. * <li>?? http://www.example.com/index.php?controller=posts&action=create</li>
  632. * <li>?? /index.php</li>
  633. * </ul>
  634. * <ul>
  635. * <li>?? http://www.example.com/news/index.php?controller=posts&action=create</li>
  636. * <li>?? /news/index.php</li>
  637. * </ul>
  638. * <ul>
  639. * <li>?? http://www.example.com/index.php/posts/create</li>
  640. * <li>?? /index.php</li>
  641. * </ul>
  642. * <ul>
  643. * <li>?? http://www.example.com/news/show/id/1</li>
  644. * <li>?? /news/show/id/1</li>
  645. * <li>????? URL ????? index.php ?????</li>
  646. * </ul>
  647. *
  648. * ????? Zend Framework ???
  649. *
  650. * @return string ?? URL ???????????
  651. */
  652. function baseUri()
  653. {
  654. if (self::$_base_uri) return self::$_base_uri;
  655. $filename = basename($_SERVER['SCRIPT_FILENAME']);
  656. if (basename($_SERVER['SCRIPT_NAME']) === $filename)
  657. {
  658. $url = $_SERVER['SCRIPT_NAME'];
  659. }
  660. elseif (basename($_SERVER['PHP_SELF']) === $filename)
  661. {
  662. $url = $_SERVER['PHP_SELF'];
  663. }
  664. elseif (isset($_SERVER['ORIG_SCRIPT_NAME']) && basename($_SERVER['ORIG_SCRIPT_NAME']) === $filename)
  665. {
  666. $url = $_SERVER['ORIG_SCRIPT_NAME']; // 1and1 shared hosting compatibility
  667. }
  668. else
  669. {
  670. // Backtrack up the script_filename to find the portion matching
  671. // php_self
  672. $path = $_SERVER['PHP_SELF'];
  673. $segs = explode('/', trim($_SERVER['SCRIPT_FILENAME'], '/'));
  674. $segs = array_reverse($segs);
  675. $index = 0;
  676. $last = count($segs);
  677. $url = '';
  678. do
  679. {
  680. $seg = $segs[$index];
  681. $url = '/' . $seg . $url;
  682. ++ $index;
  683. } while (($last > $index) && (false !== ($pos = strpos($path, $url))) && (0 != $pos));
  684. }
  685. // Does the baseUrl have anything in common with the request_uri?
  686. $request_uri = $this->requestUri();
  687. if (0 === strpos($request_uri, $url))
  688. {
  689. // full $url matches
  690. self::$_base_uri = $url;
  691. return self::$_base_uri;
  692. }
  693. if (0 === strpos($request_uri, dirname($url)))
  694. {
  695. // directory portion of $url matches
  696. self::$_base_uri = rtrim(dirname($url), '/') . '/';
  697. return self::$_base_uri;
  698. }
  699. if (! strpos($request_uri, basename($url)))
  700. {
  701. // no match whatsoever; set it blank
  702. return '';
  703. }
  704. // If using mod_rewrite or ISAPI_Rewrite strip the script filename
  705. // out of baseUrl. $pos !== 0 makes sure it is not matching a value
  706. // from PATH_INFO or QUERY_STRING
  707. if ((strlen($request_uri) >= strlen($url))
  708. && ((false !== ($pos = strpos($request_uri, $url)))
  709. && ($pos !== 0)))
  710. {
  711. $url = substr($request_uri, 0, $pos + strlen($url));
  712. }
  713. self::$_base_uri = rtrim($url, '/') . '/';
  714. return self::$_base_uri;
  715. }
  716. /**
  717. * ???? URL ???????????????
  718. *
  719. * ?????
  720. *
  721. * <ul>
  722. * <li>?? http://www.example.com/index.php?controller=posts&action=create</li>
  723. * <li>?? /</li>
  724. * </ul>
  725. * <ul>
  726. * <li>?? http://www.example.com/news/index.php?controller=posts&action=create</li>
  727. * <li>?? /news/</li>
  728. * </ul>
  729. * <ul>
  730. * <li>?? http://www.example.com/index.php/posts/create</li>
  731. * <li>?? /</li>
  732. * </ul>
  733. * <ul>
  734. * <li>?? http://www.example.com/news/show/id/1</li>
  735. * <li>?? /</li>
  736. * </ul>
  737. *
  738. * @return string ?? URL ??????
  739. */
  740. function baseDir()
  741. {
  742. if (self::$_base_dir) return self::$_base_dir;
  743. $base_uri = $this->baseUri();
  744. if (substr($base_uri, - 1, 1) == '/')
  745. {
  746. $base_dir = $base_uri;
  747. }
  748. else
  749. {
  750. $base_dir = dirname($base_uri);
  751. }
  752. self::$_base_dir = rtrim($base_dir, '/\\') . '/';
  753. return self::$_base_dir;
  754. }
  755. /**
  756. * ??????????????
  757. *
  758. * ??????? 80 ???????????????????????????
  759. *
  760. * @return string ????????????
  761. */
  762. function serverPort()
  763. {
  764. static $server_port = null;
  765. if ($server_port) return $server_port;
  766. if (isset($_SERVER['SERVER_PORT']))
  767. {
  768. $server_port = intval($_SERVER['SERVER_PORT']);
  769. }
  770. else
  771. {
  772. $server_port = 80;
  773. }
  774. if (isset($_SERVER['HTTP_HOST']))
  775. {
  776. $arr = explode(':', $_SERVER['HTTP_HOST']);
  777. $count = count($arr);
  778. if ($count > 1)
  779. {
  780. $port = intval($arr[$count - 1]);
  781. if ($port != $server_port)
  782. {
  783. $server_port = $port;
  784. }
  785. }
  786. }
  787. return $server_port;
  788. }
  789. /**
  790. * ????????????
  791. *
  792. * @return string ??????????
  793. */
  794. function scriptName()
  795. {
  796. return basename($_SERVER['SCRIPT_FILENAME']);
  797. }
  798. /**
  799. * ?? PATHINFO ??
  800. *
  801. * <ul>
  802. * <li>?? http://www.example.com/index.php?controller=posts&action=create</li>
  803. * <li>?? /</li>
  804. * </ul>
  805. * <ul>
  806. * <li>?? http://www.example.com/news/index.php?controller=posts&action=create</li>
  807. * <li>?? /</li>
  808. * </ul>
  809. * <ul>
  810. * <li>?? http://www.example.com/index.php/posts/create</li>
  811. * <li>?? /</li>
  812. * </ul>
  813. * <ul>
  814. * <li>?? http://www.example.com/news/show/id/1</li>
  815. * <li>?? /news/show/id/1</li>
  816. * <li>????? URL ????? index.php ?????</li>
  817. * </ul>
  818. *
  819. * ????? Zend Framework ???
  820. *
  821. * @return string
  822. */
  823. function pathinfo()
  824. {
  825. if (!empty($_SERVER['PATH_INFO'])) return $_SERVER['PATH_INFO'];
  826. $base_url = $this->baseUri();
  827. if (null === ($request_uri = $this->requestUri())) return '';
  828. // Remove the query string from REQUEST_URI
  829. if (($pos = strpos($request_uri, '?')))
  830. {
  831. $request_uri = substr($request_uri, 0, $pos);
  832. }
  833. if ((null !== $base_url) && (false === ($pathinfo = substr($request_uri, strlen($base_url)))))
  834. {
  835. // If substr() returns false then PATH_INFO is set to an empty string
  836. $pathinfo = '';
  837. }
  838. elseif (null === $base_url)
  839. {
  840. $pathinfo = $request_uri;
  841. }
  842. return $pathinfo;
  843. }
  844. /**
  845. * ?????????
  846. *
  847. * @return string
  848. */
  849. function requestMethod()
  850. {
  851. return $_SERVER['REQUEST_METHOD'];
  852. }
  853. /**
  854. * ??? GET ??
  855. *
  856. * @return boolean
  857. */
  858. function isGET()
  859. {
  860. return $this->requestMethod() == 'GET';
  861. }
  862. /**
  863. * ??? POST ??
  864. *
  865. * @return boolean
  866. */
  867. function isPOST()
  868. {
  869. return $this->requestMethod() == 'POST';
  870. }
  871. /**
  872. * ??? PUT ??
  873. *
  874. * @return boolean
  875. */
  876. function isPUT()
  877. {
  878. return $this->requestMethod() == 'PUT';
  879. }
  880. /**
  881. * ??? DELETE ??
  882. *
  883. * @return boolean
  884. */
  885. function isDELETE()
  886. {
  887. return $this->requestMethod() == 'DELETE';
  888. }
  889. /**
  890. * ??? HEAD ??
  891. *
  892. * @return boolean
  893. */
  894. function isHEAD()
  895. {
  896. return $this->requestMethod() == 'HEAD';
  897. }
  898. /**
  899. * ??? OPTIONS ??
  900. *
  901. * @return boolean
  902. */
  903. function isOPTIONS()
  904. {
  905. return $this->requestMethod() == 'OPTIONS';
  906. }
  907. /**
  908. * ?? HTTP ??????? XMLHttp ???
  909. *
  910. * @return boolean
  911. */
  912. function isAJAX()
  913. {
  914. return strtolower($this->header('X_REQUESTED_WITH')) == 'xmlhttprequest';
  915. }
  916. /**
  917. * ?? HTTP ??????? Flash ???
  918. *
  919. * @return boolean
  920. */
  921. function isFlash()
  922. {
  923. return strtolower($this->header('USER_AGENT')) == 'shockwave flash';
  924. }
  925. /**
  926. * ?????????
  927. *
  928. * @return string
  929. */
  930. function requestRawBody()
  931. {
  932. $body = file_get_contents('php://input');
  933. return (strlen(trim($body)) > 0) ? $body : false;
  934. }
  935. /**
  936. * ?? HTTP ????????????????????? false
  937. *
  938. * @param string $header ?????????
  939. *
  940. * @return string ???
  941. */
  942. function header($header)
  943. {
  944. $temp = 'HTTP_' . strtoupper(str_replace('-', '_', $header));
  945. if (!empty($_SERVER[$temp])) return $_SERVER[$temp];
  946. if (function_exists('apache_request_headers'))
  947. {
  948. $headers = apache_request_headers();
  949. if (!empty($headers[$header])) return $headers[$header];
  950. }
  951. return false;
  952. }
  953. /**
  954. * ????????? URL
  955. *
  956. * @return string ??????? URL
  957. */
  958. function referer()
  959. {
  960. return $this->header('REFERER');
  961. }
  962. /**
  963. * ?????????????
  964. *
  965. * ???????????? null?
  966. *
  967. * @return QRouter ???????????
  968. */
  969. function router()
  970. {
  971. return $this->_router;
  972. }
  973. /**
  974. * ?? url
  975. *
  976. * ???
  977. *
  978. * @code php
  979. * url(UDI, [??????], [???])
  980. * @endcode
  981. *
  982. * UDI ??????????Uniform Destination Identifier?????
  983. * UDI ????????????????????????????
  984. *
  985. * @code php
  986. * namespace::controller/action@module
  987. * @endcode
  988. *
  989. * UDI ????????????????
  990. * ??????????????????????????????index????
  991. * ??????????????????????????
  992. *
  993. * UDI ????????
  994. *
  995. * @code php
  996. * 'controller'
  997. * 'controller/action'
  998. * '/action'
  999. * 'controller@module'
  1000. * 'controller/action@module'
  1001. * 'namespace::controller'
  1002. * 'namespace::controller/action'
  1003. * 'namespace::controller@module'
  1004. * 'namespace::controller/action@module'
  1005. * '@module'
  1006. * 'namespace::@module'
  1007. * @endcode
  1008. *
  1009. * ???
  1010. * @code php
  1011. * url('admin::posts/edit', array('id' => $post->id()));
  1012. * @endcode
  1013. *
  1014. * $params ??????????????“/”?????????
  1015. *
  1016. * @code php
  1017. * url('posts/index', 'page/3');
  1018. * url('users/show', 'id/5/profile/yes');
  1019. * @endcode
  1020. *
  1021. * ??? PATHINFO ? URL ???????????????????? QeePHP
  1022. * ???????????? URL????????????? URL ????
  1023. * ???????????????????? URL ????
  1024. *
  1025. * $opts ?????????? URL????????
  1026. *
  1027. * - base_uri: ?? URL ???????????????????????????
  1028. * - script: ?? URL ?????????
  1029. * - mode: ?? URL ???????? standard?pathinfo ? rewrite
  1030. *
  1031. * @param string $udi UDI ???
  1032. * @param array|string $params ??????
  1033. * @param string $route_name ???
  1034. * @param array $opts ?????? URL ???
  1035. *
  1036. * @return string ??? URL ??
  1037. */
  1038. function url($udi, $params = null, $route_name = null, array $opts = null)
  1039. {
  1040. static $base_uri;
  1041. if (is_null($base_uri))
  1042. {
  1043. $base_uri = '/' . trim($this->baseDir(), '/');
  1044. if ($base_uri != '/')
  1045. {
  1046. $base_uri .= '/';
  1047. }
  1048. }
  1049. $udi = $this->normalizeUDI($udi);
  1050. if (!is_array($params))
  1051. {
  1052. $arr = Q::normalize($params, '/');
  1053. $params = array();
  1054. while ($key = array_shift($arr))
  1055. {
  1056. $value = array_shift($arr);
  1057. $params[$key] = $value;
  1058. }
  1059. }
  1060. // ?? $opts
  1061. if (is_array($opts))
  1062. {
  1063. $mode = !empty($opts['mode']) ? $opts['mode'] : self::$_url_mode;
  1064. $script = !empty($opts['script'])
  1065. ? $opts['script']
  1066. : $this->scriptName();
  1067. $url = !empty($opts['base_uri'])
  1068. ? rtrim($opts['base_uri'], '/') . '/'
  1069. : $base_uri;
  1070. }
  1071. else
  1072. {
  1073. $mode = self::$_url_mode;
  1074. $url = $base_uri;
  1075. $script = $this->scriptName();
  1076. }
  1077. if (!is_null($this->_router) && $mode != self::URL_MODE_STANDARD)
  1078. {
  1079. // ?????? URL
  1080. $params = array_merge($params, $udi);
  1081. $path = $this->_router->url($params, $route_name);
  1082. if (self::$_url_mode == self::URL_MODE_PATHINFO && $path != '/')
  1083. {
  1084. $url .= $this->scriptName();
  1085. }
  1086. else
  1087. {
  1088. $url = rtrim($url, '/');
  1089. }
  1090. $url .= $path;
  1091. }
  1092. else
  1093. {
  1094. foreach (self::$_udi_defaults as $key => $value)
  1095. {
  1096. if ($udi[$key] == $value) unset($udi[$key]);
  1097. unset($params[$key]);
  1098. }
  1099. $params = array_filter(array_merge($udi, $params));
  1100. $url .= $script;
  1101. if (!empty($params))
  1102. {
  1103. $url .= '?' . http_build_query($params, '', '&');
  1104. }
  1105. }
  1106. return $url;
  1107. }
  1108. /**
  1109. * ?? UDI ????????
  1110. *
  1111. * @param array $udi ???? UDI
  1112. *
  1113. * @return string
  1114. */
  1115. function UDIString(array $udi)
  1116. {
  1117. return "{$udi[self::UDI_NAMESPACE]}::{$udi[self::UDI_CONTROLLER]}/{$udi[self::UDI_ACTION]}@{$udi[self::UDI_MODULE]}";
  1118. }
  1119. /**
  1120. * ???????? UDI ??
  1121. *
  1122. * @code php
  1123. * $udi = array(
  1124. * QContext::UDI_CONTROLLER => '',
  1125. * QContext::UDI_ACTION => '',
  1126. * QContext::UDI_NAMESPACE => '',
  1127. * QContext::UDI_MODULE => '',
  1128. * );
  1129. *
  1130. * // ??
  1131. * // array(
  1132. * // controller: default
  1133. * // action: index
  1134. * // namespace: default
  1135. * // module: default
  1136. * // )
  1137. * dump($context->normalizeUDI($udi));
  1138. *
  1139. * $udi = 'admin::posts/edit';
  1140. * // ??
  1141. * // array(
  1142. * // controller: posts
  1143. * // action: edit
  1144. * // namespace: admin
  1145. * // module: default
  1146. * // )
  1147. * dump($context->normalizeUDI($udi));
  1148. * @endcode
  1149. *
  1150. * ??????????? UDI??? $return_array ??? false?
  1151. *
  1152. * @param string|array $udi ???? UDI
  1153. * @param boolean $return_array ????????? UDI
  1154. *
  1155. * @return array ???? UDI
  1156. */
  1157. function normalizeUDI($udi, $return_array = true)
  1158. {
  1159. if (!is_array($udi))
  1160. {
  1161. // ???? ".", "/" UDI??
  1162. // url('.') ??????
  1163. // url('/') ???????+index
  1164. if($udi === '.')
  1165. {
  1166. $namespace = $this->namespace;
  1167. $module_name = $this->module_name;
  1168. $controller = $this->controller;
  1169. $action = $this->action;
  1170. }
  1171. elseif($udi === '/')
  1172. {
  1173. $namespace = $this->namespace;
  1174. $module_name = $this->module_name;
  1175. $controller = $this->controller;
  1176. $action = self::$_udi_defaults[self::UDI_ACTION];
  1177. }
  1178. else
  1179. {
  1180. if (strpos($udi, '::') !== false)
  1181. {
  1182. $arr = explode('::', $udi);
  1183. $namespace = array_shift($arr);
  1184. $udi = array_shift($arr);
  1185. }
  1186. else
  1187. {
  1188. $namespace = $this->namespace;
  1189. }
  1190. if (strpos($udi, '@') !== false)
  1191. {
  1192. $arr = explode('@', $udi);
  1193. $module_name = array_pop($arr);
  1194. $udi = array_pop($arr);
  1195. }
  1196. else
  1197. {
  1198. $module_name = $this->module_name;
  1199. }
  1200. $arr = explode('/', $udi);
  1201. $controller = array_shift($arr);
  1202. $action = array_shift($arr);
  1203. }
  1204. $udi = array(
  1205. self::UDI_MODULE => $module_name,
  1206. self::UDI_NAMESPACE => $namespace,
  1207. self::UDI_CONTROLLER => $controller,
  1208. self::UDI_ACTION => $action,
  1209. );
  1210. }
  1211. if (empty($udi[self::UDI_MODULE]))
  1212. {
  1213. $udi[self::UDI_MODULE] = $this->module_name;
  1214. }
  1215. if (empty($udi[self::UDI_NAMESPACE]))
  1216. {
  1217. $udi[self::UDI_NAMESPACE] = $this->namespace;
  1218. }
  1219. if (empty($udi[self::UDI_CONTROLLER]))
  1220. {
  1221. $udi[self::UDI_CONTROLLER] = $this->controller_name;
  1222. }
  1223. if (empty($udi[self::UDI_ACTION]) && $udi[self::UDI_ACTION] !== '0')
  1224. {
  1225. $udi[self::UDI_ACTION] = self::UDI_DEFAULT_ACTION;
  1226. }
  1227. foreach (self::$_udi_defaults as $key => $value)
  1228. {
  1229. if (empty($udi[$key]) && $udi[$key] !== '0')
  1230. {
  1231. $udi[$key] = $value;
  1232. }
  1233. else
  1234. {
  1235. $udi[$key] = preg_replace('/[^a-z0-9]+/', '', strtolower($udi[$key]));
  1236. }
  1237. }
  1238. if (!$return_array)
  1239. {
  1240. return "{$udi[self::UDI_NAMESPACE]}::{$udi[self::UDI_CONTROLLER]}/{$udi[self::UDI_ACTION]}@{$udi[self::UDI_MODULE]}";
  1241. }
  1242. else
  1243. {
  1244. return $udi;
  1245. }
  1246. }
  1247. /**
  1248. * ????????? UDI
  1249. *
  1250. * ?????????????????????????????????? UDI?
  1251. *
  1252. * @code php
  1253. * dump($context->requestUDI());
  1254. * @endcode
  1255. *
  1256. * @param boolean $return_array ????????? UDI
  1257. *
  1258. * @return string|array ??????? UDI
  1259. */
  1260. function requestUDI($return_array = true)
  1261. {
  1262. return $this->normalizeUDI("/{$this->action_name}", $return_array);
  1263. }
  1264. /**
  1265. * ? QContext ???????????? UDI ????
  1266. *
  1267. * @code php
  1268. * $context->changeRequestUDI('posts/edit');
  1269. * // ??? posts
  1270. * echo $context->controller_name;
  1271. * @endcode
  1272. *
  1273. * @param array|string $udi ???? UDI
  1274. *
  1275. * @return QContext ?? QContext ???????????
  1276. */
  1277. function changeRequestUDI($udi)
  1278. {
  1279. $udi = $this->normalizeUDI($udi);
  1280. $this->controller_name = $udi[self::UDI_CONTROLLER];
  1281. $this->action_name = $udi[self::UDI_ACTION];
  1282. $this->module_name = $udi[self::UDI_MODULE];
  1283. $this->namespace = $udi[self::UDI_NAMESPACE];
  1284. if ($this->module_name == self::UDI_DEFAULT_MODULE)
  1285. {
  1286. $this->module_name = null;
  1287. }
  1288. if ($this->namespace == self::UDI_DEFAULT_NAMESPACE)
  1289. {
  1290. $this->namespace = null;
  1291. }
  1292. return $this;
  1293. }
  1294. }