使用Composer的自动加载


69

我一直在网上四处寻找,在这个问题上没有运气。我在我的代码中使用作曲家的自动加载composer.json

"autoload": {
    "psr-0": {"AppName": "src/"}
}

但是我需要在比供应商文件夹更高的级别上自动加载。

做这样的事情不起作用:

"autoload": {
    "psr-0": {"AppName": "../src/"}
}

有谁知道修复程序或我该怎么做?

Answers:


73

每个软件包都应负责自身的自动加载,您要尝试使用定义的软件包之外的自动加载类来实现什么?

一种解决方法(如果适用于您的应用程序本身)是将名称空间添加到加载程序实例,如下所示:

<?php

$loader = require 'vendor/autoload.php';
$loader->add('AppName', __DIR__.'/../src/');

7
这对于在测试套件中自动加载类很有用,但是针对@ chris-r问题的实际解决方案是运行“ composer.phar update”。
Sergiy Sokolenko 2013年

2
非常感谢,这是两个小时的搜索工作,我发现了这个解决方案,谢谢您,如此亲爱的
Renish Khunt 2014年

10
请注意,该功能$loader->add()仅使用PSR-0加载。对于作为PSR-4的负载,请$loader->addPsr4()改用。
alexndreazevedo '16

2
@alexndreazevedo谢谢。自从我的项目遵循PSR-4,并且使用加载失败后,我就把头发拉了半个小时add()。我已经对上述答案进行了更新,以提及正确的addPsr4()方法。
gw0

54

作曲家的文件指出:

添加自动加载字段后,您必须重新运行安装以重新生成vendor / autoload.php文件。

假设您的“ src”目录与“供应商”目录位于同一级别:

  • src
    • 应用名称
  • 供应商
  • composer.json

以下配置绝对正确:

{
    "autoload": {
        "psr-0": {"AppName": "src/"}
    }
}

但是您必须重新更新/安装依赖项才能使其运行,例如,运行:

php composer.phar update

此命令将获取依赖关系的最新版本,并更新文件“ vendor / composer / autoload_namespaces.php”以匹配您的配置。

同样,如@Dom所述,您可以使用composer dump-autoload更新自动装带器而无需进行更新。


7
您是否只需要运行`composer dump-autoload'?
Dom

@Dom感谢您的提示,我在我的答案中添加了dump-autoload。
瑟吉·索科连科

25

还有其他使用作曲家自动加载功能的方法。加载不带名称空间的程序包或自定义自动加载功能附带的程序包的有用方法。

例如,如果要包括一个包含自动加载功能的文件,则可以使用“ files”指令,如下所示:

"autoload": {
    "psr-0": {
        "": "src/",
        "SymfonyStandard": "app/"
    },
    "files": ["vendor/wordnik/wordnik-php/wordnik/Swagger.php"]
},

Swagger.php文件中,我们得到:

function swagger_autoloader($className) {
    $currentDir = dirname(__FILE__);
    if (file_exists($currentDir . '/' . $className . '.php')) {
        include $currentDir . '/' . $className . '.php';
    } elseif (file_exists($currentDir . '/models/' . $className . '.php')) {
        include $currentDir . '/models/' . $className . '.php';
    }
}
spl_autoload_register('swagger_autoloader');

https://getcomposer.org/doc/04-schema.md#files

否则,您可能要使用类映射引用:

{
    "autoload": {
        "classmap": ["src/", "lib/", "Something.php"]
    }
}

https://getcomposer.org/doc/04-schema.md#classmap

注意:在测试期间,请记住启动composerdump-autoload命令,否则您将看不到任何变化!

./composer.phar dump-autoload

自动加载愉快=)


11

我认为,Sergiy的答案应该是给定问题的选定答案。我分享我的理解。

我一直在寻找使用composer自动加载我的包文件的方法,该文件位于下面的dir结构下。

<web-root>
    |--------src/
    |           |--------App/
    |           |
    |           |--------Test/
    |
    |---------library/
    |
    |---------vendor/
    |           |
    |           |---------composer/
    |           |           |---------autoload_psr4.php
    |           |           
    |           |----------autoload.php
    |
    |-----------composer.json
    |

我正在使用psr-4自动加载规范。

必须在项目的composer.json中添加以下几行。我打算将我的课程文件放在src / App,src / Test和库目录中。

"autoload": {
        "psr-4": {
            "OrgName\\AppType\\AppName\\": ["src/App", "src/Test", "library/"]
        }
    } 

这几乎是自我解释。OrgName \ AppType \ AppName是我想要的名称空间前缀。例如对于src / App / Controller / Provider / User.php中的User类-

namespace OrgName\AppType\AppName\Controller\Provider; // namespace declaration

use OrgName\AppType\AppName\Controller\Provider\User; // when using the class

另请注意,“ src / App”,“ src / Test” ..来自您的composer.json所在的Web根目录。与供应商目录无关。看一看vendor / autoload.php

现在,如果正确安装了composer,则只需进行 #composer更新

作曲家更新后,我的课程成功加载。我观察到的是,作曲家在vendor / composer / autoload_psr4.php中添加了一行

$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);

return array(
    'Monolog\\' => array($vendorDir . '/monolog/monolog/src/Monolog'),
    'OrgName\\AppType\\AppName\\' => array($baseDir . '/src/App', $baseDir . '/src/Test', $baseDir . '/library'),
);

这就是作曲家的映射方式。对于psr-0映射位于vendor / composer / autoload_classmap.php中


3

只需在src文件夹中为指向包含您的类的文件夹的名称空间创建符号链接...

ln -s ../src/AppName ./src/AppName

您在作曲家中的自动加载将保持不变...

"autoload": {
    "psr-0": {"AppName": "src/"}
}

而且,您的AppName命名空间类src现在将从您当前的工作目录启动一个目录,该目录现在应该在其中。


你好 !谢谢,您是我在配置中找到的唯一一个,也许您可​​以帮我:)我还创建了一个符号链接,但是当我运行composer update -oComposer时不理解classes文件夹。你有好主意吗 ?请..
CBRPLX

3

自动加载配置的确在供应商目录下启动。因此,您可能需要更改供应商目录,例如

{
    "config": {
        "vendor-dir": "../vendor/"
    },
    "autoload": {
        "psr-0": {"AppName": "src/"}
    }
}

还是在您的项目中不可能?


不正确;src/是相对于项目根目录,而不是vendor。请参阅getcomposer.org/doc/01-basic-usage.md#autoloading
Alastair Irvine
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.