命名空间与自动加载系列(六)--自动加载(完)

作者: 温新

分类: 【PHP基础】

阅读: 2567

时间: 2021-05-17 11:28:09

为什么要使用类的自动加载?

前面可以看到,使用到其它类时需要通过include关键字将其引入,如果有N多个需要通过include来引入,不太现实,为了解决这个问题,可以使用类的自动加载。

__autoload已经被废弃,旧代码中可能还可以看到。现在推荐使用sqp_autoload_register

准备测试目录与文件,结构如下:

demo01
	bootstrap.php
	App
		Controller
			Index.php
			Post.php
		Module
			Post.php

每个文件内容如下:

// App/Controller/Index.php
<?php
namespace App\Controller;

class Index
{
	public static function index()
	{
		echo 'Index控制器:' . __METHOD__;
	}
}

// App/Controller/Post.php
<?php
namespace App\Controller;

class Post
{
	public static function index()
	{
		echo 'Post控制器:' . __METHOD__;
	}
}

// App/Module/Post.php
<?php
namespace App\Module;

class Post
{
	public static function index()
	{
		echo 'Post模型:' . __METHOD__;
	}
}

方式一,使用函数方式实现自动加载

// App/bootstrap.php

<?php

// 自动加载类文件

/**
* @param string $class 类的命名空间,如 App\Controller\Index
*/
spl_autoload_register(function($class){
	// 将命名空间命名路径转为文件路径
	$fileName = str_replace('\\', '/', $class) . '.php';
	require $fileName;
});
// App/index.php

<?php

include './bootstrap.php';

use App\Controller\Index;
use App\Module\Post;

Index::index();
Post::index();

使用函数方式实现类的自动加载完成。需要使用哪一个类直接引入(当然了,这个类是要存在的,不然要报错咯)。

方式二,使用面向对象方式实现

现在来bootstrap.php改造为面向对象

// App/bootstrap.php

?php

namespace App;

// 自动加载类文件
class Bootstrap
{
	public static function boot()
	{
		// 实例化自身并调用autoload方法
		spl_autoload_register([new self, 'autoload']);
	}

	public function autoload(string $class)
	{
		echo $class;die;
		$fileName = str_replace('\\', '/', $class) . '.php';
		require $fileName;
	}
}

Bootstrap::boot();

方式三,使用composer实现自动加载

1)删除bootstrap.php文件

2)使用composer进行初始化

cd demo

composer init

This command will guide you through creating your composer.json config.
Package name (<vendor>/<name>) [root/demo]:

执行composer init出现的一系列东西暂时不用管,直接回车即可。

如是出现 Author [, n to skip]: Invalid author string. Must be in the format: John Smith john@example.com

输入 n 跳过

执行完composer init后,根目录中多出一个composer.json文件,其内容如下:

{
    "name": "45796/demo",
    "require": {}
}

3)修改composer.json

{
    "name": "45796/demo",
    "require": {},
    "autoload":{
    	"psr-4": {
    		"App\\":"App"
    	}
    }
}

自动加载遵循psr-4规范,"App\\":"App"的关系时,"命名空间":"对应的文件夹"

4)生成自动加载

composer install

# 执行结果
No lock file found. Updating dependencies instead of installing from lock file. Use composer update over composer install if you do not have a lock file.
Loading composer repositories with package information
Updating dependencies
Nothing to modify in lock file
Writing lock file
Installing dependencies from lock file (including require-dev)
Nothing to install, update or remove
Generating autoload files

执行成功后,会在应用根目录生成vendor目录,其中就包含自动加载的文件

5)使用自动加载

index.php文件中引入并使用自动加载

// index.php

<?php
include './vendor/autoload.php';

use App\Controller\Index;
use App\Module\Post;

Index::index();
Post::index();

加载文件案例

使用composer自动加载后,还可以自动加载文件。TP框架中有一个common.php文件,可以存放通用文件。以Laravel文件,如想要添加一个公用的助手函数文件,其没有直接提供,此时就可以通过composer自动加载文件实现。

第一步:修改compsoer.json

{
    "name": "45796/demo",
    "require": {},
    "autoload":{
    	"files":[
    		"Help/Helper.php"
    	],
    	"psr-4": {
    		"App\\":"App"
    	}
    }
}

第二步:应用中添加对应的文件

// 文件位置:App/Help/Helper.php

<?php

function show()
{
	echo '公共文件';
}

第三步:composer更新

composer update

第四步:使用

<?php
    
show();

2021-04-17

请登录后再评论