在动态类型的 PHP 中,我们可以创建可以接受多种数据类型作为参数的函数。然后我们可以根据变量的类型对数据进行操作。有两种方法可以做到这一点:
方法一 :
function doSomething1($param) {
$type = gettype($param);
if ($type === 'string') {
// do something
}
else if ($type === 'integer') {
// do something
}
else if ($type === 'array') {
// do something
}
}
方法二 :
function doSomething2($param) {
if (is_string($param)) {
// do something
}
else if (is_int($param)) {
// do something
}
else if (is_array($param)) {
// do something
}
}
gettype()
比个人更昂贵的操作is_*()
职能? 更新
从我使用 PHP 7.0.4 的基准测试来看,一百万次迭代
doSomething2()
耗时 159 毫秒,略少于 doSomething1()
的一半时间在 315 毫秒。这与传入的是字符串(第一次检查)还是数组(最后一次检查)无关。这似乎表明 gettype()
确实是一个昂贵的操作,比使用 is_*()
的多个函数调用更昂贵.任何对这可能发生的原因有更深入了解的人,都非常感谢您的帮助。
最佳答案
让我们比较 gettype
的 C 代码和 is_string
职能。gettype
:
PHP_FUNCTION(gettype)
{
zval *arg;
zend_string *type;
ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_ZVAL(arg)
ZEND_PARSE_PARAMETERS_END();
type = zend_zval_get_type(arg);
if (EXPECTED(type)) {
RETURN_INTERNED_STR(type);
} else {
RETURN_STRING("unknown type");
}
}
因此,它创建字符串
type
并通过调用函数 zend_zval_get_type
的结果填充它,即:ZEND_API zend_string *zend_zval_get_type(const zval *arg) /* {{{ */
{
switch (Z_TYPE_P(arg)) {
case IS_NULL:
return ZSTR_KNOWN(ZEND_STR_NULL);
case IS_FALSE:
case IS_TRUE:
return ZSTR_KNOWN(ZEND_STR_BOOLEAN);
case IS_LONG:
return ZSTR_KNOWN(ZEND_STR_INTEGER);
case IS_DOUBLE:
return ZSTR_KNOWN(ZEND_STR_DOUBLE);
case IS_STRING:
return ZSTR_KNOWN(ZEND_STR_STRING);
case IS_ARRAY:
return ZSTR_KNOWN(ZEND_STR_ARRAY);
case IS_OBJECT:
return ZSTR_KNOWN(ZEND_STR_OBJECT);
case IS_RESOURCE:
if (zend_rsrc_list_get_rsrc_type(Z_RES_P(arg))) {
return ZSTR_KNOWN(ZEND_STR_RESOURCE);
} else {
return ZSTR_KNOWN(ZEND_STR_CLOSED_RESOURCE);
}
default:
return NULL;
}
}
我们比较一下
is_string
, 例如:PHP_FUNCTION(is_string)
{
php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_STRING);
}
转至
php_is_type
:static inline void php_is_type(INTERNAL_FUNCTION_PARAMETERS, int type)
{
zval *arg;
ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_ZVAL(arg)
ZEND_PARSE_PARAMETERS_END();
if (Z_TYPE_P(arg) == type) {
if (type == IS_RESOURCE) {
const char *type_name = zend_rsrc_list_get_rsrc_type(Z_RES_P(arg));
if (!type_name) {
RETURN_FALSE;
}
}
RETURN_TRUE;
} else {
RETURN_FALSE;
}
}
所以,这些方法的核心逻辑是完全一样的——PHP使用
Z_TYPE_P
检测变量的类型。但在
gettype
的情况下它还为结果创建额外的字符串并用常量字符串填充它,而不是在 is_*
的情况下只返回 bool 值 TRUE 或 FALSE|职能。所以,绝对是
is_*
功能更快:)
关于php - 在 PHP 中进行类型检查的更快方法是什么? gettype() 或多个 is_*(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36494054/