和stripos實現不相同,除開查找方式不同即返回的地址不同外,我的感受strripos比stripos的實如今條件判斷上更好(看strripos函數的判斷,綠色字體的地方)。 php
/* {{{ proto int strripos(string haystack, string needle [, int offset]) 函數
Finds position of last occurrence of a string within another string */
PHP_FUNCTION(strripos)
{
zval *zneedle;
char *needle, *haystack;
int needle_len, haystack_len;
long offset = 0;
char *p, *e, ord_needle[2];
char *needle_dup, *haystack_dup;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|l", &haystack, &haystack_len, &zneedle, &offset) == FAILURE) {
RETURN_FALSE;
}
if (Z_TYPE_P(zneedle) == IS_STRING) {
needle = Z_STRVAL_P(zneedle);
needle_len = Z_STRLEN_P(zneedle);
} else {
if (php_needle_char(zneedle, ord_needle TSRMLS_CC) != SUCCESS) {
RETURN_FALSE;
}
ord_needle[1] = '\0';
needle = ord_needle;
needle_len = 1;
}
if ((haystack_len == 0) || (needle_len == 0)) {
RETURN_FALSE;
}
if (needle_len == 1) {
/* Single character search can shortcut memcmps
Can also avoid tolower emallocs */
if (offset >= 0) {
if (offset > haystack_len) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Offset is greater than the length of haystack string");
RETURN_FALSE;
}
p = haystack + offset;
e = haystack + haystack_len - 1;
} else {
p = haystack;
if (offset < -INT_MAX || -offset > haystack_len) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Offset is greater than the length of haystack string");
RETURN_FALSE;
}
e = haystack + haystack_len + offset;
} /* Borrow that ord_needle buffer to avoid repeatedly tolower()ing needle */ *ord_needle = tolower(*needle); while (e >= p) { if (tolower(*e) == *ord_needle) { RETURN_LONG(e - p + (offset > 0 ? offset : 0)); } e--; } RETURN_FALSE; } needle_dup = estrndup(needle, needle_len); php_strtolower(needle_dup, needle_len); haystack_dup = estrndup(haystack, haystack_len); php_strtolower(haystack_dup, haystack_len); if (offset >= 0) { if (offset > haystack_len) { efree(needle_dup); efree(haystack_dup); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Offset is greater than the length of haystack string"); RETURN_FALSE; } p = haystack_dup + offset; e = haystack_dup + haystack_len - needle_len; } else { if (offset < -INT_MAX || -offset > haystack_len) { efree(needle_dup); efree(haystack_dup); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Offset is greater than the length of haystack string"); RETURN_FALSE; } p = haystack_dup; if (needle_len > -offset) { e = haystack_dup + haystack_len - needle_len; } else { e = haystack_dup + haystack_len + offset; } } while (e >= p) { if (memcmp(e, needle_dup, needle_len) == 0) { efree(haystack_dup); efree(needle_dup); RETURN_LONG(e - p + (offset > 0 ? offset : 0)); } e--; } efree(haystack_dup); efree(needle_dup); RETURN_FALSE; } /* }}} */