【问题标题】:Package Autoloading Issues包自动加载问题
【发布时间】:2014-08-20 06:51:58
【问题描述】:

我正在努力弄清楚如何正确构建和自动加载我的第一个作曲家包。我知道如果我遵循 PSR-0 命名约定,自动加载应该“正常工作”。我正在尝试设置:

  • 厂商:程序员
  • 包名:CoreLibs

我已经成功地调试了一个包含包的项目,通过在ClassLoader.php 文件的findFileWithExtension() 函数中打印输出搜索路径

/home/stuart/Desktop/test-project/vendor/Programster/CoreLibs/Programster/Programster/CoreLibs/Core.php

我知道该文件实际上位于:

/home/stuart/Desktop/test-project/vendor/Programster/CoreLibs/Core.php

我的包的 composer.json 文件:

{
    "name": "Programster/CoreLibs",
    "type": "library",
    "description": "Core libraries for PHP 5.3+",
    "keywords": ["core","library"],
    "homepage": "http://svn.yadda-yadda.com/php/core-libs",
    "license": "none",
    "authors": [
        {
            "name": "xxxx",
            "email": "my.email@email.com",
            "homepage": "http://mywebsite.com/",
            "role": "Developer"
        }
    ],
    "require": {
        "php": ">=5.3.0"
    },
    "autoload": {
        "psr-0": {
            "Programster": "Programster"
        }
    }
}

以下是项目中的一个小脚本,其中包含用于测试是否正常工作的包:

<?php

require_once(__DIR__ . '/../vendor/autoload.php');

$loader = new \Composer\Autoload\ClassLoader();
$loader->register();

use \Programster\CoreLibs as programster;
programster\Core::println("hello world");

项目的composer.json文件包含包:

{
    "repositories": [ { "type": "composer", "url": "http://satis.mydomain.com/" } ],
    "require": {
        "Programster/CoreLibs": "dev-trunk"
    }
}

是我的包配置错误,还是我真的需要在 CoreLibs 存储库源代码中创建 Programster/CoreLibs/ 子目录?

【问题讨论】:

  • PSR-0 已弃用,您可能希望使用更友好的 PSR-4。
  • @yo ,找不到有关弃用 PSR-0 的消息。你能为我分享一些关于它的链接吗?
  • 您是在寻求建议还是在解决某些问题?
  • 好吧,也许“已弃用”这个词并不合适,但 PSR-4 仍然更简洁,并且在设计时考虑了作曲家。像 Drupal 这样的项目已经采用了它。 github.com/php-fig/fig-standards/blob/master/accepted/…
  • @sectus 我正在尝试找到解决我的包自动加载问题的解决方案。也许这需要更改配置或更改目录结构。

标签: php package composer-php


【解决方案1】:
use \Programster\CoreLibs as programster;
programster\Core::println("hello world");

您的班级名称计算结果为 \Programster\CoreLibs\Core

有了这个 PSR-0 自动加载,

    "psr-0": {
        "Programster": "Programster"
    }

类名将完全转换为类似“Programster/CoreLibs/Core.php”的路径名,并且该路径将在相对于您的库composer.json 位置的“Programster”目录中搜索。

使用 PSR-4 自动加载,

    "psr-4": {
        "Programster\\CoreLibs\\": ""
    }

此定义中的前缀将从类名中删除,其余部分将转换为路径(即“Core.php”)并在提到的路径中搜索(在这种情况下,在库的主目录中, 因为 "" + "Core.php" 是指向一个没有任何子目录的文件)。

您的第二个定义在某些方面更好。它使用更长的前缀,如果你包含多个使用相同前缀的库,这很重要,因为 Composer 必须搜索多个路径才能找到该类。而且它使用更短的路径,这也允许稍微更快的磁盘 I/O 操作(不过我还没有进行任何性能测量)。

【讨论】:

  • 感谢您的信息。关于if you include more than one library using the same prefix,我的意图是稍后我将拥有另一个名为 Programster\\Package2 等的库。这应该有望“合并”,以便目录结构为vendor/Programster/CoreLibsvendor/Programster/Package2
  • 除非 Composer 改变了它组织库的方式(这不是你应该担心的,因为这不是你的事 - 你只需要关心能够自动加载类),当前模型是为包含的每个包创建一个“vendorname/packagename”子文件夹。
【解决方案2】:

我设法通过使用其他人在 cmets 中建议的 PSR-4 标准并更新我的包的 composer.json 文件(请参阅自动加载部分)使其工作:

{
    "name": "Programster/CoreLibs",
    "type": "library",
    "description": "Core libraries for PHP 5.3+",
    "keywords": ["core","library"],
    "homepage": "http://svn.mydomain/core-libs",
    "license": "none",
    "authors": [
        {
            "name": "MY name",
            "email": "my.email@email.com",
            "homepage": "http://my-website.com/",
            "role": "Developer"
        }
    ],
    "require": {
        "php": ">=5.3.0"
    },
    "autoload": {
        "psr-4": {
            "Programster\\CoreLibs\\": ""
        }
    }
}

这是我在项目中安装了包的脚本:

require_once(__DIR__ . '/../vendor/autoload.php');
\Programster\CoreLibs\Core::println("hello world");

@sectus 是对的,我不需要使用$loader = new \Composer\Autoload\ClassLoader();$loader-&gt;register();

【讨论】:

    猜你喜欢
    • 2020-06-17
    • 1970-01-01
    • 1970-01-01
    • 2016-08-29
    • 2011-08-17
    • 2014-08-02
    • 2018-07-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多