返回顶部
首页 > 资讯 > 后端开发 > PHP编程 >PHP类的引入方式
  • 951
分享到

PHP类的引入方式

php 2023-09-22 15:09:29 951人浏览 安东尼
摘要

名词解释 语言结构&函数 语言结构:就是PHP语言的关键词,语言语法的一部分;它不可以被用户定义或者添加到语言扩展或者库中;它可以有也可以没有变量和返回值。函数:由代码块组成的,可以复用。从源码的角度

名词解释

  1. 语言结构&函数
  • 语言结构:就是PHP语言的关键词,语言语法的一部分;它不可以被用户定义或者添加到语言扩展或者库中;它可以有也可以没有变量和返回值。
  • 函数:由代码块组成的,可以复用。从源码的角度来说,也就是基于Zend引擎的基础来实现的,ext拓展库中的函数都是这样实现的
  • 区别
    • 语言结构比对应功能的函数快
    • 语言结构在错误处理上比较鲁棒,由于是语言关键词,所以不具备再处理的环节
    • 语言结构不能在配置项(php.ini)中禁用,函数则可以。
    • 语言结构不能被用做回调函数
  • 语言结构为什么比函数快?

原因是在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中禁用函数?

在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;

请添加图片描述

例子

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

手动引入

require

引入一个外部文件

引入顺序
  • 按照include_path指定的目录寻找
  • 寻找当前文件所在目录和当前工作目录
  • 示例1——引入顺序测试
  • 示例2——引入优先级测试
  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();

请添加图片描述

  • 要怎么才能够实现重复引入呢?
    • 修改1.php就行了
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
  • 1.php
include_once "2.php";include_once "3.php";include_once "4.php";test();
  • 2,3,4.php
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
  • redis.php
namespace redis\redis;class RedisConn{    public function __construct()    {        echo __METHOD__ . PHP_EOL;    }}
  • entry.php
namespace handle\entry;use redis\redis\RedisConn;class Entry{    public function __construct()    {        echo __METHOD__ . PHP_EOL;        new RedisConn();    }}
  • index.php
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
  • composer.json
{    "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;    }}
  • Redis.php
namespace DB;class Redis{    public function __construct()    {        echo __METHOD__ . PHP_EOL;    }}
  • Test.php
namespace DB\test;class Test{    public function __construct()    {        echo __METHOD__ . PHP_EOL;    }}
  • index.php
require_once "vendor/autoload.php";use DB\Redis;use DB\MySQL;use DB\test\Test;new Redis();new MySQL();new Test();
  • composer
# 只修改了自动加载规则composer update# 其他依赖没安装(vendor目录不存在)composer install
  • vendor/composer/autoload_namespaces.php
// 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
  • composer.json
{    "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"}
  • Rar.php,SevenZ.php,Zip.php
namespace src\driver;class SevenZ{    public function __construct()    {        echo __METHOD__ . PHP_EOL;    }}
  • index.php
require_once "vendor/autoload.php";use src\Extractor;new Extractor();
  • composer
composer update
  • vendor/composer/autoload_psr4.php
// 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
  • composer.json
{    "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"}
  • Car.php
<?phpclass Car{    public function __construct()    {        echo __METHOD__ . PHP_EOL;    }}
  • index.php
require_once "vendor/autoload.php";new \Car();
  • composer
composer update
  • vendot/composer/autoload_classmap.php
// 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类

  • composer.json
{    "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"}
  • Person.php
class Person{    public function __construct()    {        echo __FILE__ . ' --- ' . __METHOD__ . PHP_EOL;    }}
  • index.php
require_once "vendor/autoload.php";new Person();
  • composer
composer update
  • vendor/composer/autoload_files.php
// autoload_files.php @generated by Composer$vendorDir = dirname(dirname(__FILE__));$baseDir = dirname($vendorDir);return array(    '34e6717e4080f708d812ed7cb7d8586c' => $baseDir . '/common/Person.php',);

请添加图片描述

引入的文件存在同名类怎么处理?
  • vendor/composer/autoload_files.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;    }}
  • vendor/autoload.php
// 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

--结束END--

本文标题: PHP类的引入方式

