文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

PHP类的引入方式

2023-09-22 15:29

关注

名词解释

  1. 语言结构&函数

原因是在PHP中,函数都要先被PHP解析器(Zend引擎)分解成语言结构,所以有此可见,函数比语言结构多了一层解析器解析。这样就能比较好的理解,什么语言结构比函数快了。

通过function_exists判断,如果是函数会返回true

$a = [    'echo', 'print', 'die', 'isset', 'unset',    'include', 'require', 'array', 'list',    'empty', 'include_once', 'require_once', 'array_merge',    'is_null', 'empty', 'function_exists', 'defined', 'define',    'if', 'for', 'foreach',];foreach ($a as $b) {    echo "$b: " . intval(function_exists($b)) . PHP_EOL;}

在php.ini有一个配置为disable_functions,只要填写想要禁用的函数(逗号分隔),就能够禁用了

disable_functions = array_merge,echo

请添加图片描述

var_dump(json_encode(new stdClass()));var_dump(array_merge([2], [1]));echo 123 . PHP_EOL;

请添加图片描述

例子

例子可以参考我的git:https://github.com/JACKCHEN213/php_class_load/tree/master

手动引入

require

引入一个外部文件

引入顺序
  1. 使用
require "xxx.php";require("yyy.php");
  1. 引入说明

require是一个语言结构,并且支持这两种调用方式

测试
引入不存在的文件

注意如果文件无法访问, include 和 require 在分别发出最后的 E_WARNING 或 E_ERROR 之前,都会发出额外一条 E_WARNING。

<?phprequire "9——9.txt";echo 1;

请添加图片描述

@require "9——9.txt";echo 1;

请添加图片描述

重复引入
function test(){    echo 1;}
require '1.php';require '1.php';test();

请添加图片描述

if (!function_exists('test')) {    function test()    {        echo 1;    }}

请添加图片描述

require支持重复引入,但函数不支持重复定义

引入存在相同函数
require '2.php';require '3.php';echo 111 . PHP_EOL;
function test(){    echo 2;}
function test(){    echo 3;}

请添加图片描述

require_once

require_once 表达式和 require 表达式完全相同,唯一区别是 PHP 会检查该文件是否已经被包含过,如果是则不会再次包含。

测试
引入不存在的文件
require_once 'xxxxx.yyyy';echo 111 . PHP_EOL;  

报错,忽略错误直接结束

重复引入
function test(){    echo 1;}
require_once '1.php';require_once '1.php';test();

请添加图片描述

include

require 和 include 几乎完全一样,除了处理失败的方式不同之外。require 在出错时产生 E_COMPILE_ERROR 级别的错误。换句话说将导致脚本中止而 include 只产生警告(E_WARNING),脚本会继续运行。

测试
引入错误
@include 'xxxxx.yyyy';echo 111 . PHP_EOL;

请添加图片描述

引入错误,并调用目标文件的函数
<?php@include 'xxxxx.yyyy';test();echo 111 . PHP_EOL;

请添加图片描述

include_once

同include与require_once

自动引入

多个同名类、函数怎么区分调用?

问题
ehigh@ubuntu:autoload$ tree.├── 1.php├── 2.php├── 3.php└── 4.php
include_once "2.php";include_once "3.php";include_once "4.php";test();
function test(){    echo __FUNCTION__ . PHP_EOL;}

请添加图片描述

名字空间——namespace

  1. 用户编写的代码与PHP内部的类/函数/常量或第三方类/函数/常量之间的名字冲突。
  2. 为很长的标识符名称(通常是为了缓解第一类问题而定义的)创建一个别名(或简短)的名称,提高源代码的可读性。
用法
namespace top_name\second_name\...\last_name;
示例1
namespace t1 {    function test()    {        echo __FUNCTION__ . PHP_EOL;    }}namespace test {    function test()    {        echo __FUNCTION__ . PHP_EOL;    }}namespace test\test {    function test()    {        echo __FUNCTION__ . PHP_EOL;    }}// 多个namespace,顶级namespace这么用namespace {    \t1\test(); // t1\test    \test\test(); // test\test    \test\test\test(); // test\test\test}

请添加图片描述

示例2
ehigh@ubuntu:autoload$ tree.├── 1.php├── 2.php├── 3.php└── 4.php
namespace test;function test(){    echo __FUNCTION__ . PHP_EOL;}
namespace t1;function test(){    echo __FUNCTION__ . PHP_EOL;}
namespace test\t1;function test(){    echo __FUNCTION__ . PHP_EOL;}
include_once "2.php";include_once "3.php";include_once "4.php";\test\test();\t1\test();\test\t1\test();test();

