PSR-0 自动加载器问题
PSR-0 autoloader issue
我在 PSR-0
自动加载项目中按路径实例化 class 时遇到问题。结构如下:
| - src/
| - Models/
| - My_New_Model_Migration.php
| - ...
| SeederCommand.php
| - vendor/
| - ...
| composer.json
和 Composer 自动加载器:
"autoload": {
"psr-0": {
"" : [
"src/"
]
}
}
在 SeederCommand
class 中不会涉及太多,它基本上是一个 Doctrine/migrations class,它应该使用 up()
和down()
方法。
在负责生成这些函数的函数中,我有这部分:
if (file_exists(__DIR__ . "/Models/{$model}_Migration.php")) {
$class = "{$model}_Migration";
$instantiated = new $class;
....
}
回显时我注意到文件确实存在,所以这部分工作正常。但是,更新 class 时出现错误:
PHP Fatal error: Uncaught Error: Class
'/var/www/html/.../src/Models/My_New_Model_Migration.php' not found in
/var/www/html/.../src/SeederCommand.php:97
由于路径是正确的,我认为问题一定出在 PSR-0
自动加载器通过下划线解析路径的方式工作?
有什么解决办法吗?
编辑:
This answer 对我没有帮助,因为它解释了自动加载器故事的 'why'。我知道 PSR-0
和 PSR-4
自动加载器是如何在高层次上工作的。我想解决自动加载器需要一个包含 none 的目录结构这一事实(我不希望在这种情况下引入它)。
编辑2:
SeederCommand
class 需要自动加载文件:
require "../vendor/autoload.php";
我试过 dump-autoload
并将 class 重命名为不带下划线的名称,同样的事情发生了,所以我可能在自动加载本身上做错了。
编辑3:
我尝试更新 class 我重命名为非下划线版本。例如,更新 MyNewClass
有效,但 My_New_Class
会引发错误。
创建新实例时出错 class
$class = __DIR__ . "/Models/{$model}_Migration.php";
$instantiated = new $class;
这是错误的,因为您不能通过其文件名创建 class 的实例,例如:
$instance = new /var/www/html/.../Class.php; // <-- wrong
您需要使用 class 名称和命名空间:
$instance = new \Project\Namespace\Class;
因此在您的特定情况下,它可能类似于
$class = "\Project\Models\".$model."_Migration";
// ^ depends on the real namespace and name of your migration classes
$instantiated = new $class;
PSR-0 和下划线
再次阅读 PSR-0 Standard 后,老实说,我认为在使用 PSR-0 时无法实现您想要的(具有带下划线但没有目录的 class 名称)。该标准明确指出:
Each _ character in the CLASS NAME is converted to a DIRECTORY_SEPARATOR.
可能的解决方案:类图自动加载器
但您可以对这些文件使用 composer's classmap autoloader:
This map is built by scanning for classes in all .php and .inc files in the given directories/files. You can use the classmap generation support to define autoloading for all libraries that do not follow PSR-0/4. To configure this you specify all directories or files to search for classes.
它可能看起来像那样(但我无法测试):
"autoload": {
"psr-0": {
"" : [
"src/"
]
},
"classmap": ["src/Models/"]
}
您的 class 名称中不能有下划线,目录结构中也不能有下划线。
如果您的 class 被命名为 Models_MyWhatever_Migration
,因为您在迁移期间将字符串 "MyWhatever" 动态添加到 class 名称,那么 class 必须是置于 src/Models/MyWhatever/Migration.php
。你不能在 src/Models/MyWhatever_Migration.php
.
中使用它
如果你想保留下划线作为文件名的一部分,你必须切换到 PSR-4 并使用命名空间。
我在 PSR-0
自动加载项目中按路径实例化 class 时遇到问题。结构如下:
| - src/
| - Models/
| - My_New_Model_Migration.php
| - ...
| SeederCommand.php
| - vendor/
| - ...
| composer.json
和 Composer 自动加载器:
"autoload": {
"psr-0": {
"" : [
"src/"
]
}
}
在 SeederCommand
class 中不会涉及太多,它基本上是一个 Doctrine/migrations class,它应该使用 up()
和down()
方法。
在负责生成这些函数的函数中,我有这部分:
if (file_exists(__DIR__ . "/Models/{$model}_Migration.php")) {
$class = "{$model}_Migration";
$instantiated = new $class;
....
}
回显时我注意到文件确实存在,所以这部分工作正常。但是,更新 class 时出现错误:
PHP Fatal error: Uncaught Error: Class '/var/www/html/.../src/Models/My_New_Model_Migration.php' not found in /var/www/html/.../src/SeederCommand.php:97
由于路径是正确的,我认为问题一定出在 PSR-0
自动加载器通过下划线解析路径的方式工作?
有什么解决办法吗?
编辑:
This answer 对我没有帮助,因为它解释了自动加载器故事的 'why'。我知道 PSR-0
和 PSR-4
自动加载器是如何在高层次上工作的。我想解决自动加载器需要一个包含 none 的目录结构这一事实(我不希望在这种情况下引入它)。
编辑2:
SeederCommand
class 需要自动加载文件:
require "../vendor/autoload.php";
我试过 dump-autoload
并将 class 重命名为不带下划线的名称,同样的事情发生了,所以我可能在自动加载本身上做错了。
编辑3:
我尝试更新 class 我重命名为非下划线版本。例如,更新 MyNewClass
有效,但 My_New_Class
会引发错误。
创建新实例时出错 class
$class = __DIR__ . "/Models/{$model}_Migration.php";
$instantiated = new $class;
这是错误的,因为您不能通过其文件名创建 class 的实例,例如:
$instance = new /var/www/html/.../Class.php; // <-- wrong
您需要使用 class 名称和命名空间:
$instance = new \Project\Namespace\Class;
因此在您的特定情况下,它可能类似于
$class = "\Project\Models\".$model."_Migration";
// ^ depends on the real namespace and name of your migration classes
$instantiated = new $class;
PSR-0 和下划线
再次阅读 PSR-0 Standard 后,老实说,我认为在使用 PSR-0 时无法实现您想要的(具有带下划线但没有目录的 class 名称)。该标准明确指出:
Each _ character in the CLASS NAME is converted to a DIRECTORY_SEPARATOR.
可能的解决方案:类图自动加载器
但您可以对这些文件使用 composer's classmap autoloader:
This map is built by scanning for classes in all .php and .inc files in the given directories/files. You can use the classmap generation support to define autoloading for all libraries that do not follow PSR-0/4. To configure this you specify all directories or files to search for classes.
它可能看起来像那样(但我无法测试):
"autoload": {
"psr-0": {
"" : [
"src/"
]
},
"classmap": ["src/Models/"]
}
您的 class 名称中不能有下划线,目录结构中也不能有下划线。
如果您的 class 被命名为 Models_MyWhatever_Migration
,因为您在迁移期间将字符串 "MyWhatever" 动态添加到 class 名称,那么 class 必须是置于 src/Models/MyWhatever/Migration.php
。你不能在 src/Models/MyWhatever_Migration.php
.
如果你想保留下划线作为文件名的一部分,你必须切换到 PSR-4 并使用命名空间。