Issue
I am using a parser generator that spits out a long file (~35000 lines) file with multiple PHP classes and functions in it. The file looks like this:
<?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.
This doesn't play very well with Composer's autoloading mechanism, which prefers to either:
- Load a file containing a single class, by defining it in
autoload.psr-4
. - Load an entire file whenever
vendor/autoload.php
isrequire
'd, by defining it inautoload.files
I would like to defer the loading of this file as far as possible, since the file is quite heavy and loading it on every request would burden the server quite a bit.
What I'm trying to do here is to make Composer load the file only when its namespace foo
is referred somewhere else in my code.
How can I do this?
Solution
You could create an additional autoloader that would only handle classes in your specific namespace:
// 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';
}
);
(I'm using an anonymous function for convenience sake, but it's up to you what you actually use).
Your generated file would only be hit if a class on the foo
namespace. Once hit, all classes and functions would be defined, so this autoloader wouldn't be hit again. If the class is not on the foo
namespace, it would return harmlessly.
But you still have a problem.
It seems your generated file includes namespaced functions (e.g. foo\bar()
). And there is no autoload for functions. So if you call foo\bar()
before trying to load a class on the foo
namespace, you'd be in trouble. (If you only tried to use these functions after you used any class, you'd be fine though; since by then everything in the file would be loaded).
If you want to keep your functions outside any classes, there is no way around it. Maybe you should generate these functions as static methods of a single "helper" class, like foo\Helper::bar()
. But this would probably require you changing how your code generation works.
Answered By - yivi
0 Comments:
Post a Comment
Note: Only a member of this blog may post a comment.