ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Yii 2 与第三方代码集成实战:在 Yii 中使用外部类库,以及将 Yii 嵌入其他系统

Yii 2 与第三方代码集成实战:在 Yii 中使用外部类库,以及将 Yii 嵌入其他系统 后端Web框架【免费下载链接】yii2Yii 2: The Fast, Secure and Professional PHP Framework项目地址https://gitcode.com/gh_mirrors/yi/yii2点击查看免费下载本篇技术指南围绕 Yii 2 框架的「第三方代码集成」主题展开覆盖两大场景在 Yii 应用中引入并使用第三方类库Composer 包、手动下载的库、PSR-4 命名空间类、include_path依赖库与显式classMap映射以及在第三方系统WordPress、Joomla 或其他 PHP 框架中把 Yii 当作类库来使用甚至实现 Yii 1 与 Yii 2 的同进程共存。读完本文你将掌握类自动加载的底层原理Yii::autoload()与$classMap并能独立完成双向集成的配置与入口脚本改造。在 Yii 应用中使用第三方类库在 Yii 应用里使用第三方类库核心只有一件事确保这些库的类文件可以被正常导入或自动加载。Yii 的自动加载机制建立在 PSR-4 标准之上同时通过路径别名path alias与类映射class map提供了更灵活的加载途径。下面按类库的发布形式分四种情况说明。使用 Composer 包目前绝大多数第三方类库都以 Composer 包的形式发布。安装只需两个步骤修改应用的composer.json文件在require段注明需要安装哪些 Composer 包运行php composer.phar install安装这些包。安装完成后这些包内的类库就可以通过 Composer 的自动加载器实现自动加载。但前提是应用的入口脚本包含以下两行代码// 安装 Composer 自动加载器 require __DIR__ . /../vendor/autoload.php; // 加载 Yii 的类文件 require __DIR__ . /../vendor/yiisoft/yii2/Yii.php;从入口脚本文档可以看到一个标准的 Yii Web 入口脚本正是这样组织的先注册 Composer 自动加载器再引入 Yii 类文件然后加载应用配置并创建、运行应用实例?php defined(YII_DEBUG) or define(YII_DEBUG, true); defined(YII_ENV) or define(YII_ENV, dev); // 注册 Composer 自动加载器 require __DIR__ . /../vendor/autoload.php; // 包含 Yii 类文件 require __DIR__ . /../vendor/yiisoft/yii2/Yii.php; // 加载应用配置 $config require __DIR__ . /../config/web.php; // 创建、配置、运行一个应用 (new yii\web\Application($config))-run();为什么顺序如此重要从源码看Yii.php 在引入BaseYii.php之后会执行spl_autoload_register([Yii, autoload], true, true)其中第三个参数prepend true表示将 Yii 的自动加载器注册到 PHP 自动加载栈的最前面。因此在 Composer 自动加载器已经注册的情况下Yii 的自动加载器拥有更高的优先级遇到yii\*命名空间的类时会由 Yii 自己负责加载借助Yii::$classMap与yii别名而其他第三方命名空间的类则交给 Composer 的 PSR-4 自动加载器处理两者互不干扰。使用下载的类库非 Composer 包如果类库没有发布为 Composer 包可以手动安装下载发布文件解压到BasePath/vendor目录BasePath指应用自身的 base path主目录若类库自带类自动加载器把它安装到应用的入口脚本中推荐放在Yii.php导入之前这样 Yii 官方自动加载器可以获得更高的优先级原因同上与spl_autoload_register的prepend参数行为一致若类库没有自动加载器但命名符合 PSR-4 标准可以直接利用 Yii 官方自动加载器只需为每个根命名空间声明根路径别名。例如假设你把一个根命名空间为xyz的类库安装在vendor/foo/bar目录可以在应用配置文件中这样配置[ aliases [ xyz vendor/foo/bar, ], ]这一机制背后的原理在 BaseYii.php 的autoload()方法中体现得淋漓尽致public static function autoload($className) { if (isset(static::$classMap[$className])) { $classFile static::$classMap[$className]; if (strncmp($classFile, , 1) 0) { $classFile static::getAlias($classFile); } } elseif (strpos($className, \\) ! false) { $classFile static::getAlias( . str_replace(\\, /, $className) . .php, false); if ($classFile false || !is_file($classFile)) { return; } } else { return; } include $classFile; // 调试模式下校验类是否真的被加载否则抛出 UnknownClassException }也就是说对于带命名空间的类如xyz\Foo\BarYii 会先解析xyz/Foo/Bar.php这样的衍生别名——把xyz替换成vendor/foo/bar的真实路径再检查文件是否存在并include。这就是 PSR-4 类库只需声明根别名即可被 Yii 自动加载的原因。别名解析的具体规则最长匹配、/边界字符、getAlias()不检查路径是否真实存在等可参阅别名文档。依赖 include_path 的类库如果以上情形都不符合最可能是该类库需要依赖 PHP 的include_path配置来定位类文件。此时只需参考该库的安装说明在 PHP 配置如php.ini或运行时set_include_path()中把对应目录加入导入路径即可。最坏情形使用 Yii::$classMap 显式映射最悲催的情形是类库需要显式导入每个类文件。此时可以使用 Yii 的类映射机制按需导入找出该库中包含哪些类在应用的入口脚本中把这些类及各自对应的文件路径列进Yii::$classMap数组。举例来说Yii::$classMap[Class1] path/to/Class1.php; Yii::$classMap[Class2] path/to/Class2.php;Yii::$classMap在 BaseYii.php 中被定义为公开静态属性其数组键为不带前导反斜杠的完整类名数组值是对应的类文件路径也支持路径别名。autoload()方法会首先在$classMap中查找类名命中后直接include对应文件因此类映射的优先级高于 PSR-4 式的别名推导。值得留意的是classes.php 本身就是 Yii 核心类的类映射文件由构建脚本自动生成包含yii\base\Action、yii\base\Application等 430 行映射项它在 Yii.php 中被加载进Yii::$classMap你可以参考它的写法为自己的第三方类库建立映射。在第三方系统内使用 YiiYii 提供了很多开箱即用的功能有时你可能想把其中一部分能力比如方便的yii\helpers\ArrayHelper助手类或活动记录 Active Record 数据库操作能力引入 WordPress、Joomla 或其他 PHP 框架开发的应用中。实现这个目标只需两步安装 Yii启动 Yii。安装 Yii若第三方系统支持 Composer 管理依赖直接运行composer require yiisoft/yii2如果你的目标只是使用数据库抽象层DB abstraction layer或 Yii 的其他非静态资源相关功能可以使用特殊的 Composer 包如cebe/assetfree-yii2来阻止 Bower 和 NPM 包的安装从而避免引入前端 asset 依赖。关于如何通过 Composer 的replace段跳过 assets 安装可参考安装文档中bower-asset/jquery、bower-asset/inputmask、bower-asset/punycode、bower-asset/yii2-pjax等包的替换写法。关于 Composer 安装过程中可能遇到的问题另请参见通过 Composer 安装 Yii。若第三方系统不使用 Composer也可以下载 Yii 的发布包解压到对应系统的BasePath/vendor目录内。在第三方入口脚本中启动 Yii之后修改第三方应用的入口脚本在开头位置添加 Yii 的引入代码require __DIR__ . /../vendor/yiisoft/yii2/Yii.php; $yiiConfig require __DIR__ . /../config/yii/web.php; new yii\web\Application($yiiConfig); // 不要在这里调用 run() 方法。这段代码与典型 Yii 应用的入口脚本非常相似唯一的不同在于Yii 应用实例创建之后不会紧接着调用run()方法。因为run()会接管 HTTP 请求的处理流程——一旦调用URL 规则、请求/响应处理就全部由 Yii 接管第三方系统也就不再是系统主体了。所以集成场景下只创建应用实例构造yii\web\Application时会完成组件注册与初始化把 Yii 当作一个可随时调用的服务层而请求分发仍由第三方系统负责。与 Yii 应用一样你可以根据第三方系统的运行环境针对性地配置 Yii 应用实例。比如为了使用活动记录功能需要先用第三方系统的 DB 连接信息配置 Yii 的db应用组件$yiiConfig [ id embedded-in-third-party, components [ db [ class yii\db\Connection, dsn mysql:hostlocalhost;dbnamethird_party_db, username dbuser, password dbpass, ], ], ];完成上述配置后你就可以在第三方代码中尽情使用 Yii 提供的大多数功能了——创建 AR 模型类并用它们操作数据库、使用ArrayHelper等助手类以及在任意位置通过Yii::$app访问这个已初始化的应用实例。配合使用 Yii 2 和 Yii 1如果你之前使用 Yii 1并且有正在运行的 Yii 1 应用不必用 Yii 2 重写整个应用也可以通过对既有系统增添 Yii 2 独占功能来增强它。下面详细描述实现过程。Note: Yii 2 需要 PHP 5.4 的版本就当前仓库而言framework/composer.json 中的require段已要求php: 7.4.0请以你实际部署的 Yii 2 版本对应的 PHP 要求为准。你需要确保服务器以及现有应用都能满足版本要求。在 Yii 1 应用中安装并启动 Yii 2首先参考前文的方法在已有应用中安装 Yii 2Composer 安装或解压发布包均可。之后按下述方式修改 Yii 1 应用的入口脚本// 导入下面会详细说明的定制 Yii 类文件。 require __DIR__ . /../components/Yii.php; // Yii 2 应用的配置文件 $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 类以桥接两个框架由于 Yii 1 和 Yii 2 都包含名为Yii的类直接同时引入必然冲突因此需要创建一个定制版的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;这段代码之所以可行是因为 Yii 2 的核心实现全部位于yii\BaseYii这个可扩展的基类中。从 Yii.php 可以看到官方实现正是class Yii extends \yii\BaseYii {}随后注册自动加载器、加载classes.php类映射、创建 DI 容器。集成场景下的定制类与之同构class Yii extends \yii\BaseYii继承 Yii 2 的全部静态方法Yii::$app、Yii::createObject()、Yii::getAlias()、Yii::t()等同时把 Yii 1 的YiiBase中的代码如Yii::app()、Yii::createWebApplication()复制进定制类于是两个框架的静态 API 在同一个Yii类中共存。Yii::$classMap加载 Yii 2 的类映射classes.phpregisterAutoloader([Yii, autoload])则把 Yii 2 的autoload()方法注册为自动加载器这正是 Yii.php 中spl_autoload_register([Yii, autoload], true, true)的等价操作Yii::$container new yii\di\Container初始化依赖注入容器使Yii::createObject()可用。大功告成后你可以在代码的任意位置同时访问两个框架的应用实例echo get_class(Yii::app()); // 输出 CWebApplication echo get_class(Yii::$app); // 输出 yii\web\Application其中Yii::app()返回 Yii 1 的应用实例来自createWebApplication()-run()的静态访问而Yii::$app则是 Yii 2 的应用实例——两者在同一进程中各司其职互不干扰。集成要点速查下表总结了四种在 Yii 中使用第三方类库的方式及其适用条件便于快速决策类库形态处理方式关键操作Composer 包声明依赖并安装修改composer.json运行php composer.phar install入口脚本加载vendor/autoload.php自带自动加载器的下载库手动安装解压到BasePath/vendor在入口脚本Yii.php之前注册其自动加载器PSR-4 标准库声明根别名在应用配置aliases中为根命名空间添加别名如xyz vendor/foo/bar依赖 include_path 或需显式导入配置导入路径 / 类映射调整 PHP 导入路径或在入口脚本填充Yii::$classMap反向集成把 Yii 嵌入第三方系统的核心口诀同样是两句安装 YiiComposer 或手动解压到vendor启动 Yii在第三方入口脚本中new yii\web\Application($config)但不调用run()。而在 Yii 1 与 Yii 2 共存的场景中关键在于通过一个继承yii\BaseYii并融合YiiBase代码的定制Yii类配合类映射、自动加载器注册与 DI 容器初始化让新旧两代框架在同一 PHP 进程内和谐共处。延伸阅读入口脚本了解入口脚本的完整职责与常量定义别名Aliases根别名、衍生别名的定义与解析规则应用结构base path、应用配置与组件活动记录 Active Record在第三方系统中使用 Yii 的数据库操作能力通过 Composer 安装 YiiComposer 安装与问题排查框架核心实现autoload()、getAlias()、setAlias()、createObject()等关键方法的源码框架入口 Yii.php官方Yii类的定义与自动加载器注册核心类映射Yii 核心类的 class map 示例框架 composer.jsonYii 2 的 Composer 依赖声明与 PSR-4 自动加载配置赞分享后端Web框架【免费下载链接】yii2Yii 2: The Fast, Secure and Professional PHP Framework项目地址https://gitcode.com/gh_mirrors/yi/yii2点击查看免费下载相关推荐Yii 2 与第三方代码集成完全指南在 Yii 中使用外部库、将 Yii 嵌入其他系统及 Yii 2/Yii 1 共存实战Yii 2 与第三方代码集成完全指南在 Yii 中使用外部库、将 Yii 嵌入其他系统及 Yii 2/Yii 1 共存实战 本文基于 Yii 2 官方指南的后端Web框架Yii 2 第三方代码集成实战在 Yii 中使用第三方库、把 Yii 嵌入外部系统及 Yii 1/2 双版本共存Yii 2 第三方代码集成实战在 Yii 中使用第三方库、把 Yii 嵌入外部系统及 Yii 1/2 双版本共存 本文基于 Yii 2 官方指南的《Работ后端Web框架Yii 2 第三方代码集成实战在 Yii 中使用第三方库、将 Yii 嵌入既有系统与 Yii 1/2 共存Yii 2 第三方代码集成实战在 Yii 中使用第三方库、将 Yii 嵌入既有系统与 Yii 1/2 共存 导读 本文基于 Yii 2 官方指南的 Trab后端Web框架上一篇如何用Python轻松下载番茄小说构建个人离线图书馆的完整指南下一篇抖音下载器终极指南免费批量下载无水印视频的完整方案创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表