看看这个函数的核心C代码实现: if (Z_TYPE_P(needle) == IS_STRING) { if (!Z_STRLEN_P(needle)) { php_error_docref(NULL, E_WARNING, "Empty needle"); RETURN_FALSE; } found = (char*)php_memnstr(ZSTR_VAL(haystack) + offset, Z_STRVAL_P(needle), Z_STRLEN_P(needle), ZSTR_VAL(haystack) + ZSTR_LEN(haystack)); } else { //当不是字符串时,需要将参数转换为char类型 if (php_needle_char(needle, needle_char) != SUCCESS) { RETURN_FALSE; } needle_char[1] = 0; php_error_docref(NULL, E_DEPRECATED, "Non-string needles will be interpreted as strings in the future. " \ "Use an explicit chr() call to preserve the current behavior"); //查找转换为char类型后的字符串位置 found = (char*)php_memnstr(ZSTR_VAL(haystack) + offset, needle_char, 1, ZSTR_VAL(haystack) + ZSTR_LEN(haystack)); } static int php_needle_char(zval *needle, char *target) { switch (Z_TYPE_P(needle)) { case IS_LONG: //当提供的参数是long类型时,直接转换为数字对应的字符 *target = (char)Z_LVAL_P(needle); return SUCCESS; case IS_NULL: case IS_FALSE: *target = '\0'; return SUCCESS; case IS_TRUE: *target = '\1'; return SUCCESS; case IS_DOUBLE: *target = (char)(int)Z_DVAL_P(needle); return SUCCESS; case IS_OBJECT: *target = (char) zval_get_long(needle); return SUCCESS; default: php_error_docref(NULL, E_WARNING, "needle is not a string or an integer"); return FAILURE; } } 如果你提供的needle 参数不是字符串,则会调用php_needle_char 方法转换为参数对应的字符串,题目中就是626对应的ASCII字母为r。 你也可以用chr(626)看下输出的是不是r。 C源码: https://github.com/php/php-sr... ASCII中并没有 626 这个值,那么为什么chr方法会将 626 转换成了 r 呢? 看看C代码是如何实现的: int zend_compile_func_chr(znode *result, zend_ast_list *args) /* {{{ */ { if (args->children == 1 && args->child[0]->kind == ZEND_AST_ZVAL && Z_TYPE_P(zend_ast_get_zval(args->child[0])) == IS_LONG) { //主要原因是将值跟 0xff 做了与运算。0xff的十进制是255. zend_long c = Z_LVAL_P(zend_ast_get_zval(args->child[0])) & 0xff; result->op_type = IS_CONST; ZVAL_INTERNED_STR(&result->u.constant, ZSTR_CHAR(c)); return SUCCESS; } else { return FAILURE; } } 任何一个数字,与 0xff 做与运算,其结果不会大于255,是处于 ASCII 码表达的范围内的。 626&0xff=114, 114 对应的字母是 r。
看看这个函数的核心C代码实现:
如果你提供的
needle
参数不是字符串,则会调用php_needle_char
方法转换为参数对应的字符串,题目中就是626对应的ASCII字母为r
。你也可以用
chr(626)
看下输出的是不是r
。C源码: https://github.com/php/php-sr...
ASCII中并没有 626 这个值,那么为什么
chr
方法会将 626 转换成了r
呢? 看看C代码是如何实现的:任何一个数字,与 0xff 做与运算,其结果不会大于255,是处于 ASCII 码表达的范围内的。
626&0xff=114
, 114 对应的字母是r
。