如何告诉 Composer 从文件中加载给定命名空间下的所有内容?
How to tell Composer to load everything under a given namespace from a file?
我正在使用解析器生成器生成一个长文件(~35000 行)文件,其中包含多个 PHP classes 和函数。该文件如下所示:
<?php
namespace foo;
if (function_exists("foo\bar") {
function bar() {
// ...
}
}
if (class_exists("foo\Baz") {
class Baz {
// ...
}
}
// other classes and functions declared in a similar manner.
这与 Composer 的自动加载机制配合得不是很好,它更喜欢:
- 加载包含单个 class 的文件,方法是在
autoload.psr-4
中定义它。
- 每当
vendor/autoload.php
为 require
时加载整个文件,方法是在 autoload.files
中定义它
我想尽可能推迟加载这个文件,因为这个文件很重,每次请求都加载它会给服务器带来很大的负担。
我在这里要做的是让 Composer 仅在我的代码中的其他地方引用其命名空间 foo
时才加载文件。
我该怎么做?
您可以创建一个额外的自动加载器,它只会处理您特定命名空间中的 classes:
// composer's autoloader
require dirname( __DIR__ ) . '/vendor/autoload.php';
// your own thing
spl_autoload_register(function ($class_name)
{
if (strpos($class_name, 'foo') !== 0) {
return;
}
include_once 'path_to_your_generated_autoloader.php';
}
);
(为方便起见,我使用匿名函数,但实际使用什么取决于您)。
只有 foo
命名空间上的 class 才会命中您生成的文件。一旦命中,所有 classes 和函数都会被定义,所以这个自动加载器不会再次被命中。如果 class 不在 foo
命名空间中,它将 return 无害。
但是你还是有问题。
您生成的文件似乎包含 命名空间函数(例如 foo\bar()
)。 函数没有自动加载。因此,如果您在尝试在 foo
命名空间上加载 class 之前调用 foo\bar()
before,就会遇到麻烦。 (如果您只是在使用任何 class 之后才尝试使用这些函数,您会没事的;因为届时文件中的所有内容都会被加载)。
如果您想将您的函数保留在任何 class 之外,没有办法绕过它。也许您应该将这些函数生成为单个 "helper" class 的静态方法,例如 foo\Helper::bar()
。但这可能需要您更改代码生成的工作方式。
我正在使用解析器生成器生成一个长文件(~35000 行)文件,其中包含多个 PHP classes 和函数。该文件如下所示:
<?php
namespace foo;
if (function_exists("foo\bar") {
function bar() {
// ...
}
}
if (class_exists("foo\Baz") {
class Baz {
// ...
}
}
// other classes and functions declared in a similar manner.
这与 Composer 的自动加载机制配合得不是很好,它更喜欢:
- 加载包含单个 class 的文件,方法是在
autoload.psr-4
中定义它。 - 每当
vendor/autoload.php
为require
时加载整个文件,方法是在autoload.files
中定义它
我想尽可能推迟加载这个文件,因为这个文件很重,每次请求都加载它会给服务器带来很大的负担。
我在这里要做的是让 Composer 仅在我的代码中的其他地方引用其命名空间 foo
时才加载文件。
我该怎么做?
您可以创建一个额外的自动加载器,它只会处理您特定命名空间中的 classes:
// composer's autoloader
require dirname( __DIR__ ) . '/vendor/autoload.php';
// your own thing
spl_autoload_register(function ($class_name)
{
if (strpos($class_name, 'foo') !== 0) {
return;
}
include_once 'path_to_your_generated_autoloader.php';
}
);
(为方便起见,我使用匿名函数,但实际使用什么取决于您)。
只有 foo
命名空间上的 class 才会命中您生成的文件。一旦命中,所有 classes 和函数都会被定义,所以这个自动加载器不会再次被命中。如果 class 不在 foo
命名空间中,它将 return 无害。
但是你还是有问题。
您生成的文件似乎包含 命名空间函数(例如 foo\bar()
)。 函数没有自动加载。因此,如果您在尝试在 foo
命名空间上加载 class 之前调用 foo\bar()
before,就会遇到麻烦。 (如果您只是在使用任何 class 之后才尝试使用这些函数,您会没事的;因为届时文件中的所有内容都会被加载)。
如果您想将您的函数保留在任何 class 之外,没有办法绕过它。也许您应该将这些函数生成为单个 "helper" class 的静态方法,例如 foo\Helper::bar()
。但这可能需要您更改代码生成的工作方式。