扫码关注官方订阅号
最近看laravel4的代码,发现其中Config类(Repository)中的set和get方法并不是静态方法,但调用时却可以使用Config::get('app.url'), Config::set('app.url', 'http://xxx.xx')等
请问这个是如何实现的?
走同样的路,发现不同的人生
请看依次下面代码。
https://github.com/laravel/laravel/blob/master/app/config/app.php#L144
'aliases' => array( 'App' => 'Illuminate\Support\Facades\App', 'Artisan' => 'Illuminate\Support\Facades\Artisan', 'Auth' => 'Illuminate\Support\Facades\Auth', 'Blade' => 'Illuminate\Support\Facades\Blade', 'Cache' => 'Illuminate\Support\Facades\Cache', 'ClassLoader' => 'Illuminate\Support\ClassLoader', 'Config' => 'Illuminate\Support\Facades\Config', );
https://github.com/laravel/framework/blob/master/src/Illuminate/Support/Facades/Config.php
<?php namespace Illuminate\Support\Facades; /** * @see \Illuminate\Config\Repository */ class Config extends Facade { /** * Get the registered name of the component. * * @return string */ protected static function getFacadeAccessor() { return 'config'; } }
https://github.com/laravel/framework/blob/master/src/Illuminate/Support/Facades/Facade.php#L198
public static function __callStatic($method, $args) { $instance = static::resolveFacadeInstance(static::getFacadeAccessor()); switch (count($args)) { case 0: return $instance->$method(); case 1: return $instance->$method($args[0]); case 2: return $instance->$method($args[0], $args[1]); case 3: return $instance->$method($args[0], $args[1], $args[2]); case 4: return $instance->$method($args[0], $args[1], $args[2], $args[3]); default: return call_user_func_array(array($instance, $method), $args); } }
关键就是 __callStatic 方法的继承。在执行未定义的静态方法时,如果类方法中定义了这个 __callStatic,程序就会执行这个地方的代码。
__callStatic
Config 类实际上是 Illuminate\Support\Facades\Config 的别名,
Config
Illuminate\Support\Facades\Config
当调用 Config::set() 和 Config::get() 静态方法时,就会执行 Step 2 中的代码。$instance 就是 Repository的一个实例。
Config::set()
Config::get()
Step 2
$instance
Repository
使用了拦截器__callStatic,当静态方式调用一个不存在的方法,会被这个方法拦截,第一个参数是静态调用方法名,第二个参数是一个包含调用方法参数的数组。他在拦截器方法里面做了处理,比如使用了call_user_func去自动加载对应的方法。
call_user_func
看你贴的源码里面还有句延迟静态绑定,不过不重要,重要的就是这个拦截器。
PHP的namespace就是奇葩
微信扫码关注PHP中文网服务号
QQ扫码加入技术交流群
扫描下载App
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
PHP学习
技术支持
返回顶部
请看依次下面代码。
Step 0
https://github.com/laravel/laravel/blob/master/app/config/app.php#L144
Step 1
https://github.com/laravel/framework/blob/master/src/Illuminate/Support/Facades/Config.php
Step 2
https://github.com/laravel/framework/blob/master/src/Illuminate/Support/Facades/Facade.php#L198
关键就是
__callStatic
方法的继承。在执行未定义的静态方法时,如果类方法中定义了这个__callStatic
,程序就会执行这个地方的代码。Config
类实际上是Illuminate\Support\Facades\Config
的别名,当调用
Config::set()
和Config::get()
静态方法时,就会执行Step 2
中的代码。$instance
就是Repository
的一个实例。使用了拦截器
__callStatic
,当静态方式调用一个不存在的方法,会被这个方法拦截,第一个参数是静态调用方法名,第二个参数是一个包含调用方法参数的数组。他在拦截器方法里面做了处理,比如使用了call_user_func
去自动加载对应的方法。看你贴的源码里面还有句延迟静态绑定,不过不重要,重要的就是这个拦截器。
PHP的namespace就是奇葩