PHP类自动加载 [英] PHP Class Autoloading

查看:68
本文介绍了PHP类自动加载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单框架",其主要实例为$ app.现在,实现自动加载器的最佳方法是什么(不使用Composer).我需要的是一个处理所有自动加载(支持各种名称空间)的类.我有一些方法/难题.

起初,我认为我应该创建一个处理所有问题的静态"类.但是后来我想到了一些事情.如果在实例化$ app(包含所有路径)之前使用自动加载器,则需要在$ app之外定义路径.而且,如果在自动加载类时发生错误,我将无法正确处理该错误(错误处理程序位于$ app内,并在之后实例化).

然后我想到了依赖注入,使自动加载器成为应用程序内部的对象.这将解决错误处理问题,并且不需要我硬编码路径或使它们成为全局变量.但是在实例化自动加载器之前,我还必须加载许多类(包括$ app).

但是,由于这个问题,我真的很痛苦,我真的不知道从哪里开始,有什么建议我应该考虑吗?您能解释一下我应该使用哪种方法以及为什么吗?

谢谢.

解决方案

作为我在此问题中获得的提示的结果,我进行了更多搜索,并找到了可从何处学习的良好资源.

什么是自动加载?

基本上,自动加载是程序找到未知类名称并尝试在未定义类名称的情况下加载它的过程.如果没有自动加载器,此行为将导致致命错误(至少对于PHP).使用自动加载器时,情况会发生变化,程序将尝试加载类名,而又不知道在哪里找到它,而是依赖为此目的而想到的函数或类,这些函数/类被称为 Autoloaders ./p>

__ autoload()与spl_autoload_register()

在PHP中,我们有两种实现自动加载的方式(您可能会从 PHP的站点 .).第一个是旧的 __ autoload() ,最新的是 spl_autoload_register() .但是到底有什么区别呢?基本上__autoload()是唯一的,拥有多个自动加载器会给您带来很多麻烦,并使您能够解决一个问题,而使用最新的spl_autoload_ *函数可以轻松避免该问题.另一方面, spl_autoload_register()通过将程序放入堆栈,使程序具有多个自动加载器,这样,整个系统将变得更加灵活且复杂得多(只有一个自动加载器可用于不同目的的结果)拥有一个强大的独特功能来处理许多请求,这样一来,您的代码可维护性和可重用性将降低. 警告:使用spl_autoload_register()会覆盖__autoload(),因此请小心.

编码标准(在PHP中):PSR-0与PSR-4

让我们先说 PSR-4 较新,并且认为是 PSR-0 ,但不是强制性的,您必须使用4而不是0,因为标准(PSR-4)规定:

它是完全可互操作的,并且除其他任何自动加载规范(包括PSR-0)外,还可以使用.

那我为什么要使用一个而不是另一个?

现在,这取决于您,但是建议PSR-4解决嵌套"问题PSR-0,因此您应该使用前者.假设我有一个应用程序,而我的应用程序依赖于外部组件,PSR-0遵循以下语法:

\vendor\(sub_namespaces\)class_name

可能不存在sub_namespaces的地方.但这会转换为硬盘上的完全限定路径:

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

现在让我们假设我想在我的应用程序中包含一个名为YourLibrary的库

\YourDeveloper\YourLibrary\YourFunction

这将翻译为

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

这是问题所在,如果我要将那个库放在我的子文件夹中怎么办:

/path/to/project/vendor/vendor_name

PSR-0是绝对的,您不能只修改名称空间来控制此行为(这很愚蠢,需要太多时间),因此它将转换为:

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

那不是非常嵌套和多余的吗?好吧,使用PSR-4可以避免这种情况,并将其转化为

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

不更改名称空间或自动加载器.基本上,这就是PSR-4的工作方式.这个解释很简短,但是它使您了解了PSR-4的诞生原因以及为什么应该使用它.如果您需要更充分的说明,则可以阅读PSR-0/4规范,也可以阅读

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.

解决方案

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).

这篇关于PHP类自动加载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