加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

深入php内核之php in array

发布时间:2020-12-13 02:56:03 所属栏目:PHP教程 来源:网络整理
导读:《深入php内核之php in array》要点: 本文介绍了深入php内核之php in array,希望对您有用。如果有疑问,可以联系我们。 先给年夜家介绍php in array函数基本知识热热身. PHP实战 界说和用法 PHP实战 in_array() 函数在数组中搜刮给定的值. PHP实战 语法 in

《深入php内核之php in array》要点:
本文介绍了深入php内核之php in array,希望对您有用。如果有疑问,可以联系我们。

先给年夜家介绍php in array函数基本知识热热身.PHP实战

界说和用法PHP实战

in_array() 函数在数组中搜刮给定的值.PHP实战

语法
in_array(value,array,type)PHP实战

?阐明
PHP实战

如果给定的值 value 存在于数组 array 中则返回 true.如果第三个参数设置为 true,函数只有在元素存在于数组中且数据类型与给定值雷同时才返回 true.
PHP实战

假如没有在数组中找到参数,函数返回 false.PHP实战

注释:如果 value 参数是字符串,且 type 参数设置为 true,则搜索区分年夜小写.PHP实战

无心中看到一段代码PHP实战

<必修php    
$y="1800";
$x = array();
for($j=0;$j<50000;$j++){
 $x[]= "{$j}";
}
for($i=0;$i<30000;$i++){
 if(in_array($y,$x)){
  continue;
 } 
}

测试了一下PHP实战

[root@dev tmp]# time php b.php
real??? 0m9.517s
user??? 0m4.486s
sys???? 0m0.015sPHP实战

竟然必要9sPHP实战

in_array是这个样子的PHP实战

代码如下:

bool in_array ( mixed $needle,array $haystack [,bool $strict = FALSE ] )

在 haystack 中搜索 needle,如果没有设置 strict 则使用宽松的比拟.PHP实战

needlePHP实战

待搜索的值.如果 needle 是字符串,则比拟是区分大小写的.PHP实战

haystackPHP实战

这个数组.PHP实战

strictPHP实战

如果第三个参数 strict 的值为 TRUE 则 in_array() 函数还会反省 needle 的类型是否和 haystack 中的相同.PHP实战

那么我看一下源代码PHP实战

第一步 在ext/standard/array.c 文件中PHP实战

/* }}} */              
/* {{{ proto bool in_array(mixed needle,array haystack [,bool strict])
 Checks if the given value exists in the array */   
PHP_FUNCTION(in_array)          
{                
 php_search_array(INTERNAL_FUNCTION_PARAM_PASSTHRU,0); 
}                
/* }}} */             
/* {{{ proto mixed array_search(mixed needle,bool strict])
 Searches the array for a given value and returns the corresponding key if successful */
PHP_FUNCTION(array_search)         
{            
 php_search_array(INTERNAL_FUNCTION_PARAM_PASSTHRU,1); 
}                
/* }}} */ 

顺便看到了array_search,本来和in_array的内部实现基本一致PHP实战

此中函数的参数 在./zend.h中PHP实战

#define INTERNAL_FUNCTION_PARAM_PASSTHRU ht,return_value,return_value_ptr,this_ptr,return_value_used TSRMLS_CCPHP实战

第二步 在ext/standard/array.c 文件中 查看php_search_array原型PHP实战

/* void php_search_array(INTERNAL_FUNCTION_PARAMETERS,int behavior)
 * 0 = return boolean
 * 1 = return key
 */  