请添加图片描述

use

引入命名空间下的文件,use与require和include是不相同的,使用use的前提是文件已经包含进当前文件。

用法
类:   use namespace\class;函数: use function namespache\function;常量: use const namespace\function;
示例1
namespace t1 {    function test()    {        echo __FUNCTION__ . PHP_EOL;    }}namespace test {    function test()    {        echo __FUNCTION__ . PHP_EOL;    }}namespace test\test {    function test()    {        echo __FUNCTION__ . PHP_EOL;    }}// 多个namespace,顶级namespace这么用namespace {    use function t1\test as t1;    use function test\test as t2;    use function test\test\test as t3;    t1(); // t1\test    t2(); // test\test    t3(); // test\test\test}
示例2
include_once "2.php";include_once "3.php";include_once "4.php";use function t1\test as t2;use function test\t1\test as t3;use function test\test as t1;t1(); // test\testt2(); // t1\testt3(); // test\t1\test

类的自动加载

现在我们可以使用namespace和use来区分类、函数、常量了,但是我们要将目标文件引入才能使用。单靠use不能将目标类导入,那么有什么办法可以不用引入(require)使用的文件呢?

php提供__autoload魔术函数和spl_autoload_register函数来实现类自动加载。

__autoload

请添加图片描述

用法
__autoload(string $class): void
示例1
ehigh@ubuntu:autoload$ tree.├── handle│   └── entry.php├── redis│   └── redis.php└── index.php
namespace redis\redis;class RedisConn{    public function __construct()    {        echo __METHOD__ . PHP_EOL;    }}
namespace handle\entry;use redis\redis\RedisConn;class Entry{    public function __construct()    {        echo __METHOD__ . PHP_EOL;        new RedisConn();    }}
use handle\entry\Entry;function __autoload($class){    $classmap = [        "redis\\redis\\RedisConn" => __DIR__ . "/redis/redis.php",        "handle\\entry\\Entry" => __DIR__ . "/handle/entry.php",    ];    if (isset($classmap[$class]) && is_file($classmap[$class])) {        require_once $classmap[$class];    } else {        throw new Exception("Class not found: " . $class);    }}$r = new Entry();

请添加图片描述

spl_autoload_register

spl_autoload_register — 注册给定的函数作为 __autoload 的实现

用法
spl_autoload_register(callable $autoload_function = ?, bool $throw = true, bool $prepend = false): bool
示例1
use handle\entry\Entry;spl_autoload_register(function ($class) {    $classmap = [        "redis\\redis\\RedisConn" => __DIR__ . "/redis/redis.php",        "handle\\entry\\Entry" => __DIR__ . "/handle/entry.php",    ];    if (isset($classmap[$class]) && is_file($classmap[$class])) {        require_once $classmap[$class];    } else {        throw new Exception("Class not found: " . $class);    }});new Entry();

请添加图片描述

示例2
use handle\entry\Entry;function load_entry(){    require_once "handle/entry.php";}function load_redis(){    require_once "redis/redis.php";}spl_autoload_register('load_redis');spl_autoload_register('load_entry');new Entry()

请添加图片描述

常量和函数的自动加载?

在上面,我们通过__autoload和spl_autoload_register来加载类,其中使用了namespace和use。
在第二节中,我们知道namespace可以用来修饰常量和函数,那么我们能不能使用__autoload和spl_autoload_register来加载呢?

示例1
namespace test;echo __FILE__ . PHP_EOL;function test(){    echo __FUNCTION__ . PHP_EOL;}const NAME = 'JackC';class Student{    public function __construct()    {        echo __METHOD__ . PHP_EOL;    }}
use test\Student;use function test\test;use const test\NAME;function load($class){    require_once "2.php";}spl_autoload_register('load');test();new Student();var_dump(NAME);

请添加图片描述
常量和函数写为类的静态属性和静态方法!

使用了类自动加载,use了相应类,类对应文件是否被引入了?
示例1
use handle\entry\Entry;use redis\redis\RedisConn;function load_entry(){    require_once "handle/entry.php";}function load_redis(){    require_once "redis/redis.php";}spl_autoload_register('load_redis');spl_autoload_register('load_entry');new RedisConn();var_dump(get_included_files());

请添加图片描述

类的自动加载是动态的!

composer引入

Composer 是 PHP 的一个依赖管理工具。它允许你申明项目所依赖的代码库,它会在你的项目中为你安装他们。