本文链接: https://lsjlt.com/news/415474.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • PHP类的引入方式
    名词解释 语言结构&函数 语言结构:就是php语言的关键词,语言语法的一部分;它不可以被用户定义或者添加到语言扩展或者库中;它可以有也可以没有变量和返回值。函数:由代码块组成的,可以复用。从源码的角度...
    99+
    2023-09-22
    php
  • C++类型转换引入了那几种方式
    这期内容当中小编将会给大家带来有关C++类型转换引入了那几种方式,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。众所周知C++关于类型转换引入了四种方式:static_castconst_castdynam...
    99+
    2023-06-15
  • 如何引入CSS的方式
    小编给大家分享一下如何引入CSS的方式,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!(1)内嵌式通过<style>&...
    99+
    2024-04-02
  • JavaScript引入方式深入解读
    目录一、JS介绍二、JS特点三、JS和Java的区别四、HTML和CSS和JS这之间的关系五、JS的引入方式1.内嵌式2.链接式一、JS介绍   Javascri...
    99+
    2024-04-02
  • JavaScript的引入方式有哪些
    本篇内容主要讲解“JavaScript的引入方式有哪些”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“JavaScript的引入方式有哪些”吧! ...
    99+
    2024-04-02
  • css的引入方式有哪些
    这篇文章将为大家详细讲解有关css的引入方式有哪些,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。css的三种引入方式1.行内样式,最直接最简单的一种,直接对HTML标签使用style="&quo...
    99+
    2023-06-14
  • 有哪些引入CSS的方式
    本篇文章给大家分享的是有关有哪些引入CSS的方式,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。css的全称是什么css的全称是Cascading Style Sheets(层叠...
    99+
    2023-06-08
  • 引入CSS的方式有哪些
    这篇文章主要讲解了“引入CSS的方式有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“引入CSS的方式有哪些”吧!看到淘宝网页中这样写使用的是import,而很多网站都是使用link,当然...
    99+
    2023-06-08
  • vue 按需引入vant跟全局引入方式
    目录一、按需引入1.下载插件2.自动按需引入组件 (推荐)3.创建src文件跟js4.全局main.js导入5.使用二、全局导入一、按需引入 1.下载插件 第一步我们可以先打开van...
    99+
    2022-11-13
    vue按需引入 vue全局引入 vant全局引入 vant按需引入
  • php引用类名的方法介绍
    这篇文章主要讲解了“php引用类名的方法介绍”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“php引用类名的方法介绍”吧!PHP 命名空间中的类名可以通过三种方式引用:1、非限定名称,或不包含...
    99+
    2023-06-20
  • css的引入方式实例分析
    本篇内容主要讲解“css的引入方式实例分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“css的引入方式实例分析”吧! css的三种...
    99+
    2024-04-02
  • css的引入方式有哪4种
    这篇文章主要介绍css的引入方式有哪4种,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!四种引入方式:1、直接在html标签使用style属性引入;2、将css样式规则写在style标签中;3、使用link标签引入外部...
    99+
    2023-06-15
  • JSP引入jQuery的方式有哪些
    本篇内容主要讲解“JSP引入jQuery的方式有哪些”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“JSP引入jQuery的方式有哪些”吧!在jsp页面引入JQuery插件,主要的是引入的路径问题...
    99+
    2023-06-29
  • vue-cli2.0 与 3 引入方式
    vue-cli 现在出到3 了 不同的版本使用方式还是稍有不同的,根据引入方式可以选择不同版本 2的引入方式 vue install -g vue-cli 3 引入方式 vue install -g @vue/cli 这样会引入2 的...
    99+
    2023-01-31
    方式 vue
  • vue3+ts+echarts实现按需引入和类型界定方式
    目录vue3+ts+echarts实现按需引入和类型界定vue3按需引入echarts问题及使用vue3+ts+echarts实现按需引入和类型界定 一直想系统学习一下echarts...
    99+
    2022-11-13
    vue3 ts echarts vue3按需引入 vue3类型界定
  • css样式引入方式的优缺有哪些
    这篇文章将为大家详细讲解有关css样式引入方式的优缺有哪些,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。三种css的引入方式1.行内样式优点:书写方便,权重高缺点:没有做到结构样式相分离<div s...
    99+
    2023-06-08
  • css引入的3种方式是什么
    小编给大家分享一下css引入的3种方式是什么,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧! 1、内部引用,在html文档中在&...
    99+
    2024-04-02
  • HTML中引入CSS的方式有哪些
    这篇文章给大家分享的是有关HTML中引入CSS的方式有哪些的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。   一、认识CSS   CSS:层叠样式表(Cascading St...
    99+
    2024-04-02
  • css的三种引入方式是什么
    这篇文章主要介绍“css的三种引入方式是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“css的三种引入方式是什么”文章能帮助大家解决问题。css的引入方式有三种...
    99+
    2024-04-02
  • CSS引入样式的方法有哪些
    本文小编为大家详细介绍“CSS引入样式的方法有哪些”,内容详细,步骤清晰,细节处理妥当,希望这篇“CSS引入样式的方法有哪些”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。   ...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作