static void php_search_array(INTERNAL_FUNCTION_PARAMETERS,int behavior) /* {{{ */
{  
 zval *value,/* value to check for */
   *array,/* array to check in */
   **entry,/* pointer to array entry */
   res;    /* comparison result */
 HashPosition pos;  /* hash iterator */
 zend_bool strict = 0;  /* strict comparison or not */
 ulong num_key;
 uint str_key_len;
 char *string_key;
 int (*is_equal_func)(zval *,zval *,zval * TSRMLS_DC) = is_equal_function;
 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,"za|b",&value,&array,&strict) == FAILURE) {
  return;
 } 
 if (strict) {
  is_equal_func = is_identical_function;
 } 
 zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(array),&pos);
 while (zend_hash_get_current_data_ex(Z_ARRVAL_P(array),(void **)&entry,&pos) == SUCCESS) {
  is_equal_func(&res,value,*entry TSRMLS_CC);
  if (Z_LVAL(res)) {
   if (behavior == 0) {
    RETURN_TRUE;
   } else {
    /* Return current key */
    switch (zend_hash_get_current_key_ex(Z_ARRVAL_P(array),&string_key,&str_key_len,&num_key,&pos)) {
     case HASH_KEY_IS_STRING:
      RETURN_STRINGL(string_key,str_key_len - 1,1);
      break;
     case HASH_KEY_IS_LONG:
      RETURN_LONG(num_key);
      break;
    }
   }
  }
  zend_hash_move_forward_ex(Z_ARRVAL_P(array),&pos);
 } 
 RETURN_FALSE;
}  
/* }}} */
/* {{{ proto bool in_array(mixed needle,bool strict])
 Checks if the given value exists in the array */

我们发现 strict? 这个值的不同有两种比拟方式,看一下两个函数的不同之处PHP实战

is_identical_function 反省类型是否相同PHP实战

ZEND_API int is_identical_function(zval *result,zval *op1,zval *op2 TSRMLS_DC) /* {{{ */
{  
 Z_TYPE_P(result) = IS_BOOL;
 if (Z_TYPE_P(op1) != Z_TYPE_P(op2)) {
  Z_LVAL_P(result) = 0;
  return SUCCESS;
 } 
 switch (Z_TYPE_P(op1)) {
  case IS_NULL:
   Z_LVAL_P(result) = 1;
   break;
  case IS_BOOL:
  case IS_LONG:
  case IS_RESOURCE:
   Z_LVAL_P(result) = (Z_LVAL_P(op1) == Z_LVAL_P(op2));
   break;
  case IS_DOUBLE:
   Z_LVAL_P(result) = (Z_DVAL_P(op1) == Z_DVAL_P(op2));
   break;
  case IS_STRING:
   Z_LVAL_P(result) = ((Z_STRLEN_P(op1) == Z_STRLEN_P(op2))
   && (!memcmp(Z_STRVAL_P(op1),Z_STRVAL_P(op2),Z_STRLEN_P(op1))));
   break;
  case IS_ARRAY:
   Z_LVAL_P(result) = (Z_ARRVAL_P(op1) == Z_ARRVAL_P(op2)
   zend_hash_compare(Z_ARRVAL_P(op1),Z_ARRVAL_P(op2),(compare_func_t) hash_zval_identical_function,1 TSRMLS_CC)==0);
   break;
  case IS_OBJECT:
   if (Z_OBJ_HT_P(op1) == Z_OBJ_HT_P(op2)) {
   Z_LVAL_P(result) = (Z_OBJ_HANDLE_P(op1) == Z_OBJ_HANDLE_P(op2));
   } else {
   Z_LVAL_P(result) = 0;
   }
   break;
  default:
   Z_LVAL_P(result) = 0;
   return FAILURE;
 } 
 return SUCCESS;
}  
/* }}} */

is_equal_function 不检查类型是否相同,所以必要隐式转换PHP实战