使用composer创建一个项目

mkdir test && cd testcomposer init
ehigh@ubuntu:test$ composer init                  Welcome to the Composer config generator                  This command will guide you through creating your composer.json config.Package name (<vendor>/<name>) [ehigh/test]: jackc/testDescription []: 测试项目Author [chenchao <1366294101@qq.com>, n to skip]: Minimum Stability []: 1Invalid minimum stability "1". Must be empty or one of: stable, RC, beta, alpha, devMinimum Stability []: devPackage Type (e.g. library, project, metapackage, composer-plugin) []: projectLicense []: xxx-xxx-xxxDefine your dependencies.Would you like to define your dependencies (require) interactively [yes]? Search for a package: thans/tp-jwt-authEnter the version constraint to require (or leave blank to use the latest version): 1.2.1Search for a package: Would you like to define your dev dependencies (require-dev) interactively [yes]? Search for a package: topthink/think-swooleEnter the version constraint to require (or leave blank to use the latest version): 4.0.7Search for a package: Add PSR-4 autoload mapping? Maps namespace "Jackc\Test" to the entered relative path. [src/, n to skip]: {    "name": "jackc/test",    "description": "测试项目",    "type": "project",    "require": {        "thans/tp-jwt-auth": "1.2.1"    },    "require-dev": {        "topthink/think-swoole": "4.0.7"    },    "license": "xxx-xxx-xxx",    "autoload": {        "psr-4": {            "Jackc\\Test\\": "src/"        }    },    "authors": [        {            "name": "chenchao",            "email": "1366294101@qq.com"        }    ],    "minimum-stability": "dev"}Do you confirm generation [yes]? Would you like to install dependencies now [yes]? Loading composer repositories with package informationInfo from https://repo.packagist.org: #StandWithUkraineUpdating dependenciesLock file operations: 22 installs, 0 updates, 0 removals  - Locking league/flysystem (1.x-dev 094defd)  - Locking league/flysystem-cached-adapter (1.1.0)  - Locking league/mime-type-detection (1.11.0)  - Locking nette/php-generator (v3.6.x-dev 9073c8a)  - Locking nette/utils (v3.2.x-dev 02a54c4)  - Locking open-smf/connection-pool (v1.0.16)  - Locking psr/cache (1.0.1)  - Locking psr/container (1.x-dev 513e066)  - Locking psr/http-message (dev-master efd67d1)  - Locking psr/log (1.1.4)  - Locking psr/simple-cache (1.0.1)  - Locking qeq66/jwt (3.3.x-dev bd2fa6c)  - Locking stechstudio/backoff (1.2)  - Locking swoole/ide-helper (4.8.x-dev afe3a09)  - Locking symfony/deprecation-contracts (2.5.x-dev e8b495e)  - Locking symfony/finder (5.4.x-dev 7872a66)  - Locking symfony/polyfill-php80 (dev-main cfa0ae9)  - Locking thans/tp-jwt-auth (v1.2.1)  - Locking topthink/framework (6.0.x-dev 4c328dc)  - Locking topthink/think-helper (v3.1.6)  - Locking topthink/think-orm (2.0.x-dev d86a204)  - Locking topthink/think-swoole (v4.0.7)Writing lock fileInstalling dependencies from lock file (including require-dev)Package operations: 22 installs, 0 updates, 0 removals  - Downloading psr/cache (1.0.1)  - Downloading league/mime-type-detection (1.11.0)  - Downloading league/flysystem (1.x-dev 094defd)  - Downloading league/flysystem-cached-adapter (1.1.0)  - Downloading nette/utils (v3.2.x-dev 02a54c4)  - Downloading psr/container (1.x-dev 513e066)  - Downloading psr/http-message (dev-master efd67d1)  - Downloading symfony/deprecation-contracts (2.5.x-dev e8b495e)  - Downloading symfony/polyfill-php80 (dev-main cfa0ae9)  - Downloading topthink/think-helper (v3.1.6)  - Downloading psr/simple-cache (1.0.1)  - Downloading topthink/think-orm (2.0.x-dev d86a204)  - Downloading topthink/framework (6.0.x-dev 4c328dc)  - Downloading qeq66/jwt (3.3.x-dev bd2fa6c)  - Downloading thans/tp-jwt-auth (v1.2.1)  - Downloading symfony/finder (5.4.x-dev 7872a66)  - Downloading swoole/ide-helper (4.8.x-dev afe3a09)  - Downloading stechstudio/backoff (1.2)  - Downloading open-smf/connection-pool (v1.0.16)  - Downloading nette/php-generator (v3.6.x-dev 9073c8a)  - Downloading topthink/think-swoole (v4.0.7)  - Installing psr/cache (1.0.1): Extracting archive  - Installing league/mime-type-detection (1.11.0): Extracting archive  - Installing league/flysystem (1.x-dev 094defd): Extracting archive  - Installing league/flysystem-cached-adapter (1.1.0): Extracting archive  - Installing nette/utils (v3.2.x-dev 02a54c4): Extracting archive  - Installing psr/container (1.x-dev 513e066): Extracting archive  - Installing psr/http-message (dev-master efd67d1): Extracting archive  - Installing symfony/deprecation-contracts (2.5.x-dev e8b495e): Extracting archive  - Installing symfony/polyfill-php80 (dev-main cfa0ae9): Extracting archive  - Installing topthink/think-helper (v3.1.6): Extracting archive  - Installing psr/simple-cache (1.0.1): Extracting archive  - Installing psr/log (1.1.4): Extracting archive  - Installing topthink/think-orm (2.0.x-dev d86a204): Extracting archive  - Installing topthink/framework (6.0.x-dev 4c328dc): Extracting archive  - Installing qeq66/jwt (3.3.x-dev bd2fa6c): Extracting archive  - Installing thans/tp-jwt-auth (v1.2.1): Extracting archive  - Installing symfony/finder (5.4.x-dev 7872a66): Extracting archive  - Installing swoole/ide-helper (4.8.x-dev afe3a09): Extracting archive  - Installing stechstudio/backoff (1.2): Extracting archive  - Installing open-smf/connection-pool (v1.0.16): Extracting archive  - Installing nette/php-generator (v3.6.x-dev 9073c8a): Extracting archive  - Installing topthink/think-swoole (v4.0.7): Extracting archive12 package suggestions were added by new dependencies, use `composer suggest` to see details.Generating autoload files6 packages you are using are looking for funding.Use the `composer fund` command to find out more!PSR-4 autoloading configured. Use "namespace Jackc\Test;" in src/Include the Composer autoloader with: require 'vendor/autoload.php';
require & require-dev

