4

我已经在我的内部设置了一个非常基本的自动加载器index.php来获取一个命名空间类hello.php。我的开发环境是Ubuntu 12.04

我为什么要这样做?我正在尝试遵守PSR-1PSR-2 编码标准,其中包括:

类名必须在 StudlyCaps 中声明

命名空间为 /Vendor/Class(注意:大写)

以下是我在更改大写字母之前有效的结构和代码。

文件夹结构

- web
  -- index.php
  -- core
    --- hello.php

自动装载机

在 index.php 中,我有我的自动加载器:

set_include_path(__DIR__);
spl_autoload_extensions('.php,.class.php');
spl_autoload_register();

类文件

在核心文件夹中,我有 hello.php

namespace core;

class hello {
    public function __construct() {
        echo 'Constructed!';
    }
}

有效的代码

如果我$obj = new \core\hello();在我的中运行index.php,我会返回“Constructed!”。伟大的!


不起作用的

将我的核心文件夹重命名为“Core”——注意大写 C,hello.php以及namespace Core;.

现在让我们再试一次$obj = new \Core\hello();

Fatal error: Class 'Core\hello' not found in ...

那么请告诉我,为什么我不能使用大写字母来符合 PSR 标准?我究竟做错了什么?

4

3 回答 3

8

在 Linux 平台上运行 PHP 代码时,请务必记住 Linux 对文件名区分大小写。

这会影响自动加载器,因为它们通常在构建要加载的文件名时使用命名空间和类名。

如果文件夹名为core,则命名空间必须为core,大小写相同。如果将其更改为Core在命名空间中,则必须对文件夹名称执行相同操作。(因此,core必须同时更改所有其他类Core)。

在 Windows 上,这不会发生,因为 Windows 文件系统不区分大小写。当代码在本地基于 Windows 的开发系统上进行测试和工作时,这可能会导致混淆,然后在将其复制到基于 Linux 的服务器时会中断。

[编辑]

好的,所以我错过了您也更改了目录名。但是,我仍然认为这是文件名/目录名的问题。

我注意到你在spl_autoload_register()没有任何参数的情况下打电话。这意味着默认spl_autoload()函数将用​​作自动加载器。

如果您阅读的文档spl_autoload(),您会注意到它使用类和命名空间的小写版本。

换句话说,使用默认的自动加载器,您的类可以混合大小写,但文件夹结构和文件名必须全部小写。

所以事实上,对你来说,你需要保持你的文件名小写。

根据我的原始答案,我个人经历了相反的情况,我有一个完全小写的文件名,当我从 Windows 开发盒移动到 Linux 服务器时,我的混合大小写类名被打破了。我的经验与你的不同的原因是因为我使用的是自定义编写的自动加载函数,它不会进行自动小写转换,所以我的文件名的大小写必须与我的类名的大小写匹配。

于 2013-02-22T15:34:57.483 回答
2

我认为您向我们展示了一些很好的歧义。如果我错了,请纠正我。

根据规范,您必须使用被实例化的类(和命名空间)的小写名称。(http://www.php.net/manual/en/function.spl-autoload.php

但是 PSR 告诉我们使用大写字母。如果您想坚持使用 PSR,那么我们必须将默认的 spl_autoload 覆盖为我们自己的。

于 2013-10-23T12:44:35.493 回答
1

对于其他有此问题的人,为什么不使用 ucfirst() 或 strtolower() ?

所以下面的代码将尝试所有小写并尝试首字母大写文件

例如:somename.class.php 或 Somename.class.php

is_readable() 首先检查不显示找不到文件的 php 错误。

spl_autoload_register(function($name) {

    if (is_readable(strtolower($name).'.class.php')) {
        require_once(strtolower($name).'.class.php');
    } 
    elseif (is_readable(ucfirst($name).'.class.php')) {
        require_once(ucfirst($name).'.class.php');
    }
});
于 2014-01-28T01:33:03.013 回答