Yii 2 与第三方代码集成:在 Yii 中使用外部库、把 Yii 嵌入第三方系统及 Yii 1/2 共存实战指南
2026/9/24 9:54:25 网站建设 项目流程
  • 后端
  • Web框架

【免费下载链接】yii2

Yii 2: The Fast, Secure and Professional PHP Framework

项目地址:https://gitcode.com/gh_mirrors/yi/yii2
点击查看免费下载

本篇技术指南基于 Yii 2 官方指南的《Working with Third-Party Code》(乌克兰语译本位于 docs/guide-uk/tutorial-yii-integration.md,英文原文见 docs/guide/tutorial-yii-integration.md),系统讲解三个实战场景:在 Yii 应用中引入第三方库、把 Yii 作为库嵌入 WordPress / Joomla 等第三方系统,以及在存量 Yii 1 应用中渐进式引入 Yii 2。读完本文,你将掌握 Composer 包接入、PSR-4 别名自动加载、Yii::$classMap按需加载、new yii\web\Application($config)run()引导模式,以及通过自定义Yii类实现 Yii 1/2 双应用共存的完整方案,并结合本仓库源码理解其底层自动加载与请求处理机制。

为什么需要与第三方代码集成

无论是哪种 PHP 项目,最终几乎都会面临两类集成需求:

  • 在 Yii 应用里使用第三方代码:例如引入某个只提供 Composer 包或压缩包下载的 SDK、工具库;
  • 在第三方系统中使用 Yii 的能力:例如在 WordPress、Joomla 或其他框架开发的系统中,借用 Yii 的 ArrayHelper 之类的辅助类,或直接使用 Active Record 的数据层能力。

前者要解决"如何让 Yii 正确加载外部类",后者要解决"如何把 Yii 当作一个库安装并引导起来,且不干扰宿主系统的请求流程"。本指南对这两类问题给出了完整的官方解法,第三部分还会介绍新旧框架共存的升级路径。

在 Yii 应用中使用第三方库

在 Yii 应用中使用第三方库,核心工作只有一件事:确保库中的类被正确包含或能够被自动加载。根据库的交付形态不同,有四种由易到难的接入方式。

使用 Composer 包(推荐方式)

大量第三方库以 Composer 包的形式发布。接入只需两个步骤:

  1. 修改应用的composer.json,声明需要安装的包;
  2. 执行composer install安装这些包。

安装完成后,包内类的自动加载由 Composer 的自动加载器负责。因此请确认应用的入口脚本中包含下面两行:

// 注册 Composer 自动加载器 require __DIR__ . '/../vendor/autoload.php'; // 引入 Yii 类文件 require __DIR__ . '/../vendor/yiisoft/yii2/Yii.php';

两行的顺序是有讲究的:先注册 Composer 自动加载器,再引入Yii.php。因为 framework/Yii.php 在文件末尾通过spl_autoload_register(['Yii', 'autoload'], true, true)注册 Yii 自己的自动加载器,最后一个注册的自动加载器会最先被 PHP 调用,这样 Yii 自动加载器在类加载优先级上拥有最高优先权,从而保证Yii::$classMap等机制能先于 Composer 命中。

关于这一顺序的更多说明,可参考自动加载章节中"使用其他自动加载器"一节——多个自动加载器并存时,Yii.php必须放在最后引入。

使用手动下载的库

如果某个库没有发布为 Composer 包,则需要遵循其自带的安装说明。大多数情况下你需要:

  • 手动下载发布文件;
  • 解压到BasePath/vendor目录,其中BasePath是应用的基本路径(即basePath属性,源码定义于 framework/base/Application.php)。

解压完成之后,根据库的自动加载能力,按以下优先级选择接入方式:

方式一:库自带类自动加载器。在入口脚本中注册该自动加载器。官方建议在引入Yii.php之前完成注册,理由同上——Yii 自动加载器后注册即可获得优先权,避免类被其他加载器抢先加载。