require中的依赖是开发环境和生产环境都会使用的;require-dev中的依赖只会在开发环境中使用。

composer require --dev 表示将所要安装的依赖名放在"require-dev"下。composer install no-dev 表示只安装"require"中的依赖。

自动加载方式

PSR-0

官网

已弃用- 自 2014 年 10 月 21 日起,PSR-0 已被标记为已弃用。现在推荐PSR-4作为替代方案。

[1] 命名空间必须与绝对路径一致
[2] 类名首字母必须大写
[3 ]除去入口文件外,其他“.php”必须只有一个类
[4] php类文件必须自动载入,不采用include等
[5] 单一入口

composer使用psr-0加载类

与psr-4不用的是,使用psr-0加载类的命名空间不用指定最外层目录的名字空间,见下例子

.├── composer.json├── composer.lock├── index.php├── sdk│   └── DB│       ├── MySQL.php│       ├── Redis.php│       └── test│           └── Test.php└── src
{    "name": "jackc/test",    "description": "测试项目",    "type": "project",    "require": {        "thans/tp-jwt-auth": "1.2.1"    },    "require-dev": {        "topthink/think-swoole": "4.0.7"    },    "license": "xxx-xxx-xxx",    "autoload": {        "psr-0": {            "DB\\": "sdk/"        }    },    "authors": [        {            "name": "chenchao",            "email": "1366294101@qq.com"        }    ],    "minimum-stability": "dev"}
namespace DB;class MySQL{    public function __construct()    {        echo __METHOD__ . PHP_EOL;    }}
namespace DB;class Redis{    public function __construct()    {        echo __METHOD__ . PHP_EOL;    }}
namespace DB\test;class Test{    public function __construct()    {        echo __METHOD__ . PHP_EOL;    }}
require_once "vendor/autoload.php";use DB\Redis;use DB\MySQL;use DB\test\Test;new Redis();new MySQL();new Test();
# 只修改了自动加载规则composer update# 其他依赖没安装(vendor目录不存在)composer install
// autoload_namespaces.php @generated by Composer$vendorDir = dirname(dirname(__FILE__));$baseDir = dirname($vendorDir);return array(    'DB\\' => array($baseDir . '/sdk'),);

请添加图片描述

问题:在sdk根目录下的类要怎么加载?

