php strripos 字符串查找函數內部源碼實現

和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; } /* }}} */
相關文章
相關標籤/搜索