ZEND_API int is_equal_function(zval *result,zval *op2 TSRMLS_DC) /* {{{ */
{  
 if (compare_function(result,op1,op2 TSRMLS_CC) == FAILURE) {
  return FAILURE;
 } 
 ZVAL_BOOL(result,(Z_LVAL_P(result) == 0));
 return SUCCESS;
}  
/* }}} */
==》compare_function
ZEND_API int compare_function(zval *result,zval *op2 TSRMLS_DC) /* {{{ */
{   
 int ret;
 int converted = 0;
 zval op1_copy,op2_copy;
 zval *op_free;
 while (1) {
  switch (TYPE_PAIR(Z_TYPE_P(op1),Z_TYPE_P(op2))) {
   case TYPE_PAIR(IS_LONG,IS_LONG):
   ZVAL_LONG(result,Z_LVAL_P(op1)>Z_LVAL_P(op2)必修1:(Z_LVAL_P(op1)<Z_LVAL_P(op2)必修-1:0));
   return SUCCESS;
   case TYPE_PAIR(IS_DOUBLE,IS_LONG):
   Z_DVAL_P(result) = Z_DVAL_P(op1) - (double)Z_LVAL_P(op2);
   ZVAL_LONG(result,ZEND_NORMALIZE_BOOL(Z_DVAL_P(result)));
   return SUCCESS;
   case TYPE_PAIR(IS_LONG,IS_DOUBLE):
   Z_DVAL_P(result) = (double)Z_LVAL_P(op1) - Z_DVAL_P(op2);
   ZVAL_LONG(result,ZEND_NORMALIZE_BOOL(Z_DVAL_P(result)));
   return SUCCESS;
   case TYPE_PAIR(IS_DOUBLE,IS_DOUBLE):
   if (Z_DVAL_P(op1) == Z_DVAL_P(op2)) {
    ZVAL_LONG(result,0);
   } else {
    Z_DVAL_P(result) = Z_DVAL_P(op1) - Z_DVAL_P(op2);
    ZVAL_LONG(result,ZEND_NORMALIZE_BOOL(Z_DVAL_P(result)));
   }
   return SUCCESS;
   case TYPE_PAIR(IS_ARRAY,IS_ARRAY):
   zend_compare_arrays(result,op2 TSRMLS_CC);
   return SUCCESS;
   case TYPE_PAIR(IS_NULL,IS_NULL):
   ZVAL_LONG(result,0);
   return SUCCESS;
   case TYPE_PAIR(IS_NULL,IS_BOOL):
   ZVAL_LONG(result,Z_LVAL_P(op2) 必修 -1 : 0);
   return SUCCESS;
   case TYPE_PAIR(IS_BOOL,Z_LVAL_P(op1) 必修 1 : 0);
   return SUCCESS;
   case TYPE_PAIR(IS_BOOL,ZEND_NORMALIZE_BOOL(Z_LVAL_P(op1) - Z_LVAL_P(op2)));
   return SUCCESS;
   case TYPE_PAIR(IS_STRING,IS_STRING):
   zendi_smart_strcmp(result,op2);
   return SUCCESS;
   case TYPE_PAIR(IS_NULL,IS_STRING):
   ZVAL_LONG(result,zend_binary_strcmp("",Z_STRLEN_P(op2)));
   return SUCCESS;
   case TYPE_PAIR(IS_STRING,zend_binary_strcmp(Z_STRVAL_P(op1),Z_STRLEN_P(op1),"",0));
   return SUCCESS;
   case TYPE_PAIR(IS_OBJECT,1);
   return SUCCESS;
   case TYPE_PAIR(IS_NULL,IS_OBJECT):
   ZVAL_LONG(result,-1);
   return SUCCESS;
   case TYPE_PAIR(IS_OBJECT,IS_OBJECT):
   /* If both are objects sharing the same comparision handler then use is */
   if (Z_OBJ_HANDLER_P(op1,compare_objects) == Z_OBJ_HANDLER_P(op2,compare_objects)) {
    if (Z_OBJ_HANDLE_P(op1) == Z_OBJ_HANDLE_P(op2)) {
     /* object handles are identical,apparently this is the same object */
     ZVAL_LONG(result,0);
     return SUCCESS;
    }
    ZVAL_LONG(result,Z_OBJ_HT_P(op1)->compare_objects(op1,op2 TSRMLS_CC));
    return SUCCESS;
   }
   /* break missing intentionally */
   default:
   if (Z_TYPE_P(op1) == IS_OBJECT) {
    if (Z_OBJ_HT_P(op1)->get) {
     op_free = Z_OBJ_HT_P(op1)->get(op1 TSRMLS_CC);
     ret = compare_function(result,op_free,op2 TSRMLS_CC);
     zend_free_obj_get_result(op_free TSRMLS_CC);
     return ret;
    } else if (Z_TYPE_P(op2) != IS_OBJECT && Z_OBJ_HT_P(op1)->cast_object) {
     ALLOC_INIT_ZVAL(op_free);
     if (Z_OBJ_HT_P(op1)->cast_object(op1,Z_TYPE_P(op2) TSRMLS_CC) == FAILURE) {
      ZVAL_LONG(result,1);
      zend_free_obj_get_result(op_free TSRMLS_CC);
      return SUCCESS;
     }
     ret = compare_function(result,op2 TSRMLS_CC);
     zend_free_obj_get_result(op_free TSRMLS_CC);
     return ret;
    }
   }
   if (Z_TYPE_P(op2) == IS_OBJECT) {
    if (Z_OBJ_HT_P(op2)->get) {
     op_free = Z_OBJ_HT_P(op2)->get(op2 TSRMLS_CC);
     ret = compare_function(result,op_free TSRMLS_CC);
     zend_free_obj_get_result(op_free TSRMLS_CC);
     return ret;
    } else if (Z_TYPE_P(op1) != IS_OBJECT && Z_OBJ_HT_P(op2)->cast_object) {
     ALLOC_INIT_ZVAL(op_free);
     if (Z_OBJ_HT_P(op2)->cast_object(op2,Z_TYPE_P(op1) TSRMLS_CC) == FAILURE) {
      ZVAL_LONG(result,-1);
      zend_free_obj_get_result(op_free TSRMLS_CC);
      return SUCCESS;
     }
     ret = compare_function(result,op_free TSRMLS_CC);
     zend_free_obj_get_result(op_free TSRMLS_CC);
     return ret;
    } else if (Z_TYPE_P(op1) == IS_OBJECT) {
     ZVAL_LONG(result,1);
     return SUCCESS;
    }
   }
   if (!converted) {
    if (Z_TYPE_P(op1) == IS_NULL) {
     zendi_convert_to_boolean(op2,op2_copy,result);
     ZVAL_LONG(result,Z_LVAL_P(op2) 必修 -1 : 0);
     return SUCCESS;
    } else if (Z_TYPE_P(op2) == IS_NULL) {
     zendi_convert_to_boolean(op1,op1_copy,Z_LVAL_P(op1) 必修 1 : 0);
     return SUCCESS;
    } else if (Z_TYPE_P(op1) == IS_BOOL) {
     zendi_convert_to_boolean(op2,ZEND_NORMALIZE_BOOL(Z_LVAL_P(op1) - Z_LVAL_P(op2)));
     return SUCCESS;
    } else if (Z_TYPE_P(op2) == IS_BOOL) {
     zendi_convert_to_boolean(op1,ZEND_NORMALIZE_BOOL(Z_LVAL_P(op1) - Z_LVAL_P(op2)));
     return SUCCESS;
    } else {
     zendi_convert_scalar_to_number(op1,result);
     zendi_convert_scalar_to_number(op2,result);
     converted = 1;
    }
   } else if (Z_TYPE_P(op1)==IS_ARRAY) {
    ZVAL_LONG(result,1);
    return SUCCESS;
   } else if (Z_TYPE_P(op2)==IS_ARRAY) {
    ZVAL_LONG(result,-1);
    return SUCCESS;
   } else if (Z_TYPE_P(op1)==IS_OBJECT) {
    ZVAL_LONG(result,1);
    return SUCCESS;
   } else if (Z_TYPE_P(op2)==IS_OBJECT) {
    ZVAL_LONG(result,-1);
    return SUCCESS;
   } else {
    ZVAL_LONG(result,0);
    return FAILURE;
   }
  } 
 }  
}   
/* }}} */

编程之家培训学院每天发布《深入php内核之php in array》等实战技能,PHP、MYSQL、LINUX、APP、JS,CSS全面培养人才。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读