//

PSR-4

官网

PSR-4和PSR-0最大的区别是对下划线(underscore)的定义不同。PSR-4中,在类名中使用下划线没有任何特殊含义。而PSR-0则规定类名中的下划线_会被转化成目录分隔符。

区分

composer使用psr-4引入类

使用上面的项目,在src下面天机哎测试用例

src├── driver│   ├── Rar.php│   ├── SevenZ.php│   └── Zip.php└── Extractor.php
{    "name": "jackc/test",    "description": "测试项目",    "type": "project",    "require": {        "thans/tp-jwt-auth": "1.2.1"    },    "require-dev": {        "topthink/think-swoole": "4.0.7"    },    "license": "xxx-xxx-xxx",    "autoload": {        "psr-0": {            "DB\\": "sdk/"        },        "psr-4": {            "src\\": "src/"        }    },    "authors": [        {            "name": "chenchao",            "email": "1366294101@qq.com"        }    ],    "minimum-stability": "dev"}
namespace src\driver;class SevenZ{    public function __construct()    {        echo __METHOD__ . PHP_EOL;    }}
require_once "vendor/autoload.php";use src\Extractor;new Extractor();
composer update
// autoload_psr4.php @generated by Composer$vendorDir = dirname(dirname(__FILE__));$baseDir = dirname($vendorDir);return array(    'think\\swoole\\' => array($vendorDir . '/topthink/think-swoole/src'),    'think\\' => array($vendorDir . '/topthink/framework/src/think', $vendorDir . '/topthink/think-helper/src', $vendorDir . '/topthink/think-orm/src'),    'thans\\jwt\\' => array($vendorDir . '/thans/tp-jwt-auth/src'),    'src\\' => array($baseDir . '/src'),    'Symfony\\Polyfill\\Php80\\' => array($vendorDir . '/symfony/polyfill-php80'),    'Symfony\\Component\\Finder\\' => array($vendorDir . '/symfony/finder'),    'Smf\\ConnectionPool\\' => array($vendorDir . '/open-smf/connection-pool/src'),    'STS\\Backoff\\' => array($vendorDir . '/stechstudio/backoff/src'),    'Psr\\SimpleCache\\' => array($vendorDir . '/psr/simple-cache/src'),    'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'),    'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-message/src'),    'Psr\\Container\\' => array($vendorDir . '/psr/container/src'),    'Psr\\Cache\\' => array($vendorDir . '/psr/cache/src'),    'League\\MimeTypeDetection\\' => array($vendorDir . '/league/mime-type-detection/src'),    'League\\Flysystem\\Cached\\' => array($vendorDir . '/league/flysystem-cached-adapter/src'),    'League\\Flysystem\\' => array($vendorDir . '/league/flysystem/src'),    'Lcobucci\\JWT\\' => array($vendorDir . '/qeq66/jwt/src'),);

请添加图片描述

classmap

将指定目录下的类加载到顶级命名空间下

使用

还是复用上面的项目,添加了一个lib目录,目录下有一个车俩的类

