今天突然想看看那些,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);
}
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;
* 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;
}
return;
}
if (strict) {
is_equal_func = is_identical_function;
}
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);
}
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);
}
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
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