1 PHP_FUNCTION(strpos)
2 {
3 zval *needle;
4 zend_string *haystack;
5 char *found = NULL;
6 char needle_char[2];
7 zend_long offset = 0; // 搜索位置默认0
8
9 ZEND_PARSE_PARAMETERS_START(2, 3)
10 Z_PARAM_STR(haystack)
11 Z_PARAM_ZVAL(needle)
12 Z_PARAM_OPTIONAL
13 Z_PARAM_LONG(offset)
14 ZEND_PARSE_PARAMETERS_END();
15
16 /* 如果搜索起始位置offset<0, 则转换一下 */
17 if (offset < 0) {
18 offset += (zend_long)ZSTR_LEN(haystack);
19 }
20 /* 如果转换之后 offset<0 或 offset大于(待查找字符串的长度),则待查找字符串中根本就没有这个位置*/
21 if (offset < 0 || (size_t)offset > ZSTR_LEN(haystack)) {
22 php_error_docref(NULL, E_WARNING, "Offset not contained in string");
23 RETURN_FALSE;
24 }
25
26 /* 搜索 */
27 if (Z_TYPE_P(needle) == IS_STRING) { // needle是字符串
28 /* needle长度为0,则报错 */
29 if (!Z_STRLEN_P(needle)) {
30 php_error_docref(NULL, E_WARNING, "Empty needle");
31 RETURN_FALSE;
32 }
33 /* 具体的搜索实现 */
34 found = (char*)php_memnstr(ZSTR_VAL(haystack) + offset,
35 Z_STRVAL_P(needle),
36 Z_STRLEN_P(needle),
37 ZSTR_VAL(haystack) + ZSTR_LEN(haystack));
38 } else {
39 if (php_needle_char(needle, needle_char) != SUCCESS) {
40 RETURN_FALSE;
41 }
42 needle_char[1] = 0;
43
44 found = (char*)php_memnstr(ZSTR_VAL(haystack) + offset,
45 needle_char,
46 1,
47 ZSTR_VAL(haystack) + ZSTR_LEN(haystack));
48 }
49
50 if (found) {
51 RETURN_LONG(found - ZSTR_VAL(haystack));
52 } else {
53 RETURN_FALSE;
54 }
55 }