PHP包含路径和路径分隔符混淆

时间:2012-08-19 22:57:06

标签: php zend-framework

我正在尝试运行一个开源Web应用程序。它来自这里 - https://sourceforge.net/projects/labshare-sahara/ 它使用Zend PHP框架。

我的问题是使用以下代码。它无法找到文件,因此返回false,并显示消息:

  

“2012-08-20T00:01:08 + 02:00调试(7):无法找到授权类   SAHARANS_Auth_Type_Database包含路径“

输出到日志文件。


   private function _loadClass($name)
       {
            /* Find the class to load. */
            $file = implode('/', explode('_', $name)) . '.php';
            foreach (explode(PATH_SEPARATOR, get_include_path()) as $path)
            {
                $this->_logger->debug("does $path/$file exist?"); //I added this
                if (file_exists($path . PATH_SEPARATOR . $file))
                {
                    return new $name();
                }
            }

            $this->_logger->debug("Unable to find auth class $name in include path.");
            return false;
        }

为了给出更多的上下文,我得到它来向日志打印更多信息 - 所以它每次都围绕for循环写入日志。这是输出:

2012-08-20T00:47:07+02:00 DEBUG (7): does C:\xampp\htdocs\Sahara-WI\WI\application/../library/SAHARANS/Auth/Type/Database.php exist?

2012-08-20T00:47:07+02:00 DEBUG (7): does C:\xampp\htdocs\Sahara-WI\WI\library/SAHARANS/Auth/Type/Database.php exist?

2012-08-20T00:47:07+02:00 DEBUG (7): does C:\xampp\htdocs\Sahara-WI\WI\application\models/SAHARANS/Auth/Type/Database.php exist?

2012-08-20T00:47:07+02:00 DEBUG (7): does C:\xampp\htdocs\Sahara-WI\WI\institution/SAHARANS/Auth/Type/Database.php exist?

2012-08-20T00:47:07+02:00 DEBUG (7): does ./SAHARANS/Auth/Type/Database.php exist?

2012-08-20T00:47:07+02:00 DEBUG (7): does C:\xampp\php\PEAR/SAHARANS/Auth/Type/Database.php exist?

2012-08-20T00:47:07+02:00 DEBUG (7): Unable to find auth class SAHARANS_Auth_Type_Database in include path

2012-08-20T00:47:07+02:00 DEBUG (7): does C:\xampp\htdocs\Sahara-WI\WI\application/../library/Sahara/Auth/Type/Database.php exist?

2012-08-20T00:47:07+02:00 DEBUG (7): does C:\xampp\htdocs\Sahara-WI\WI\library/Sahara/Auth/Type/Database.php exist

2012-08-20T00:47:07+02:00 DEBUG (7): does C:\xampp\htdocs\Sahara-WI\WI\application\models/Sahara/Auth/Type/Database.php exist?

注意:Database.php确实存在于models \ Sahara \ Auth \ Type目录中!

立即看起来很奇怪的是'/'和'\'之间的交换 路径,但试图强制反对(我使用的是Windows机器)似乎没有任何影响。

提前致谢!

3 个答案:

答案 0 :(得分:1)

PATH_SEPARATOR是;在Windows上,以及:在其他操作系统上。它用于分割多个路径,而不是(子)目录和文件名。

变化:

if (file_exists($path . PATH_SEPARATOR . $file));

要:

if (file_exists($path . '/' . $file));

这将无处不在。

答案 1 :(得分:1)

好的两件事:

  1. 使用DIRECTORY_SEPARATOR and not PATH_SEPARATOR
  2. 使用realpath()修复任何路径怪异。
  3. 如果有人感兴趣,我的自动加载器看起来像这样(不是ZF):

    <?php
    
    namespace Application\Common;
    /**
     * Autoloader class
     * This class will be responsible for autoloading of classes.
     */
    class Autoloader {
    
        /** @var string $namespace  Namespace prefix for this instance */
        private $namespace;
        /** @var string $path       Path prefix for this instance */
        private $path;
    
        /**
         * @param string $namespace
         * @param string $path
         */
        public function __construct($namespace, $path) {
            $this->namespace = ltrim($namespace, "\\");
            $this->path      = rtrim($path, "/\\");
        }
    
        /**
         * Attempts to load a class.
         *
         * @param string $class The class name, including namespace.
         *
         * @return bool Success or fail based on class existence.
         */
        public function load($class) {
            $class = ltrim($class, "\\");
            //Check to see if class is from correct namespace defined by Autoloader instance.
            if (strpos($class, $this->namespace) === 0) {
                //Explode by namespace parts
                $namespace_parts = explode("\\", $class);
                //Class would be the last element, take it out and return it
                $class             = array_pop($namespace_parts);
                $namespace_parts[] = '';
                /* Build the directory path:
                    The base path as defined in Autoloader
                    The namespace parts, each a folder
                    Parts of the class, separated by an underscore, become folders as well
                */
                $path = $this->path . DIRECTORY_SEPARATOR . implode(DIRECTORY_SEPARATOR, $namespace_parts);
                $path .= str_replace("_", DIRECTORY_SEPARATOR, $class) . ".php";
                $path = realpath($path);
                if (file_exists($path)) {
                    require $path;
                    return true;
                }
            }
            return false;
        }
    
        /**
         * Register the function.
         */
        public function register() {
            spl_autoload_register(array($this, "load"));
        }
    
        /**
         * Unregisters the function.
         */
        public function unregister() {
            spl_autoload_unregister(array($this), "load");
        }
    }
    

    使用:

    //Application being the common namespace prefix.
    //__DIR__."Application" being the base directory.
    $autoloader = new Application\Common\Autoloader("Application", __DIR__ . "Application");
    $autoloader->register();
    

答案 2 :(得分:0)

您的自动加载器需要在课堂上实际需要,所以您可能需要:

if (file_exists($path . PATH_SEPARATOR . $file))
{
    require $path . PATH_SEPARATOR . $file;
    return new $name();
}