ehigh@ubuntu:test$ tree liblib└── Car.php
{    "name": "jackc/test",    "description": "测试项目",    "type": "project",    "require": {        "thans/tp-jwt-auth": "1.2.1"    },    "require-dev": {        "topthink/think-swoole": "4.0.7"    },    "license": "xxx-xxx-xxx",    "autoload": {        "psr-0": {            "DB\\": "sdk/"        },        "psr-4": {            "src\\": "src/"        },        "classmap": ["lib"]    },    "authors": [        {            "name": "chenchao",            "email": "1366294101@qq.com"        }    ],    "minimum-stability": "dev"}
<?phpclass Car{    public function __construct()    {        echo __METHOD__ . PHP_EOL;    }}
require_once "vendor/autoload.php";new \Car();
composer update
// autoload_classmap.php @generated by Composer$vendorDir = dirname(dirname(__FILE__));$baseDir = dirname($vendorDir);return array(    'Attribute' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Attribute.php',    'Car' => $baseDir . '/lib/Car.php',    'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',    'Nette\\ArgumentOutOfRangeException' => $vendorDir . '/nette/utils/src/exceptions.php',    'Nette\\DeprecatedException' => $vendorDir . '/nette/utils/src/exceptions.php',    'Nette\\DirectoryNotFoundException' => $vendorDir . '/nette/utils/src/exceptions.php',    'Nette\\FileNotFoundException' => $vendorDir . '/nette/utils/src/exceptions.php',    'Nette\\HtmlStringable' => $vendorDir . '/nette/utils/src/HtmlStringable.php',    'Nette\\IOException' => $vendorDir . '/nette/utils/src/exceptions.php',    'Nette\\InvalidArgumentException' => $vendorDir . '/nette/utils/src/exceptions.php',    'Nette\\InvalidStateException' => $vendorDir . '/nette/utils/src/exceptions.php',    'Nette\\Iterators\\CachingIterator' => $vendorDir . '/nette/utils/src/Iterators/CachingIterator.php',    'Nette\\Iterators\\Mapper' => $vendorDir . '/nette/utils/src/Iterators/Mapper.php',    'Nette\\Localization\\ITranslator' => $vendorDir . '/nette/utils/src/compatibility.php',    'Nette\\Localization\\Translator' => $vendorDir . '/nette/utils/src/Translator.php',    'Nette\\MemberAccessException' => $vendorDir . '/nette/utils/src/exceptions.php',    'Nette\\NotImplementedException' => $vendorDir . '/nette/utils/src/exceptions.php',    'Nette\\NotSupportedException' => $vendorDir . '/nette/utils/src/exceptions.php',    'Nette\\OutOfRangeException' => $vendorDir . '/nette/utils/src/exceptions.php',    'Nette\\PhpGenerator\\Attribute' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Attribute.php',    'Nette\\PhpGenerator\\ClassType' => $vendorDir . '/nette/php-generator/src/PhpGenerator/ClassType.php',    'Nette\\PhpGenerator\\Closure' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Closure.php',    'Nette\\PhpGenerator\\Constant' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Constant.php',    'Nette\\PhpGenerator\\Dumper' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Dumper.php',    'Nette\\PhpGenerator\\EnumCase' => $vendorDir . '/nette/php-generator/src/PhpGenerator/EnumCase.php',    'Nette\\PhpGenerator\\Extractor' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Extractor.php',    'Nette\\PhpGenerator\\Factory' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Factory.php',    'Nette\\PhpGenerator\\GlobalFunction' => $vendorDir . '/nette/php-generator/src/PhpGenerator/GlobalFunction.php',    'Nette\\PhpGenerator\\Helpers' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Helpers.php',    'Nette\\PhpGenerator\\Literal' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Literal.php',    'Nette\\PhpGenerator\\Method' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Method.php',    'Nette\\PhpGenerator\\Parameter' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Parameter.php',    'Nette\\PhpGenerator\\PhpFile' => $vendorDir . '/nette/php-generator/src/PhpGenerator/PhpFile.php',    'Nette\\PhpGenerator\\PhpLiteral' => $vendorDir . '/nette/php-generator/src/PhpGenerator/PhpLiteral.php',    'Nette\\PhpGenerator\\PhpNamespace' => $vendorDir . '/nette/php-generator/src/PhpGenerator/PhpNamespace.php',    'Nette\\PhpGenerator\\Printer' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Printer.php',    'Nette\\PhpGenerator\\PromotedParameter' => $vendorDir . '/nette/php-generator/src/PhpGenerator/PromotedParameter.php',    'Nette\\PhpGenerator\\Property' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Property.php',    'Nette\\PhpGenerator\\PsrPrinter' => $vendorDir . '/nette/php-generator/src/PhpGenerator/PsrPrinter.php',    'Nette\\PhpGenerator\\TraitUse' => $vendorDir . '/nette/php-generator/src/PhpGenerator/TraitUse.php',    'Nette\\PhpGenerator\\Traits\\AttributeAware' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Traits/AttributeAware.php',    'Nette\\PhpGenerator\\Traits\\CommentAware' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Traits/CommentAware.php',    'Nette\\PhpGenerator\\Traits\\FunctionLike' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Traits/FunctionLike.php',    'Nette\\PhpGenerator\\Traits\\NameAware' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Traits/NameAware.php',    'Nette\\PhpGenerator\\Traits\\VisibilityAware' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Traits/VisibilityAware.php',    'Nette\\PhpGenerator\\Type' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Type.php',    'Nette\\SmartObject' => $vendorDir . '/nette/utils/src/SmartObject.php',    'Nette\\StaticClass' => $vendorDir . '/nette/utils/src/StaticClass.php',    'Nette\\UnexpectedValueException' => $vendorDir . '/nette/utils/src/exceptions.php',    'Nette\\Utils\\ArrayHash' => $vendorDir . '/nette/utils/src/Utils/ArrayHash.php',    'Nette\\Utils\\ArrayList' => $vendorDir . '/nette/utils/src/Utils/ArrayList.php',    'Nette\\Utils\\Arrays' => $vendorDir . '/nette/utils/src/Utils/Arrays.php',    'Nette\\Utils\\AssertionException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php',    'Nette\\Utils\\Callback' => $vendorDir . '/nette/utils/src/Utils/Callback.php',    'Nette\\Utils\\DateTime' => $vendorDir . '/nette/utils/src/Utils/DateTime.php',    'Nette\\Utils\\FileSystem' => $vendorDir . '/nette/utils/src/Utils/FileSystem.php',    'Nette\\Utils\\Floats' => $vendorDir . '/nette/utils/src/Utils/Floats.php',    'Nette\\Utils\\Helpers' => $vendorDir . '/nette/utils/src/Utils/Helpers.php',    'Nette\\Utils\\Html' => $vendorDir . '/nette/utils/src/Utils/Html.php',    'Nette\\Utils\\IHtmlString' => $vendorDir . '/nette/utils/src/compatibility.php',    'Nette\\Utils\\Image' => $vendorDir . '/nette/utils/src/Utils/Image.php',    'Nette\\Utils\\ImageException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php',    'Nette\\Utils\\Json' => $vendorDir . '/nette/utils/src/Utils/Json.php',    'Nette\\Utils\\JsonException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php',    'Nette\\Utils\\ObjectHelpers' => $vendorDir . '/nette/utils/src/Utils/ObjectHelpers.php',    'Nette\\Utils\\ObjectMixin' => $vendorDir . '/nette/utils/src/Utils/ObjectMixin.php',    'Nette\\Utils\\Paginator' => $vendorDir . '/nette/utils/src/Utils/Paginator.php',    'Nette\\Utils\\Random' => $vendorDir . '/nette/utils/src/Utils/Random.php',    'Nette\\Utils\\Reflection' => $vendorDir . '/nette/utils/src/Utils/Reflection.php',    'Nette\\Utils\\RegexpException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php',    'Nette\\Utils\\Strings' => $vendorDir . '/nette/utils/src/Utils/Strings.php',    'Nette\\Utils\\Type' => $vendorDir . '/nette/utils/src/Utils/Type.php',    'Nette\\Utils\\UnknownImageFileException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php',    'Nette\\Utils\\Validators' => $vendorDir . '/nette/utils/src/Utils/Validators.php',    'PhpToken' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/PhpToken.php',    'Stringable' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Stringable.php',    'UnhandledMatchError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php',    'ValueError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/ValueError.php',);

