这里以重写 app/Providers/AppServiceProvider.php
为例
1.新建 app/CustomAppServiceProvider.php
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* @return void
*/
public function register()
{
}
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
echo '这是我的重写 AppServiceProvider';
dd(__METHOD__);
}
}
Tip
这里需要注意的是,app/CustomAppServiceProvider.php
文件里的命名空间和类名要与app/Providers/AppServiceProvider.php
的保持一致。
2.修改 public/index.php
require __DIR__.'/../vendor/autoload.php';
为:
$baseDir = dirname(dirname(__FILE__));
$loader = require __DIR__.'/../vendor/autoload.php';
$loader->addClassMap(['App\\Providers\\AppServiceProvider' => $baseDir . '/app/CustomAppServiceProvider.php']);
3.访问测试 http://domain
输出
这是我的重写 AppServiceProvider
"App\Providers\AppServiceProvider::boot"
以这种方式可以重写任意 php 文件,但是缺点也很明显,就是无法继承原始类,所以还是有些麻烦的。你们怎么看??
classMap 原理分析:
- 入口文件 `public/index.php’
导入 composer autoload
require __DIR__.'/../vendor/autoload.php';
- 导入自动加载
vendor/compsoer/autoload_real.php
//导入自动加载
require_once __DIR__ . '/composer/autoload_real.php';
//返回自动加载实例
return ComposerAutoloaderInit54df22c225263f90be475b6ea9e2a98d::getLoader();
- 找到文件
vendor/composer/autoload_real.php
47 行
//导入自动加载类映射
$classMap = require __DIR__ . '/autoload_classmap.php';
- 找到文件
vendor/composer/autoload_classmap.php
可以看到文件内容是携带命名空间的类和文件地址的对应关系,其实意思就是 类指向此文件地址。
<?php
// autoload_classmap.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
'Adbar\\Dot' => $vendorDir . '/adbario/php-dot-notation/src/Dot.php',
...
...
...
)
- 其实我们在 composer.json 文件中也可以配置映射关系
"autoload": {
"classmap": [
"database/seeds",
"database/factories"
]
},
推广一下我的开源商城:strongshop
Gitee 地址:https://gitee.com/openstrong/strongshop