该篇属于 Laravel 底层核心技术实战揭秘这一课程 laravel 底层核心概念解析这一章的扩展阅读由于要真正学好 laravel 底层, 有些 PHP 相关的知识必须得了解, 考虑到学员们的基础差异, 为了避免视频当中过于详细而连篇累牍, 故将一些 laravel 底层实现相关的 PHP 知识点以文章形式呈现, 供大家预习和随时查阅
传统上, 在 PHP 里, 当我们要用到一个 class 文件的时候, 我们都得在文档头部 require 或者 include 一下:
- <?php
- require_once('../includes/functions.php');
- require_once('../includes/database.php');
- require_once('../includes/user.php');
- ...
但是一旦要调用的文档多了, 就得每次都写一行, 瞅着也不美观, 有什么办法能让 PHP 文档自动加载呢?
- <?php
- function __autoload($class_name)
- {
- require "./{$class_name}.php";
- }
对, 可以使用 PHP 的魔法函数__autoload(), 上面的示例就是自动加载当前目录下的 PHP 文件当然, 实际当中, 我们更可能会这么来使用:
- <?php
- function __autoload($class_name)
- {
- $name = strtolower($class_name);
- $path = "../includes/{$name}.php";
- if(file_exists($path)){
- require_once($path);
- }else{
- die("the file {$class_name} could not be found");
- }
- }
也即是做了一定的文件名大小写处理, 然后在 require 之前检查文件是否存在, 不存在的话显示自定义的信息
类似用法经常在私人项目, 或者说是单一项目的框架中见到, 为什么呢? 因为你只能定义一个__autoload function, 在多人开发中, 做不到不同的 developer 使用不同的自定义的 autoloader, 除非大家都提前说好了, 都使用一个__autoload, 涉及到改动了就进行版本同步, 这很麻烦
也主要是因为此, 有个好消息, 就是这个__autoload 函数马上要在
7.2
版本的 PHP 中弃用了
Warning This feature has been DEPRECATED as of PHP 7.2.0. Relying on this feature is highly discouraged.
那么取而代之的是一个叫
spl_autoload_register()
的东东, 它的好处是可以自定义多个 autoloader.
- // 使用匿名函数来 autoload
- spl_autoload_register(function($class_name) {
- require_once('...');
- });
- // 使用一个全局函数
- function Custom()
- {
- require_once('...');
- }
- spl_autoload_register('Custom');
- // 使用一个 class 当中的 static 方法
- class MyCustomAutoloader
- {
- static public function myLoader($class_name)
- {
- require_once('...');
- }
- }
- // 传 array 进来, 第一个是 class 名, 第二个是方法名
- spl_autoload_register(['MyCustomAutoloader','myLoader']);
- // 甚至也可以用在实例化的 object 上
- class MyCustomAutoloader
- {
- public function myLoader($class_name)
- {
- }
- }
- $object = new MyCustomAutoloader;
- spl_autoload_register([$object,'myLoader']);
值得一提的是, 使用 autoload, 无论是__autoload(), 还是
spl_autoload_register()
, 相比于 require 或 include, 好处就是 autoload 机制是 lazy loading, 也即是并不是你一运行就给你调用所有的那些文件, 而是只有你用到了哪个, 比如说 new 了哪个文件以后, 才会通过 autoload 机制去加载相应文件
当然, laravel 包括各个 package 里也是经常用到
spl_autoload_register
, 比如这里:
- /**
- * Prepend the load method to the auto-loader stack.
- *
- * @return void
- */
- protected
- function prependToLoaderStack() {
- spl_autoload_register([$this, 'load'], true, true);
- }
感兴趣的童鞋可以使用
spl_autoload_functions()
来查看一个系统中注册了多少个 autoloader, 你可以在 laravel 中调用看一下~
更详细的我们会在 Laravel 底层核心技术实战揭秘里阐述
来源: https://juejin.im/post/5a75ae9a6fb9a063543c050b