请添加图片描述

目录存在同名类,怎么处理?
  1. 不在同一个目录下
    请添加图片描述
  2. 同一个目录下存在同名类

请添加图片描述
3. 结论

存在多个同名类,只会导入一个类,加载规则是:  1. 不存在目录,加载第一个文件的类  2. 存在目录,加载第一个目录最深的级的类
files

指定文件导入

使用

复用上面的项目,添加了common目录,添加了person类

{    "name": "jackc/test",    "description": "测试项目",    "type": "project",    "require": {    },    "require-dev": {    },    "license": "xxx-xxx-xxx",    "autoload": {        "psr-0": {            "DB\\": "sdk/"        },        "psr-4": {            "src\\": "src/"        },        "classmap": ["lib"],        "files": ["common/Person.php"]    },    "authors": [        {            "name": "chenchao",            "email": "1366294101@qq.com"        }    ],    "minimum-stability": "dev"}
class Person{    public function __construct()    {        echo __FILE__ . ' --- ' . __METHOD__ . PHP_EOL;    }}
require_once "vendor/autoload.php";new Person();
composer update
// autoload_files.php @generated by Composer$vendorDir = dirname(dirname(__FILE__));$baseDir = dirname($vendorDir);return array(    '34e6717e4080f708d812ed7cb7d8586c' => $baseDir . '/common/Person.php',);

请添加图片描述

引入的文件存在同名类怎么处理?
// autoload_files.php @generated by Composer$vendorDir = dirname(dirname(__FILE__));$baseDir = dirname($vendorDir);return array(    '34e6717e4080f708d812ed7cb7d8586c' => $baseDir . '/common/Person.php',    '7677e46b6e54f2c15468e2eafd3c16ac' => $baseDir . '/common/test/Person.php',);

请添加图片描述

composer会引入,但运行会报错

测试项目

composer文件说明

  1. autoload_classmap.php

classmap映射加载的类

  1. autoload_files.php

