PHP Class Autoloading

一笑奈何 提交于 2019-12-10 21:47:55

问题


I have a "simple framework" whose main instance is $app. Now, what is the best way to implement an autoloader (without using Composer). What I need is to have a class which handles all the autoloading (supporting the various namespaces). I have a few approaches/dilemmas.

At first I thought I should create a "static" class which handles everything. But then something came to my mind. If I use the autoloader before instantiating $app (which contains all the paths), I would need to define the paths outside of $app. And also if an error occours in autoloading a class, I wouldn't be able to handle the error properly (error handler is inside $app, and instantiated after).

Then I thought of dependency injection, making the autoloader an object inside the app. That would resolve the error handling problem, and wouldn't need me to hard code paths or making them globals. But I would have to load many classes (including $app) too before I can instantiate the autoloader.

But really I'm in a world of pain because of this issue, I don't really know where to start, are there some advices I should take into account ? Can you explain me which method should I use and why ?

Thanks.


回答1:


As a result of the tips I got in this questions, I searched a bit more and found good resources from where to learn.

What's Autoloading ?

Autoloading is basically the process in which the program finds an unknown Class Name and attempts to load it without Class Name being defined. Without an autoloader, this behavior would result in a fatal error (for PHP at least). With an autoloader, things change, and the program will attempt loading Class Name, without knowing where to find it, but relying on functions or classes thought for this purpose, those functions/classes are called Autoloaders.

__autoload() vs spl_autoload_register()

In PHP we have two different ways to achieve autoloading (you might find useful to read it from PHP's site.). The first one is the old __autoload(), the newest is spl_autoload_register(). But what exactly is the difference ? Basically __autoload() is unique, having multiple Autoloaders would cause you many troubles and would get you in solving a problem which can be easily avoided by using the newest spl_autoload_* functions. spl_autoload_register() on the other side allow the program to have multiple Autoloaders by putting them in a stack, in this way the whole system becomes more flexible and much less complicated (having a single Autoloader for different purpose results in having a big unique function handling many requests, this way you'll have less code maintainability and reusability). Warning: using spl_autoload_register() will overwrite __autoload(), so be careful.

Coding standards (in PHP): PSR-0 vs PSR-4

Let's start by saying that PSR-4 is newer and it was thought to be an improvement of PSR-0, but not compulsory you must use 4 instead of 0, as the standard (PSR-4) states:

It is fully interoperable, and can be used in addition to any other autoloading specification, including PSR-0.

So why should I use one instead of the other ?

Now this is up to you, but as a suggestion PSR-4 solves the "nesting" problem PSR-0, so you should be using the former. Let's suppose I have an application, and my application relies on external components, PSR-0 follows this syntax:

\vendor\(sub_namespaces\)class_name

Where sub_namespaces might be absent. But that translates to a fully qualified path on the hard drive:

path/to/project/vendor/sub/namespaces/class/name.php

Now let's suppose I want to include a library called YourLibrary in my application

\YourDeveloper\YourLibrary\YourFunction

This would translate to

/path/to/project/YourDeveloper/YourLibrary/YourFunction

And here's the problem, what if I want to put that library in a subfolder of mine:

/path/to/project/vendor/vendor_name

PSR-0 is absolute, you can't just modify the namespace to control this behaviour (it would be silly and require too much time) so it would translate to this:

/path/to/project/vendor/YourDeveloper/src/YourDeveloper/YourLibrary/YourFunction

Isn't that extremely nested and redundant ? Well, using PSR-4 you can avoid that and transform that into

/path/to/project/vendor/YourDeveloper/YourLibrary/YourFunction

Without altering the namespaces or the Autoloaders. That's basically how PSR-4 works. This explanation is quite short, but it gives you a glance of why PSR-4 was born and why you SHOULD use it. If you require a more adequate explanation, you can go and read the PSR-0/4 specifications or you can read this beautiful article on sitepoint.

Should I really be caring about standards ?

If you have been in the world of programming for enough time, you probably won't end up asking such question. But if you are, you are probably a new programmer, or you haven't been a programmer long enough, that's why you SHOULD read this answer. In the IT world, and especially in programming, standards are almost everything. If we hadn't followed standards, we might not even have videos on our computers. If anyone follows their own standard, everything would look messy, and in this case, Autoloaders would become personal; so instead of having one SIMPLE Autoloader, you would end up having many Autoloaders, one for each standard, making your application much more difficult to maintain and to debug (because everyone can make erors).




回答2:


If you writing a framework you should always look at existing ones, which properly allready solved your problem. Then you get inspired or just use that component. A great starting point is symfony, their components are seperated and tested. If you load it with composer or download it manually is your choice ;)

They also have a Classloader http://symfony.com/doc/2.0/components/class_loader.html which you could use as it. Or you just take a look what their approach is.

The Autoloader (or your classloader) should be the included at the beginning of your application and this should be the only class you include directly.

If you want to load your class dynamic your have to take a look how your store your classes, there are diffrent "standard" ways like PSR0 http://www.php-fig.org/psr/psr-0/. If you want your users to add their own classes, when they using your framework you should consider to support multiple standards.



来源:https://stackoverflow.com/questions/23312688/php-class-autoloading

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!