方式二:库符合 PSR-4 命名规范但没有自动加载器。可以直接使用 Yii 自动加载器来加载这些类。你需要做的只是为库用到的每个根命名空间声明一个根别名。例如,假设库被安装在vendor/foo/bar目录,且其类位于xyz根命名空间下,在应用配置中加入:

[ 'aliases' => [ '@xyz' => '@vendor/foo/bar', ], ]

这里的原理是:Yii 自动加载器(framework/BaseYii.php 中的BaseYii::autoload())会把类名xyz\SomeClass翻译成别名@xyz/SomeClass.php,再通过getAlias()解析为真实文件路径后include。而@vendor是 Yii 预定义别名(默认指向@app/vendor),@xyz => '@vendor/foo/bar'这种"别名指向别名"的写法在setAlias()中会自动先解析@vendor/foo/bar得到真实路径(参见 framework/BaseYii.php 的setAlias()实现:当$path@开头时调用getAlias()转换)。

方式三:库依赖 PHPinclude_path如果以上两种都不适用,很可能该库依靠 PHP 的include_path配置来定位类文件,按库的说明配置include_path指令即可。

方式四(最坏情况):库要求显式引入每个类文件。此时可以在入口脚本中通过Yii::$classMap实现按需加载:

Yii::$classMap['Class1'] = 'path/to/Class1.php'; Yii::$classMap['Class2'] = 'path/to/Class2.php';

底层机制:Yii 自动加载器如何工作

为了用好上述方式,有必要理解 Yii 自动加载器的实现。在 framework/BaseYii.php 中,BaseYii::autoload($className)的加载流程分两步:

  1. 先查类映射表:如果static::$classMap[$className]存在,直接include对应文件(支持@开头的路径别名,会先经getAlias()解析)。框架自身全部类都通过此方式加载——framework/Yii.php 中Yii::$classMap = require __DIR__ . '/classes.php';加载的就是 framework/classes.php 这份由构建工具自动生成的 430 行类映射表,例如'yii\base\Application' => YII2_PATH . '/base/Application.php'
  2. 否则按 PSR-4 推导:将命名空间分隔符\替换为/,拼接出别名'@' . str_replace('\\', '/', $className) . '.php',交给getAlias()解析,命中已注册的根别名即加载,未命中则直接返回(把机会留给其他自动加载器)。

也就是说,前文"方式二"的别名配置,正是让 Yii 自动加载器用最少的配置、以接近 PSR-4 标准的成本替你完成类加载。而Yii::$classMap这种"类名 => 文件路径"的映射则是最快的路径——不经过任何推导,直接 include。自动加载的完整规则详见自动加载与别名两个章节。

把 Yii 作为库嵌入第三方系统

Yii 提供了大量开箱即用的优秀特性(如 ArrayHelper、Active Record、日志、缓存等),因此在开发或增强第三方系统(WordPress、Joomla,或其他 PHP 框架开发的应用)时,你可能只想借用其中一部分能力。官方给出的方案分两步:安装 Yii引导(bootstrap)Yii

安装 Yii

方案 A:宿主系统使用 Composer 管理依赖。按乌克兰语译本中的经典流程,执行以下命令把 Yii 加入项目依赖:

composer global require "fxp/composer-asset-plugin:^1.4.1" composer require yiisoft/yii2 composer install

第一条命令安装 composer asset plugin,它允许通过 Composer 统一管理 Bower 和 NPM 包依赖。注意:即使你只想使用数据库抽象层或其他与资源无关的特性,也必须安装该插件。原因可以从本仓库 framework/composer.json 的require段看到——yiisoft/yii2本身声明了bower-asset/jquerybower-asset/inputmaskbower-asset/punycodebower-asset/yii2-pjax等 Bower 资产依赖,安装过程需要插件来转换这些依赖。

