drewm / morse
PHP代码便携性的功能检测库
Requires
- php: >=5.3
Requires (Dev)
- phpunit/phpunit: 4.0.*
README
Morse 是一个用于 PHP 代码在不同环境中运行的特性检测库。
支持 PHP 5.3 及以上版本。
为什么?
在未知(有时甚至是敌对)环境中编写可工作的 PHP 代码是困难的。你并不总是知道有哪些功能可用,因此你必须对其进行测试。Morse 是一个用于封装这些测试的库。
大多数测试都非常简单——只需一个 function_exists()
或类似的函数——但你在代码库中可能需要重复进行这些测试。Morse 将这些测试集中起来,提供了可重用性和一致性。
某些测试可能并不那么简单,可能是因为 那个奇怪的 PHP 错误 或不寻常的托管配置或其他原因。你必须做一些奇怪的舞蹈来检查某件事是否真的会工作。Morse 会处理这个问题,并确保你的应用程序代码中不会有这种奇怪的舞蹈,防止下一个开发者认为它很愚蠢并将其删除。
安装
可以下载并包含,或者通过 Composer 安装
composer require drewm/morse
如何
use \DrewM\Morse\Morse; if (Morse::featureExists('http/curl')) { // use curl }else{ // use sockets }
测试功能是否存在
Morse::featureExists('group/feature');
可能存在于新类支持或旧函数支持中的功能可以返回 Morse::CLASS_SUPPORT
或 Morse::FUNCTION_SUPPORT
的值,这两个值都是真值。
所以这个是可行的
if (Morse::featureExists('file/finfo')) { ... }
但同样
switch(Morse::featureExists('file/finfo')) { case Morse::CLASS_SUPPORT: $finfo = new finfo(...); break; case Morse::FUNCTION_SUPPORT: $finfo = finfo_open(...); break; default: die('No finfo support!'); break; }
如果找到类支持,则无论函数支持如何都会返回。
在列表中查找第一个匹配项
$best_match = Morse::getFirstAvailable(['image/gd', 'image/imagick']);
或
$best_match = Morse::getFirstAvailable([ 'image/gd' => 'gd', 'image/imagick' => 'imagick' ]); switch($best_match) { case 'gd': ... break; case 'imagick': ... break; }
特性
当前的功能检测测试包括以下内容
- 缓存
- apc
- memcache
- memcached
- opcache
- crypto
- mcrypt
- openssl
- password
- 数据
- json
- 数据库
- mysqli
- pdo
- pdo-mysql
- pdo-pgsql
- pdo-sqlite
- 文件
- finfo
- zip
- http
- curl
- filter
- 套接字
- 图像
- gd
- imagick
- 数字
- bigint
- 协议
- ldap
- 系统
- exec
- ignore_user_abort
- ini_set
- passthru
- popen
- proc_open
- set_time_limit
- shell_exec
- 系统
- 文本
- ctype
- iconv
- intl
- 多字节
- 转写
贡献特性测试
特性测试是返回 true 或 false 的函数,以指示对某个特性的支持。
假设你想添加一个名为 Pongo 的数据库的特性检测测试。你可以使用特性标识符 db/pongo
来测试它,这将映射到 Feature/Db.php
类文件中的名为 testPongo
的函数。
特性标识符的两部分都会通过 ucwords()
转换以修正大小写。破折号会被转换为下划线。因此,db/pongo-panda
会映射到 Feature\Db::testPongo_Panda
。
namespace DrewM\Morse\Feature; class Db extends \DrewM\Morse\Feature { public function testPongo_Panda() { // do whatever needs to be done to determine support // return true for support, false for no support; return true; } }
如果特性可以存在于 OO 风格类和过程式函数形式中,返回 \DrewM\Morse\Morse::CLASS_SUPPORT
或 \DrewM\Morse\Morse::FUNCTION_SUPPORT
作为你的真值。首先检查类。
namespace DrewM\Morse\Feature; class Db extends \DrewM\Morse\Feature { public function testPongo_Panda() { if (class_exists('PongoPanda')) { return \DrewM\Morse\Morse::CLASS_SUPPORT; } if (self::functionAvailable('pongo_panda')) { return \DrewM\Morse\Morse::FUNCTION_SUPPORT; } return false; } }
特性类应该是大概念(图像、文本、数据库),而测试本身应该是特定功能。
请为你要添加的功能编写相应的 PHPUnit 测试。请注意,你不能依赖于环境,所以只需测试检测是否正常工作并返回一个合理的值。
功能可用性测试
PHP 提供了 function_exists()
函数用于测试一个函数是否已声明。在某些情况下(例如当 suhosin 黑名单被激活时),即使函数已被禁用且不可用,它也可能返回 true
。因此,在功能类内部执行以下操作以检测一个函数是否既已声明且未禁用
self::functionAvailable('pongo_panda')