PHP 可以透过 include、include_once、require、require_once 来将档案引入, 一般来说以 OOP 写法习惯, 一个档案一个 class, 所以如果我们要用到 Car.php 的 Car class, 我们必须引入 Car.php
// index.php
include "Car.php";
$car = new Car();
这样没有问题, 但是如果我们有很多 class 要用时, 都要一个一个手动引入, 实在是有违工程师初心, 最好是用到的时候表面上可以直接用, 实际上系统帮我们自动引入相关 php 档案, PHP 提供了一些 spl_autoload 相关函数来让我们可以完成自动引入的功能
<?php
/*
spl_autoload_register(?callable $callback = null, bool $throw = true, bool $prepend = false): bool
注册一个函数到 spl_autoload 伫列, 如果伫列还没启用就启用
$callback: 欲注册的自动引入函数, 如果没有提供, 会自动注册 spl_autoload 函数, 这是系统预设的自动引入函数
$throw: 无法注册成功时, 是否抛出异常
$prepend: 若为 true, 表示注册的函数放入伫列头部, false, 放入尾部
概念: 当使用到未被定义的 class 或 interface 时, PHP 引擎会通过自动引入函数来引入所需要的 class, interface
*/
// 假设 class 都放在 ./classes 目录里
// ./classes/Car.php
class Car
{
public function start()
{
echo "car is starting";
}
}
// index.php
function autoload($className) $filename;
{
$filename = __DIR__ . "/classes/" . $className . ".php";
if (is_readable($filename)) {
include $filename;
}
}
spl_autoload_register("autoload");
$car = new Car();
$car->start();
再搭配 namesapce 的使用可以, 实作出 PSR-4 的 Autoloader
<?php
// 自动引入类
class Psr4AutoLoad
{
// 这里面存放命名空间映射
protected $maps = [];
public function __construct()
{
spl_autoload_register([$this, 'autoload']);
}
// 自己写的自动引入
public function autoload($className)
{
// 完整的类名由命名空间名和类名组成
// 得到命名空间名, 根据命名空间名得到其目录路径
$pos = strrpos($className, '\\'); //找最右边的'\'
$namespace = substr($className, 0, $pos);
// 得到类名
$realClass = substr($className, $pos + 1);
// 找到文件并且包含进来
$this->mapLoad($namespace, $realClass);
}
// 根据命名空间名得到目录路径并且拼接真正的文件全路径
protected function mapLoad($namespace, $realClass)
{
if (array_key_exists($namespace, $this->maps)) {
$namespace = $this->maps[$namespace];
}
// 处理路径
$namespace = rtrim(str_replace('\\/', '/', $namespace), '/') . '/';
// 拼接文件全路径
$filePath = $namespace . $realClass . '.php';
// 将该文件包含进来即可
if (file_exists($filePath)) {
include $filePath;
} else {
die('该文件不存在');
}
}
// 给一个命名空间, 给一个路径, 将命名空间和路径保存到映射阵列中
public function addMaps($namespace, $path)
{
if (array_key_exists($namespace, $this->maps)) {
die('此命名空间已经映射过');
}
// 命名空间和路径以键值对形式存放到阵列中
$this->maps[$namespace] = $path;
}
}
$autoloader = new Psr4AutoLoad();
接续昨日的对话流设计, 现在我们要进入实作的部分让各位能更了解设计流程。 首先从设定 Action...
上一回,我提到 CC: Tweaked 的 Computer 方块有许多基础指令 但我不打算逐一介绍...
Wentz的风险模型 (Wentz’s Risk Model)结合了孔雀模型(Peacock Mo...
点击劫持 点击劫持(Clickjacking) 技术又称为 界面伪装攻击(UI redress at...
直接在官网上下载即可。 这边选择自己的系统 这里将这两个打勾就能直接用右键开启 ...