drewm/morse

PHP代码便携性的功能检测库

v0.6 2015-08-18 17:37 UTC

This package is auto-updated.

Last update: 2024-08-24 04:30:41 UTC


README

Morse 是一个用于 PHP 代码在不同环境中运行的特性检测库。

Build Status Scrutinizer Code Quality

支持 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_SUPPORTMorse::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')