如果你确实只想用数据层等非资源特性、不想引入 Bower/NPM 包,英文原版指南还提到一个替代做法:声明一个特殊的 composer 包(cebe/assetfree-yii2)来阻止 Bower 与 NPM 包的安装,详见 docs/guide/tutorial-yii-integration.md 对应小节。

若还需要使用 Yii 的资源发布能力,应在composer.jsonextra段补充以下配置,指定 Bower/NPM 资产的安装目录:

{ ... "extra": { "asset-installer-paths": { "npm-asset-library": "vendor/npm", "bower-asset-library": "vendor/bower" } } }

更多关于 Composer 及安装过程中可能遇到的问题,参见通过 Composer 安装 Yii。

方案 B:宿主系统不使用 Composer。直接从官方下载页获取 Yii 发行文件,解压到BasePath/vendor目录(BasePath即宿主系统的应用根目录)。

引导 Yii:创建应用实例但不调用 run()

接下来修改第三方系统的入口脚本,在其开头加入如下代码:

require __DIR__ . '/../vendor/yiisoft/yii2/Yii.php'; $yiiConfig = require __DIR__ . '/../config/yii/web.php'; new yii\web\Application($yiiConfig); // 此处不要调用 run()

这段代码与典型 Yii 应用的入口脚本非常相似,唯一区别是:创建应用实例后不调用run()方法。原因在于:一旦调用run(),Yii 就会接管整个请求处理流程(run()内部会依次执行处理请求、分发路由、渲染响应、发送输出并结束请求的完整生命周期,见 framework/base/Application.php 中Application::run()的实现,它负责调用handleRequest()并处理退出流程),而这套流程宿主系统本身已经完成,Yii 不应越俎代庖。这里 Yii 应用实例仅作为**服务定位器(service locator)**和功能提供者存在。

与正规 Yii 应用一样,你应当基于宿主系统的运行环境来配置这个应用实例。例如要使用 Active Record 特性,就需要配置db应用组件,指向宿主系统正在使用的数据库连接:

// config/yii/web.php return [ 'id' => 'third-party-bridge', 'basePath' => __DIR__ . '/..', 'components' => [ 'db' => [ 'class' => 'yii\db\Connection', 'dsn' => 'mysql:host=localhost;dbname=host_system_db', 'username' => 'host_user', 'password' => 'host_password', 'charset' => 'utf8', ], ], ];

完成以上两步后,你就可以在第三方系统中使用 Yii 的大部分功能了——例如创建 Active Record 类并借助它操作数据库(详见 Active Record 章节)。在任意代码位置,通过\Yii::$app即可访问到这个被引导起来的应用实例及其全部组件。

同时使用 Yii 2 与 Yii 1

如果你此前使用 Yii 1 并已有线上应用,官方并不建议一次性重写整个应用,而是推荐渐进式增强:保留 Yii 1 应用,同时引入 Yii 2 独有的一些特性。

前提条件(版本说明):原指南要求 Yii 2 需要 PHP 5.4 或更高版本,需确认服务器与现有应用均满足。需要特别指出的是,本仓库当前 framework/composer.json 中的要求已是"php": ">=7.4.0",即现代 Yii 2 版本实际要求 PHP 7.4 以上,集成前请以你所安装的 Yii 2 发行版实际约束为准。

具体操作分两步。

第一步:按上一节"把 Yii 作为库嵌入第三方系统"的说明,在你的现有应用中安装 Yii 2。

第二步:将应用入口脚本改为如下形态:

// 引入下面将要描述的自定义 Yii 类 require __DIR__ . '/../components/Yii.php'; // Yii 2 应用配置(仅作为服务定位器使用,不调用 run()) $yii2Config = require __DIR__ . '/../config/yii2/web.php'; new yii\web\Application($yii2Config); // 不要调用 run() // Yii 1 应用配置,正常运行 $yii1Config = require __DIR__ . '/../config/yii1/main.php'; Yii::createWebApplication($yii1Config)->run();

由于 Yii 1 和 Yii 2 都定义了一个名为Yii的类,直接同时引入两个框架会发生致命冲突,因此必须创建一个合并两者的自定义版本。把下面的内容保存为components/Yii.php