files定义的文件

  1. autoload_namespaces.php

psr-0定义的命名空间

  1. autoload_psr4.php

psr-4定义的名字空间

  1. autoload_real.php

框架加载类的入口文件

// autoload_real.php @generated by Composerclass ComposerAutoloaderInitaffaa1fd2638648a4ae4ee9274a5741d{    private static $loader;    public static function loadClassLoader($class)    {        if ('Composer\Autoload\ClassLoader' === $class) {            require __DIR__ . '/ClassLoader.php';        }    }        public static function getLoader()    {        if (null !== self::$loader) {            return self::$loader;        }        spl_autoload_register(array('ComposerAutoloaderInitaffaa1fd2638648a4ae4ee9274a5741d', 'loadClassLoader'), true, true);        self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__)));        spl_autoload_unregister(array('ComposerAutoloaderInitaffaa1fd2638648a4ae4ee9274a5741d', 'loadClassLoader'));        $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());        if ($useStaticLoader) {            require __DIR__ . '/autoload_static.php';            call_user_func(\Composer\Autoload\ComposerStaticInitaffaa1fd2638648a4ae4ee9274a5741d::getInitializer($loader));        } else {            $map = require __DIR__ . '/autoload_namespaces.php';            foreach ($map as $namespace => $path) {                $loader->set($namespace, $path);            }            $map = require __DIR__ . '/autoload_psr4.php';            foreach ($map as $namespace => $path) {                $loader->setPsr4($namespace, $path);            }            $classMap = require __DIR__ . '/autoload_classmap.php';            if ($classMap) {                $loader->addClassMap($classMap);            }        }        $loader->register(true);        if ($useStaticLoader) {            $includeFiles = Composer\Autoload\ComposerStaticInitaffaa1fd2638648a4ae4ee9274a5741d::$files;        } else {            $includeFiles = require __DIR__ . '/autoload_files.php';        }        foreach ($includeFiles as $fileIdentifier => $file) {            composerRequireaffaa1fd2638648a4ae4ee9274a5741d($fileIdentifier, $file);        }        return $loader;    }}function composerRequireaffaa1fd2638648a4ae4ee9274a5741d($fileIdentifier, $file){    if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {        $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;        require $file;    }}
// autoload.php @generated by Composerrequire_once __DIR__ . '/composer/autoload_real.php';return ComposerAutoloaderInitaffaa1fd2638648a4ae4ee9274a5741d::getLoader();
  1. autoload_static.php

autoload_classmap.php、autoload_namespace.php、autoload_psr4.php、autoload_file.php的总和

// autoload_static.php @generated by Composernamespace Composer\Autoload;class ComposerStaticInitaffaa1fd2638648a4ae4ee9274a5741d{    public static $files = array (        '34e6717e4080f708d812ed7cb7d8586c' => __DIR__ . '/../..' . '/common/Person.php',        '7677e46b6e54f2c15468e2eafd3c16ac' => __DIR__ . '/../..' . '/common/test/Person.php',    );    public static $prefixLengthsPsr4 = array (        's' =>         array (            'src\\' => 4,        ),    );    public static $prefixDirsPsr4 = array (        'src\\' =>         array (            0 => __DIR__ . '/../..' . '/src',        ),    );    public static $prefixesPsr0 = array (        'D' =>         array (            'DB\\' =>             array (                0 => __DIR__ . '/../..' . '/sdk',            ),        ),    );    public static $classMap = array (        'Car' => __DIR__ . '/../..' . '/lib/test/test1/Apple.php',        'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',    );    public static function getInitializer(ClassLoader $loader)    {        return \Closure::bind(function () use ($loader) {            $loader->prefixLengthsPsr4 = ComposerStaticInitaffaa1fd2638648a4ae4ee9274a5741d::$prefixLengthsPsr4;            $loader->prefixDirsPsr4 = ComposerStaticInitaffaa1fd2638648a4ae4ee9274a5741d::$prefixDirsPsr4;            $loader->prefixesPsr0 = ComposerStaticInitaffaa1fd2638648a4ae4ee9274a5741d::$prefixesPsr0;            $loader->classMap = ComposerStaticInitaffaa1fd2638648a4ae4ee9274a5741d::$classMap;        }, null, ClassLoader::class);    }}

建议

  1. PHP工程项目使用composer进行管理
  2. 不要去修改依赖库的代码
  3. 类的引入方式采用PSR-4规范

来源地址:https://blog.csdn.net/qq_41105107/article/details/127065985

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