天涯论坛

 找回密码
 立即注册
搜索
查看: 14|回复: 1

PHP自动加载

[复制链接]

2986

主题

3万

回帖

9956万

积分

论坛元老

Rank: 8Rank: 8

积分
99569168
发表于 2024-10-4 12:57:41 | 显示全部楼层 |阅读模式

自定义的自动加载函数:

系统的自动加载函数仅有一个__autoload(), 有时候略显不方便, 咱们有时候还需要分别定义区别的函数, 去做为自动加载函数,

以应对区别的情形, 此时就能够运用自定义加载函数。

bool spl_autoload_register ([ callable $autoload_function [,bool $throw = true [, bool $prepend = false ]]] )

autoload_function 欲注册的自动装载函数。倘若供给任何参数, 则自动注册 autoload 的默认实现函数spl_autoload()。

throw 此参数设置了 autoload_function 没法成功注册时, spl_autoload_register()是不是抛出反常

prepend 倘若是 true, spl_autoload_register() 会添加函数到队列之首, 而不是队列尾部。

<?php //1,先声明要做为自定义加载函数的函数名,能够多个:spl_autoload_register(auto1); spl_autoload_register(auto2); //2,分别定义这几个函数,其中写规律去加载需要的类文件。 function auto1($className){ echo "<h1>$className</h1>"; $file =./class/ . $className . .class.php; if(file_exists($file)){ //file_exists()判断文件是不是存在 require_once $file; } } function auto2($className){ echo "<h4>$className</h4>"; $file = ./library/ . $className . .class.php; if(file_exists($file)){ //file_exists()判断文件是不是存在 require_once$file; } }//3,运用类,需要的时候就会自动依次调用这几个函数去完成加载工作。 $obj1 = new A(); $obj2 = new B(); var_dump($obj1,$obj2); ?>

PHP自动加载——PSR4规范

1.先来介绍一下PSR规范

PHP-FIG, 它的网站是:www.php-fig.org。便是这个联盟组织发明和创造了PSR规范, 其中自动加载触及其中两个规范, 一个是PSR0, 一个是PSR4, PSR0规范已然过时了,

官方有提示, 此刻重点是用PSR4规范定义自动加载标准。

PSR-4风格

类名:ZendAbc

命名空间前缀:Zend

文件基目录:/usr/includes/Zend/

文件路径:

/usr/includes/Zend/Abc.php

类名:SymfonyCoreRequest

命名空间前缀:SymfonyCore

文件基目录:./vendor/Symfony/Core/

文件路径:

./vendor/Symfony/Core/Request.php

3. 自动加载办法

spl_autoload_register(function ($class) { // 命名空间前缀 $prefix = Foo\\Bar\\; // 命名空间前缀对应的基本目录 $base_dir = __DIR__ . /src/; // 检测new的类是不是有命名空间前缀$len = strlen($prefix);if (strncmp($prefix, $class, $len) !== 0) { return; } // 获取去掉命名空间前缀后的类名 $relative_class = substr($class, $len); // 将命名空间的中的分隔符替换为目录分隔符,再加上基本目录和.php后缀,最后拼接成 // 文件路径 $file = $base_dir . str_replace(\\, /, $relative_class) . .php; // 倘若文件存在则require if (file_exists($file)) { require$file; } });

然则上面的办法只能适用固定的命名空间前缀, 不可通用。

4、再次优化通用自动加载办法

<?php namespace Example; /** * 下面这个例子实现了一个命名空间前缀对应多个基本目录 * * 此刻咱们的目录结构是下面这般: * * /demo/autoload/ * controller/ * DemoController.php # Foo\Bar\DemoController * Admin/ * AdminController.php # Foo\Bar\Admin\AdminController * model/ * DemoModel.php # Foo\Bar\DemoModel * Admin/ * AdminModel.php # Foo\Bar\Admin\AdminModel * * Foo\Bar分别对应基本路径 /demo/autoload/controller 和 /demo/autoload/model */ class Psr4AutoloaderClass { /** * 一个数组,key为命名空间前缀,值为基本路径 * * @var array */ protected $prefixes = array(); /** * 封装自动加载函数 * * @return void */ public function register() { spl_autoload_register(array($this, loadClass)); } /** * * 添加一个基本路径对应一个命名空间前缀 * * @paramstring $prefix 命名空间前缀. *@param string $base_dir 命名空间类文件的基本路径 * @param bool true为往数组头部添加元素,false为往数组尾部添加元素 * @return void */ public function addNamespace($prefix, $base_dir, $prepend = false) { // 去掉左边的\ $prefix = trim($prefix, \\) . \\; // 规范基本路径$base_dir = rtrim($base_dir, DIRECTORY_SEPARATOR) ./; // 初始化数组 if (isset($this->prefixes[$prefix]) === false) { $this->prefixes[$prefix] = array(); } // 将命名空间前缀和基本路径存入数组 if($prepend) { array_unshift($this->prefixes[$prefix], $base_dir); } else { array_push($this->prefixes[$prefix], $base_dir); } } /** * 真正包括文件办法,将给到类名文件包括进来 * *@param string $class 全限定类名(包括命名空间). * @return 成功将返回文件路径,失败则返回false */ public function loadClass($class) { $prefix = $class; //查询$prefix最后一个\的位置,瞧瞧最后一个\之前的字符串是不是在$this->prefixes中 //倘若不存在则继续查找上一个\的位置,获取上一个\之前的字符串是不是在$this->prefixes中 //倘若循环结束还是找到则返回false while (false !== $pos = strrpos($prefix, \\)) { $prefix = substr($class, 0, $pos + 1); $relative_class = substr($class, $pos +1); $mapped_file = $this->loadMappedFile($prefix, $relative_class); if ($mapped_file) { return $mapped_file; } //去掉右边的\$prefix = rtrim($prefix,\\); } return false; } /** * 倘若参数中的$prefix在$this->prefixes中存在,那样将循环$this->prefixes[$prefix]里的value(基本路径) * 之后拼接文件路径,倘若文件存在将文件包括进来 * *@param string $prefix 命名空间前缀. * @paramstring $relative_class 真正的类名(不包括命名空间路径的类名). *@return mixed 包括成功返回文件路径,否则返回false */ protected function loadMappedFile($prefix, $relative_class) { // 检测数组中是不是有$prefix这个key if(isset($this->prefixes[$prefix]) === false) { return false; } // 将数组中所有的基本路径中的文件包括进来 foreach ($this->prefixes[$prefix] as $base_dir) { // 拼接文件绝对路径$file = $base_dir . str_replace(\\, /, $relative_class) . .php; // 倘若文件存在则包括进来 if ($this->requireFile($file)) { // 返回文件路径 return$file; } }// 找到文件 return false; } /** *倘若文件存在则包括进来. * * @param string $file 文件路径. * @returnbool */ protected function requireFile($file) { if (file_exists($file)) { require $file; return true; } return false; } }




上一篇:Ubuntu 24.04 安排 nginx + php-fpm,入门PHP必须!
下一篇:常用PHP运行环境一键安装包(Windows)
回复

使用道具 举报

2986

主题

3万

回帖

9956万

积分

论坛元老

Rank: 8Rank: 8

积分
99569168
 楼主| 发表于 2024-10-29 03:00:17 | 显示全部楼层
你的见解独到,让我受益匪浅,非常感谢。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

站点统计|Archiver|手机版|小黑屋|天涯论坛 ( 非经营性网站 )|网站地图

GMT+8, 2024-11-23 10:10 , Processed in 0.116200 second(s), 21 queries .

Powered by Discuz! X3.4

Copyright © 2001-2023, Tencent Cloud.