$yii2path = '/path/to/yii2'; require $yii2path . '/BaseYii.php'; // Yii 2.x $yii1path = '/path/to/yii1'; require $yii1path . '/YiiBase.php'; // Yii 1.x class Yii extends \yii\BaseYii { // 将从 YiiBase (1.x) 中的代码复制粘贴到这里 } Yii::$classMap = include($yii2path . '/classes.php'); // 通过 Yii 1 注册 Yii 2 的自动加载器 Yii::registerAutoloader(['Yii', 'autoload']); // 创建依赖注入容器 Yii::$container = new yii\di\Container;

这段代码做了四件关键的事:

  1. 分别引入两代框架的基类BaseYii.php(Yii 2.x 的核心类,本仓库对应 framework/BaseYii.php)与YiiBase.php(Yii 1.x)。随后定义的自定义Yii类继承自\yii\BaseYii,并将 Yii 1 的YiiBase中那些 Yii 2 没有的方法(如app()createWebApplication())复制进来,从而"合二为一";
  2. 装载 Yii 2 的类映射表Yii::$classMap = include($yii2path . '/classes.php'),对应本仓库 framework/classes.php 这份自动生成的框架类映射;
  3. 合并自动加载:通过Yii::registerAutoloader(['Yii', 'autoload'])把 Yii 2 的autoload方法注册进自动加载链(registerAutoloader是 Yii 1 的YiiBase提供的封装方法,本质是对 PHPspl_autoload_register的包装;在纯 Yii 2 环境中,本仓库的 framework/Yii.php 则是直接调用spl_autoload_register(['Yii', 'autoload'], true, true)完成注册);
  4. 初始化依赖注入容器Yii::$container = new yii\di\Container;,与 framework/Yii.php 末尾的Yii::$container = new yii\di\Container();一致,为后续Yii::createObject()的依赖解析(见 framework/BaseYii.php 的createObject()实现)提供容器。

完成后,代码中任何位置都可以通过Yii::$app访问 Yii 2 的应用实例,通过Yii::app()访问 Yii 1 的应用实例,二者互不干扰:

echo get_class(Yii::app()); // 输出 'CWebApplication'(Yii 1 应用) echo get_class(Yii::$app); // 输出 'yii\web\Application'(Yii 2 应用)

这种"双应用共存"模式让存量 Yii 1 项目可以逐模块、渐进式地迁移或调用 Yii 2 能力,而不必承担一次性重写的风险。

小结与延伸阅读

本文覆盖了 Yii 2 与第三方代码集成的完整方案:在 Yii 应用内,按 Composer 包、PSR-4 别名、include_pathYii::$classMap的优先级由易到难接入外部类,并理解了 framework/BaseYii.php 中自动加载器的两步查找机制;在第三方系统内,通过"安装 + 引导"两步把 Yii 变成能力库,关键约束是创建应用实例但不调用run();在 Yii 1 存量项目中,通过自定义Yii类合并两代框架的基类、类映射与自动加载链,实现Yii::$appYii::app()并存。

继续深入可参考本仓库的以下资料:

  • 入口脚本:应用启动的第一环,理解常量定义与引导顺序;
  • 自动加载:Yii 自动加载器的完整规则与类映射机制;
  • 别名:根别名、派生别名与预定义别名的解析规则;
  • 应用:应用实例的属性、配置与basePath
  • 应用组件:db等组件如何配置与访问;
  • Active Record:嵌入场景下最常用的数据层能力;
  • 资源管理:Bower/NPM 资产发布与目录配置;
  • 核心实现:framework/Yii.php、framework/BaseYii.php、framework/classes.php、framework/base/Application.php。
  • 后端
  • Web框架

【免费下载链接】yii2

Yii 2: The Fast, Secure and Professional PHP Framework

项目地址:https://gitcode.com/gh_mirrors/yi/yii2
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询