70

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

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

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

做这样的事情是行不通的:

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

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

4

6 回答 6

74

每个包都应该负责自动加载自己,你想用你定义的包之外的自动加载类来实现什么?

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

<?php

$loader = require 'vendor/autoload.php';
$loader->add('AppName', __DIR__.'/../src/');
于 2012-10-10T12:13:43.950 回答
54

作曲家文档指出:

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

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

  • 源代码
    • 应用名称
  • 小贩
  • 作曲家.json

以下配置绝对正确:

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

但是您必须重新更新/安装依赖项以使其适合您,即运行:

php composer.phar update

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

同样正如@Dom 所指出的,您可以使用composer dump-autoload更新自动加载器而无需进行更新。

于 2013-03-12T09:18:36.007 回答
26

还有其他使用作曲家自动加载功能的方法。加载没有命名空间的包或带有自定义自动加载功能的包的有用方法。

例如,如果您想包含一个包含自动加载功能的单个文件,您可以使用“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

快乐的自动加载 =)

于 2014-09-21T14:15:06.243 回答
12

在我看来,Sergiy 的答案应该是给定问题的选定答案。我分享我的理解。

我正在寻找使用我在下面给出的目录结构下的作曲家自动加载我的包文件。

<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中的类用户-

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

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

另请注意“src/App”、“src/Test”.. 来自您的 web-root,即您的 composer.json 所在的位置。与供应商目录无关。看看 vendor/autoload.php

现在,如果 composer 安装正确,只需要 #composer update

在作曲家更新我的类后成功加载。我观察到的是 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

于 2015-06-16T10:25:56.533 回答
3

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

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

您在作曲家中的自动加载看起来是一样的......

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

现在,您的 AppName 命名空间类将从您当前工作目录的文件夹中启动一个目录src......这应该可以工作。

于 2012-10-10T12:12:45.310 回答
3

自动加载配置确实在供应商目录下启动。所以你可能想改变供应商目录,例如

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

或者这在你的项目中是不可能的?

于 2012-10-10T12:15:55.373 回答