免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2845 | 回复: 3
打印 上一主题 下一主题

修改array_combine函数,增加可选参数use_strict [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-05-29 18:06 |只看该作者 |倒序浏览
本帖最后由 无野 于 2010-06-15 16:29 编辑

array_combine是PHP5一个standard的array函数。
它的作用是创建一个数组,用一个数组的值作为其键名,另一个数组的值作为其值。
    array array_combine ( array $keys, array $values )
    返回一个 array,用来自 keys 数组的值作为键名,来自 values 数组的值作为相应的值。
    如果两个数组的单元数不同或者数组为空时返回 FALSE。

注意粗体字的描述,也就是说,如果你使用array_combine,在没有做好兼容性的情况下,便有因为两数组单元素不同而导致程序异常。
首先不讨论这种异常对于程序来说是好处还是坏处,我认为至少函数应该要给程序员一个可选的严格模式。

我决定对array_combine做这个修改,即添加一个boolean参数use_strict,默认值为true。这样可以兼容原生的函数。
vi php-5.3.1/ext/standard/array.c, 将array_combine函数原型源码修改成如下:
  1. /* {{{ proto array array_combine(array keys, array values)
  2.    Creates an array by using the elements of the first parameter as keys and the elements of the second as the corresponding values
  3. */
  4. PHP_FUNCTION(array_combine)
  5. {
  6.         zval *values, *keys;
  7.         HashPosition pos_values, pos_keys;
  8.         zval **entry_keys, **entry_values;
  9.         int num_keys, num_values;
  10.         zend_bool use_strict = 1;

  11.         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "aa|b", &keys, &values, &use_strict) == FAILURE) {
  12.                 return;
  13.         }

  14.         num_keys = zend_hash_num_elements(Z_ARRVAL_P(keys));
  15.         num_values = zend_hash_num_elements(Z_ARRVAL_P(values));
  16.         if (use_strict){
  17.                 if (num_keys != num_values) {
  18.                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Both parameters should have an equal number of elements");
  19.                         RETURN_FALSE;
  20.                 }
  21.         }
  22.         if (!num_keys) {
  23.                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Both parameters should have at least 1 element");
  24.                 RETURN_FALSE;
  25.         }

  26.         array_init_size(return_value, num_keys);

  27.         zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(keys), &pos_keys);
  28.         zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(values), &pos_values);
  29.         while (zend_hash_get_current_data_ex(Z_ARRVAL_P(keys), (void **)&entry_keys, &pos_keys) == SUCCESS &&
  30.                 zend_hash_get_current_data_ex(Z_ARRVAL_P(values), (void **)&entry_values, &pos_values) == SUCCESS
  31.         ) {
  32.                 if (Z_TYPE_PP(entry_keys) == IS_LONG) {
  33.                         zval_add_ref(entry_values);
  34.                         add_index_zval(return_value, Z_LVAL_PP(entry_keys), *entry_values);
  35.                 } else {
  36.                         zval key, *key_ptr = *entry_keys;

  37.                         if (Z_TYPE_PP(entry_keys) != IS_STRING) {
  38.                                 key = **entry_keys;
  39.                                 zval_copy_ctor(&key);
  40.                                 convert_to_string(&key);
  41.                                 key_ptr = &key;
  42.                         }

  43.                         zval_add_ref(entry_values);
  44.                         add_assoc_zval_ex(return_value, Z_STRVAL_P(key_ptr), Z_STRLEN_P(key_ptr) + 1, *entry_values);

  45.                         if (key_ptr != *entry_keys) {
  46.                                 zval_dtor(&key);
  47.                         }
  48.                 }

  49.                 zend_hash_move_forward_ex(Z_ARRVAL_P(keys), &pos_keys);
  50.                 zend_hash_move_forward_ex(Z_ARRVAL_P(values), &pos_values);
  51.         }
  52. }
  53. /* }}} */
复制代码
这样,array_combine就变成了:
    array array_combine ( array $keys, array $values [, bool $use_strict] )

因为我在一台测试上做这个事,所以我重编译了PHP。

我们来测一下修改的效果。
使用默认的严格模式:
  1. $a = array('green', 'red');
  2. $b = array('avocado', 'apple', 'banana');
  3. $c = array_combine($a, $b);
  4. print_r($c);
复制代码
  1. [root@tekeq test]# /wwws/php/bin/php test.php
  2. PHP Warning:  array_combine(): Both parameters should have an equal number of elements in /root/test/test.php on line 5
复制代码
使用非严格模式:
  1. $a = array('green', 'red');
  2. $b = array('avocado', 'apple', 'banana');
  3. $c = array_combine($a, $b, false); //使用非严格模式
  4. print_r($c);
复制代码
  1. [root@tekeq test]# /wwws/php/bin/php test.php
  2. Array
  3. (
  4.     [green] => avocado
  5.     [red] => apple
  6. )
复制代码
看起来一切正常,就这么办。

认为有需要的同学,可以改一下,这修改后的是兼容以前的。
如果觉得没必要就算了,我是有需要才改,不是改着玩。

相关文章:http://tekeq.com/tech/array_combine/

论坛徽章:
59
2015七夕节徽章
日期:2015-08-24 11:17:25ChinaUnix专家徽章
日期:2015-07-20 09:19:30每周论坛发贴之星
日期:2015-07-20 09:19:42ChinaUnix元老
日期:2015-07-20 11:04:38荣誉版主
日期:2015-07-20 11:05:19巳蛇
日期:2015-07-20 11:05:26CU十二周年纪念徽章
日期:2015-07-20 11:05:27IT运维版块每日发帖之星
日期:2015-07-20 11:05:34操作系统版块每日发帖之星
日期:2015-07-20 11:05:36程序设计版块每日发帖之星
日期:2015-07-20 11:05:40数据库技术版块每日发帖之星
日期:2015-07-20 11:05:432015年辞旧岁徽章
日期:2015-07-20 11:05:44
2 [报告]
发表于 2010-05-29 21:53 |只看该作者
学习了,不错。有创意。

论坛徽章:
0
3 [报告]
发表于 2010-05-30 10:27 |只看该作者
我有点吃饱了撑着的感觉。

论坛徽章:
0
4 [报告]
发表于 2010-05-30 16:22 |只看该作者
我有点吃饱了撑着的感觉。
maochanglu 发表于 2010-05-30 10:27

你还真没说错,哈哈
我最近晚上老感觉吃饱了会撑着,所以决定以后晚上只吃水果,不吃饭。
想找回以前身轻如燕的感觉。。。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP