我在项目中有一个包,使用composer自动加载,composer.json的条目如下:
"autoload": {
"psr-4": {
"CompanyName\\PackageName\\": "packages/package-folder/src/"
}
}
现在我正在将这个项目复制到另一个不使用composer的项目中。如何在那里自动加载相同的包?
我在项目中有一个包,使用composer自动加载,composer.json的条目如下:
"autoload": {
"psr-4": {
"CompanyName\\PackageName\\": "packages/package-folder/src/"
}
}
你需要阅读`composer.json`中定义的每个命名空间,手动加载相应的类。
以下是具体步骤:
function loadPackage($dir)
{
$composer = json_decode(file_get_contents("$dir/composer.json"), 1);
$namespaces = $composer['autoload']['psr-4'];
// Foreach namespace specified in the composer, load the given classes
foreach ($namespaces as $namespace => $classpaths) {
if (!is_array($classpaths)) {
$classpaths = array($classpaths);
}
spl_autoload_register(function ($classname) use ($namespace, $classpaths, $dir) {
// Check if the namespace matches the class we are looking for
if (preg_match("#^".preg_quote($namespace)."#", $classname)) {
// Remove the namespace from the file path since it's psr4
$classname = str_replace($namespace, "", $classname);
$filename = preg_replace("#\\\\#", "/", $classname).".php";
foreach ($classpaths as $classpath) {
$fullpath = $dir."/".$classpath."/$filename";
if (file_exists($fullpath)) {
include_once $fullpath;
}
}
}
});
}
}
loadPackage(__DIR__."/vendor/project");
new CompanyName\PackageName\Test();
当然,我不知道你在PackageName中有哪些类。
/vendor/project
是你的外部库被克隆或下载的位置。这是你拥有composer.json
文件的地方。
注意:这仅适用于psr4自动加载。
编辑: 为一个命名空间添加多个类路径支持
编辑2: 我创建了一个Github存储库来处理这段代码,如果有人想要改进它。
是的,这个问题已经过去6个月了,然而我刚使用了以下方法。
我找到了以下解决方法。我只需在项目文件夹中本地运行命令 composer dump-autoload -o
。之后,我只需要上传 ./vendor/composer 文件夹和 /vendor/autoload.php 的内容到服务器上,就可以再次工作了。
如果您无法在服务器上运行 composer,则这很有帮助。
出于多种原因,我不太喜欢Composer。第一个原因是共享主机服务没有将Composer作为软件包提供,因此很难交付低成本的应用程序或简单的MVC自定义框架。以下是符合PSR4标准的解决方法。
假设您在根目录中的文件中添加了此自动加载方法,并且我们正在自动加载名为“src”的文件夹中的所有类,以下是如何实现此目标的方法。
define('ROOT', dirname(__DIR__));
define('SLASH', DIRECTORY_SEPARATOR);
spl_autoload_register(function ($className)
{
$fileName = sprintf("%s%ssrc%s%s.php", ROOT, SLASH, SLASH, str_replace("\\", "/", $className));
if (file_exists($fileName))
{
require ($fileName);
}
else
{
echo "file not found {$fileName}";
}
});
现在每个文件都应该添加命名空间,如果有依赖,则使用它。以下是一个基本示例:
namespace myapp;
use Core\Example;