include and require are the two basic methods of introducing files in PHP. There is nothing wrong with using include and require directly in small-scale development, but in large projects, it will cause a lot of include and require accumulation. Such code is inelegant, inefficient, and difficult to maintain.
In order to solve this problem, some frameworks will provide a configuration list of imported files and import the required files when the object is initialized. But this only makes the code more concise, and the introduced effect is still unsatisfactory. After PHP5, with the improvement of PHP's object-oriented support, the __autoload function truly makes automatic loading possible.
* The functions of include and require are the same. The difference is that include will only generate a warning when an error occurs, while require will throw an error and terminate the script.
* The only difference between include_once and include is that include_once will check whether the file has been introduced, and if so, it will not be introduced again.
==================Automatic loading==================
Implementation The simplest way to autoload is to use the __autoload magic method. When the class to be used has not been introduced, this function will be triggered before PHP reports an error, and the undefined class name will be passed in as a parameter. As for the specific logic of the function, this needs to be implemented by the user himself.
First create an autoload.php to do a simple test:
1 2 3 4 5 |
|
Through this simple example, we can find that during the instantiation process of the class, the work done by the system is roughly like this ’s:
1 2 3 4 5 6 7 8 9 10 11 |
|
After understanding the working principle of the __autoload function, let us use it to implement automatic loading.
First create a class file (it is recommended that the file name be consistent with the class name), the code is as follows:
1 2 3 4 5 6 |
|
(I created a HelloWorld class here for demonstration) Next we have to define_ The specific logic of _autoload enables automatic loading:
1 2 3 4 5 |
|
==================Namespace============ ======
In fact, namespaces are not a new thing. Many languages (such as C++) have already supported this feature. It’s just that PHP started relatively late and was not supported until PHP 5.3.
In short, a namespace is an identifier, and its main purpose is to solve the problem of naming conflicts.
Just like in daily life, there are many people with the same name. How to distinguish these people? Then you need to add some additional logos.
It seems good to use your work unit as your logo, so you don’t have to worry about the embarrassment of “name collision”.
Here we will do a small task to introduce Baidu CEO Robin Li:
1 2 3 4 5 |
|
↑ This is Robin Li’s basic information. Namespace is his unit identification and class is his name.
The namespace is declared through the keyword namespace. If a file contains a namespace, it must declare the namespace before all other code.
1 |
|
↑ Under normal circumstances, whether you are introducing "Baidu Robin Li" or "Baidu Robin Li" to others, they can understand.
When the current namespace is not declared, qualified class names and fully qualified class names are equivalent. Because if you don't specify a space, it defaults to global (\).
1 |
|
↑ If you introduce Robin Li to their employees at Google, be sure to specify "Robin Robin of Baidu." Otherwise, he will think that Baidu is a department of Google and Robin Li is just one of its employees.
This example shows the difference between using qualified class names and fully qualified class names in namespaces. (Fully qualified class name = current namespace + qualified class name)
1 |
|
↑ The first situation is that others already know Robin Li, you only need to say the name directly, and he will know who you are referring to. The second situation is that Robin Li is their CEO. If you directly address the CEO, he can react immediately.
Using a namespace only prefixes the class name, which is less likely to cause conflicts. The system will still not automatically import it.
If the file is not introduced, the system will trigger the __autoload function and pass in the qualified class name as a parameter before throwing the "Class Not Found" error.
So the above examples are based on the situation that you have manually introduced the relevant files, otherwise the system will throw "Class 'Baidu\Robin Li' not found".
==================spl_autoload==================
接下来让我们要在含有命名空间的情况下去实现自动加载。这里我们使用 spl_autoload_register() 函数来实现,这需要你的 PHP 版本号大于 5.12。
spl_autoload_register 函数的功能就是把传入的函数(参数可以为回调函数或函数名称形式)注册到 SPL __autoload 函数队列中,并移除系统默认的 __autoload() 函数。
一旦调用 spl_autoload_register() 函数,当调用未定义类时,系统就会按顺序调用注册到 spl_autoload_register() 函数的所有函数,而不是自动调用 __autoload() 函数。
现在,我们来创建一个 Linux 类,它使用 os 作为它的命名空间(建议文件名与类名保持一致):
1 2 3 4 |
|
接着,在同一个目录下新建一个 PHP 文件,使用 spl_autoload_register 以函数回调的方式实现自动加载:
1 2 3 4 5 6 7 8 9 |
|
这里我们使用了一个数组去保存类名与文件路径的关系,这样当类名传入时,自动加载器就知道该引入哪个文件去加载这个类了。
但是一旦文件多起来的话,映射数组会变得很长,这样的话维护起来会相当麻烦。如果命名能遵守统一的约定,就可以让自动加载器自动解析判断类文件所在的路径。接下来要介绍的PSR-4 就是一种被广泛采用的约定方式。
=================PSR-4规范==================
PSR-4 是关于由文件路径自动载入对应类的相关规范,规范规定了一个完全限定类名需要具有以下结构:
1 |
|
如果继续拿上面的例子打比方的话,顶级命名空间相当于公司,子命名空间相当于职位,类名相当于人名。那么李彦宏标准的称呼为 "百度公司 CEO 李彦宏"。
PSR-4 规范中必须要有一个顶级命名空间,它的意义在于表示某一个特殊的目录(文件基目录)。子命名空间代表的是类文件相对于文件基目录的这一段路径(相对路径),类名则与文件名保持一致(注意大小写的区别)。
举个例子:在全限定类名 \app\view\news\Index 中,如果 app 代表 C:\Baidu,那么这个类的路径则是 C:\Baidu\view\news\Index.php
我们就以解析 \app\view\news\Index 为例,编写一个简单的 Demo:
1 |
|
通过这个 Demo 可以看出限定类名转换为路径的过程。那么现在就让我们用规范的面向对象方式去实现自动加载器吧。
首先我们创建一个文件 Index.php,它处于 \app\mvc\view\home 目录中:
1 2 3 4 5 |
|
接着我们在创建一个加载类(不需要命名空间),它处于 \ 目录中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
最后,将 Loader 类中的 autoload 注册到 spl_autoload_register 函数中:
1 2 |
|
示例中的代码其实就是 ThinkPHP 自动加载器源码的精简版,它是 ThinkPHP 5 能实现惰性加载的关键。
至此,自动加载的原理已经全部讲完了,如果有兴趣深入了解的话,可以参考下面的 ThinkPHP 源码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 |
|
相关推荐:
The above is the detailed content of Detailed explanation of PHP namespace and automatic loading instances. For more information, please follow other related articles on the PHP Chinese website!