简体   繁体   English

PSR-0自动装带器问题

[英]PSR-0 autoloader issue

I have trouble instantiating class by path in my PSR-0 autoloaded project. 我在PSR-0自动加载的项目中无法通过路径实例化类。 Structure is as follows: 结构如下:

| - src/
|    - Models/
|        - My_New_Model_Migration.php
|        - ...
|    SeederCommand.php
| - vendor/
|     - ...
| composer.json

And Composer autoloader: 和Composer自动加载器:

"autoload": {
    "psr-0": {
        "" : [
            "src/"
        ]
    }
}

Not to get to much in SeederCommand class, it is basically a Doctrine/migrations class which is supposed to create a migration with up() and down() methods. SeederCommand类中SeederCommand太多SeederCommand ,它基本上是Doctrine / migrations类,应该使用up()down()方法创建迁移。

Inside the function responsible for generating those I have this part: 在负责生成这些函数的函数内部,我有以下部分:

if (file_exists(__DIR__ . "/Models/{$model}_Migration.php")) {
    $class = "{$model}_Migration";
    $instantiated = new $class;
    ....
}

When echoing I notice that file indeed does exist, so this part is working as it should. 在回显时,我注意到该文件确实存在,因此该部分正在正常工作。 When newing up the class however I am getting an error: 但是,在更新课程时,出现错误:

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 PHP致命错误:未捕获错误:在/var/www/html/.../src/SeederCommand.php:97中找不到类'/var/www/html/.../src/Models/My_New_Model_Migration.php'

Since paths are correct, I presume the issue must be in way a PSR-0 autoloader works by parsing paths by underscore? 由于路径是正确的,因此我认为问题一定是PSR-0自动加载器通过下划线来解析路径吗?

Is there some way around it? 周围有办法吗?

EDIT: 编辑:

This answer doesn't help me as it explains the 'why' of the autoloader story. 这个答案对我没有帮助,因为它解释了自动装带器故事的“原因”。 I know how both PSR-0 and PSR-4 autoloaders work on the high level. 我知道PSR-0PSR-4自动装带器都是如何在高水平上工作的。 I would like a way around the fact that autoloader wants a directory structure where there is none (and I don't want it introduced in this case). 我想解决一个事实,即自动加载器需要一个没有目录结构的目录结构(在这种情况下,我不想引入它)。

EDIT2: 编辑2:

SeederCommand class requires autoload file: SeederCommand类需要自动加载文件:

require "../vendor/autoload.php"; 

I've tried doing a dump-autoload and renaming class to one without underscores and same thing happens, so I might have done something wrong with autoloading itself. 我尝试过执行一次dump-autoload并将类重命名为一个没有下划线的类,并且发生了同样的事情,因此我可能在自动加载本身方面做错了。

EDIT3: 编辑3:

I have tried newing up a class I renamed to a non-underscore version. 我尝试更新我重命名为非下划线版本的类。 For example newing up MyNewClass works, but My_New_Class throws an error. 例如,更新MyNewClass可以,但是My_New_Class会引发错误。

Error while creating instance of new class 创建新类的实例时出错

$class = __DIR__ . "/Models/{$model}_Migration.php";
$instantiated = new $class;

This is wrong because you cannot create an instance of a class by its file name like: 这是错误的,因为您不能通过类的文件名来创建类的实例:

$instance = new /var/www/html/.../Class.php; // <-- wrong

Instead you need to use the class name and namespace: 相反,您需要使用类名和名称空间:

$instance = new \Project\Namespace\Class;

So in your specific case it could be something like 因此,在您的特定情况下,它可能类似于

$class = "\\Project\\Models\\".$model."_Migration";
// ^ depends on the real namespace and name of your migration classes
$instantiated = new $class;

PSR-0 and underscores PSR-0和下划线

After reading the PSR-0 Standard again, I honestly think there is no way to achieve what you want (having a class name with underscore but no directory for it) while using PSR-0. 再次阅读PSR-0标准之后,老实说,我认为使用PSR-0时无法实现您想要的(具有带下划线的类名,但没有目录)。 The standard explicitly states: 该标准明确规定:

Each _ character in the CLASS NAME is converted to a DIRECTORY_SEPARATOR. 类别名称中的每个_字符都将转换为DIRECTORY_SEPARATOR。

Possible solution: Classmap autoloader 可能的解决方案:Classmap自动加载器

But you could use composer's classmap autoloader for those files instead: 但是您可以改用composer的classmap自动加载器来处理这些文件:

This map is built by scanning for classes in all .php and .inc files in the given directories/files. 通过扫描给定目录/文件中所有.php和.inc文件中的类来构建此映射。 You can use the classmap generation support to define autoloading for all libraries that do not follow PSR-0/4. 您可以使用类映射生成支持为所有不遵循PSR-0 / 4的库定义自动加载。 To configure this you specify all directories or files to search for classes. 要配置它,您可以指定所有目录或文件来搜索类。

It could maybe look like that (but I was not able to test it): 它可能看起来像这样(但我无法对其进行测试):

"autoload": {
    "psr-0": {
        "" : [
            "src/"
        ]
    },
    "classmap": ["src/Models/"]
}

You cannot have underscores in your classname, and not have them in the directory structure. 您的类名中不能包含下划线,目录结构中也不能包含下划线。

If your class is named Models_MyWhatever_Migration , because you dynamically add the string "MyWhatever" to the classname during migration, that class MUST be placed in src/Models/MyWhatever/Migration.php . 如果您的类名为Models_MyWhatever_Migration ,因为在迁移过程中将字符串“ MyWhatever”动态添加到了类名,则该类必须放置在src/Models/MyWhatever/Migration.php You cannot have it in src/Models/MyWhatever_Migration.php . 您不能在src/Models/MyWhatever_Migration.php拥有它。

If you want to keep the underscore as part of the filename, you have to switch to PSR-4 and use namespaces. 如果要将下划线保留为文件名的一部分,则必须切换到PSR-4并使用名称空间。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM