今天突然想看看那些,count(),in_array()这样的数组函数是怎么实现的,于是去找php的源代码,搜索了一下。找到了php源文件里有这样一个文件:php-5.3.0extstandardarray.c 在里面找了一下。

 

/* {{{ 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);
}

好像又用到了 php_search_array,那就去找吧,代码如下:

/* 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, 0, &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;
}

 

不仅是in_array()调用了,还有一个array_search()也使用了这个函数。

/* {{{ proto mixed array_search(mixed needle, array haystack [, 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);
}

看来那些php函数都是通过c语言实现的。这些代码里经常出现”zend_”,由此可见这些东西与zend公司大有渊源啊。

不过这些代码写的一点也不友好,像天书似的,是不是高手写代码都要这样呢?

 

附上standard目录里的其它c后缀文件名

assert.c                  base64.c                  versioning.c
basic_functions.c         var_unserializer.c        browscap.c
var.c                     uuencode.c                crc32.c
array.c                   credits.c                 url_scanner_ex.c
url_scanner.c             url.c                     crypt.c
crypt_blowfish.c          crypt_freesec.c           uniqid.c
css.c                     type.c                    cyr_convert.c
user_filters.c            datetime.c                syslog.c
dir.c                     dl.c                      strnatcmp.c
dns.c                     string.c                  dns_win32.c
exec.c                    streamsfuncs.c            file.c
soundex.c                 filestat.c                filters.c
flock_compat.c            sha1.c                    formatted_print.c
fsock.c                   scanf.c                   ftok.c
ftp_fopen_wrapper.c       head.c                    rand.c
html.c                    quot_print.c              http.c
http_fopen_wrapper.c      image.c                   incomplete_class.c
info.c                    proc_open.c               iptc.c
lcg.c                     levenshtein.c             link.c
link_win32.c              mail.c                    php_fopen_wrapper.c
math.c                    md5.c                     php_crypt_r.c
metaphone.c               microtime.c               pageinfo.c
pack.c  

Comments are closed.

Post Navigation