/library/Zend/Loader.php

https://github.com/0x20h/zf2 · PHP · 202 lines · 77 code · 13 blank · 112 comment · 22 complexity · 611de941bdc047efa224edd7337df524 MD5 · raw file

  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Zend
  16. * @package Zend_Loader
  17. * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
  18. * @license http://framework.zend.com/license/new-bsd New BSD License
  19. * @version $Id$
  20. */
  21. namespace Zend;
  22. /**
  23. * Static methods for loading classes and files.
  24. *
  25. * @category Zend
  26. * @package Zend_Loader
  27. * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
  28. * @license http://framework.zend.com/license/new-bsd New BSD License
  29. */
  30. class Loader
  31. {
  32. /**
  33. * Loads a PHP file. This is a wrapper for PHP's include() function.
  34. *
  35. * $filename must be the complete filename, including any
  36. * extension such as ".php". Note that a security check is performed that
  37. * does not permit extended characters in the filename. This method is
  38. * intended for loading Zend Framework files.
  39. *
  40. * If $dirs is a string or an array, it will search the directories
  41. * in the order supplied, and attempt to load the first matching file.
  42. *
  43. * If the file was not found in the $dirs, or if no $dirs were specified,
  44. * it will attempt to load it from PHP's include_path.
  45. *
  46. * If $once is TRUE, it will use include_once() instead of include().
  47. *
  48. * @param string $filename
  49. * @param string|array $dirs - OPTIONAL either a path or array of paths
  50. * to search.
  51. * @param boolean $once
  52. * @return boolean
  53. * @throws Zend\Loader\Exception\SecurityException
  54. */
  55. public static function loadFile($filename, $dirs = null, $once = false)
  56. {
  57. self::_securityCheck($filename);
  58. /**
  59. * Search in provided directories, as well as include_path
  60. */
  61. $incPath = false;
  62. if (!empty($dirs) && (is_array($dirs) || is_string($dirs))) {
  63. if (is_array($dirs)) {
  64. $dirs = implode(PATH_SEPARATOR, $dirs);
  65. }
  66. $incPath = get_include_path();
  67. set_include_path($dirs . PATH_SEPARATOR . $incPath);
  68. }
  69. /**
  70. * Try finding for the plain filename in the include_path.
  71. */
  72. if ($once) {
  73. include_once $filename;
  74. } else {
  75. include $filename;
  76. }
  77. /**
  78. * If searching in directories, reset include_path
  79. */
  80. if ($incPath) {
  81. set_include_path($incPath);
  82. }
  83. return true;
  84. }
  85. /**
  86. * Returns TRUE if the $filename is readable, or FALSE otherwise.
  87. * This function uses the PHP include_path, where PHP's is_readable()
  88. * does not.
  89. *
  90. * Note from ZF-2900:
  91. * If you use custom error handler, please check whether return value
  92. * from error_reporting() is zero or not.
  93. * At mark of fopen() can not suppress warning if the handler is used.
  94. *
  95. * @param string $filename
  96. * @return boolean
  97. */
  98. public static function isReadable($filename)
  99. {
  100. if (is_readable($filename)) {
  101. // Return early if the filename is readable without needing the
  102. // include_path
  103. return true;
  104. }
  105. if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN'
  106. && preg_match('/^[a-z]:/i', $filename)
  107. ) {
  108. // If on windows, and path provided is clearly an absolute path,
  109. // return false immediately
  110. return false;
  111. }
  112. foreach (self::explodeIncludePath() as $path) {
  113. if ($path == '.') {
  114. if (is_readable($filename)) {
  115. return true;
  116. }
  117. continue;
  118. }
  119. $file = $path . '/' . $filename;
  120. if (is_readable($file)) {
  121. return true;
  122. }
  123. }
  124. return false;
  125. }
  126. /**
  127. * Explode an include path into an array
  128. *
  129. * If no path provided, uses current include_path. Works around issues that
  130. * occur when the path includes stream schemas.
  131. *
  132. * @param string|null $path
  133. * @return array
  134. */
  135. public static function explodeIncludePath($path = null)
  136. {
  137. if (null === $path) {
  138. $path = get_include_path();
  139. }
  140. if (PATH_SEPARATOR == ':') {
  141. // On *nix systems, include_paths which include paths with a stream
  142. // schema cannot be safely explode'd, so we have to be a bit more
  143. // intelligent in the approach.
  144. $paths = preg_split('#:(?!//)#', $path);
  145. } else {
  146. $paths = explode(PATH_SEPARATOR, $path);
  147. }
  148. return $paths;
  149. }
  150. /**
  151. * Ensure that filename does not contain exploits
  152. *
  153. * @param string $filename
  154. * @return void
  155. * @throws Zend\Loader\Exception\SecurityException
  156. */
  157. protected static function _securityCheck($filename)
  158. {
  159. /**
  160. * Security check
  161. */
  162. if (preg_match('/[^a-z0-9\\/\\\\_.:-]/i', $filename)) {
  163. require_once __DIR__ . '/Loader/Exception/SecurityException.php';
  164. throw new Loader\Exception\SecurityException('Illegal character in filename');
  165. }
  166. }
  167. /**
  168. * Attempt to include() the file.
  169. *
  170. * include() is not prefixed with the @ operator because if
  171. * the file is loaded and contains a parse error, execution
  172. * will halt silently and this is difficult to debug.
  173. *
  174. * Always set display_errors = Off on production servers!
  175. *
  176. * @param string $filespec
  177. * @param boolean $once
  178. * @return boolean
  179. * @deprecated Since 1.5.0; use loadFile() instead
  180. */
  181. protected static function _includeFile($filespec, $once = false)
  182. {
  183. if ($once) {
  184. return include_once $filespec;
  185. } else {
  186. return include $filespec ;
  187. }
  188. }
  189. }