欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

PHP?strstr函數(shù)原型源碼分析

 更新時(shí)間:2023年06月05日 09:55:52   作者:zzMeow  
這篇文章主要為大家介紹了PHP?strstr函數(shù)原型源碼分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

strstr

函數(shù)原型

源碼分析 版本PHP5.3.29

1、ext/standard/php_string.h

PHP_FUNCTION(strstr);

2、ext/standard/string.c

PHP_FUNCTION(strstr)
{
    zval *needle;
    char *haystack;
    int haystack_len;
    char *found = NULL;
    char needle_char[2];
    long found_offset;
    zend_bool part = 0;
    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|b", &haystack, &haystack_len, &needle, &part) == FAILURE) {
        return;
    }
    if (Z_TYPE_P(needle) == IS_STRING) {
        if (!Z_STRLEN_P(needle)) {
            php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty delimiter");
            RETURN_FALSE;
        }
        found = php_memnstr(haystack, Z_STRVAL_P(needle), Z_STRLEN_P(needle), haystack + haystack_len);
    } else {
        if (php_needle_char(needle, needle_char TSRMLS_CC) != SUCCESS) {
            RETURN_FALSE;
        }
        needle_char[1] = 0;
        found = php_memnstr(haystack, needle_char,    1, haystack + haystack_len);
    }
    if (found) {
        found_offset = found - haystack;
        if (part) {
            RETURN_STRINGL(haystack, found_offset, 1);
        } else {
            RETURN_STRINGL(found, haystack_len - found_offset, 1);
        }
    }
    RETURN_FALSE;
}

zval *needle

文件位置 Zend/zend.h

typedef struct _zval_struct zval;
struct _zval_struct {
    /* Variable information */
    zvalue_value value;        /* value */
    zend_uint refcount__gc;
    zend_uchar type;    /* active type */
    zend_uchar is_ref__gc;
};

needle是一個(gè)變量結(jié)構(gòu)體,對(duì)應(yīng)php strstr 函數(shù)參數(shù) mixed $needle

1、char *haystack

char *haystack s是一個(gè)字符指針,對(duì)應(yīng) php strstr函數(shù)參數(shù) string $haystack

2、zend_parse_parameters

文件位置 Zend/zend_API.c

int zend_parse_parameters(int num_args TSRMLS_DC, char *type_spec, ...);
int zend_parse_parameters_ex(int flags, int num_args TSRMLS_DC, char *type_spec, ...);
ZEND_API int zend_parse_parameters(int num_args TSRMLS_DC, char *type_spec, ...) /* {{{ */
{
    va_list va;
    int retval;
    RETURN_IF_ZERO_ARGS(num_args, type_spec, 0);
    va_start(va, type_spec);
    retval = zend_parse_va_args(num_args, type_spec, &va, 0 TSRMLS_CC);
    va_end(va);
    return retval;
}
/* }}} */
ZEND_API int zend_parse_method_parameters(int num_args TSRMLS_DC, zval *this_ptr, char *type_spec, ...) /* {{{ */
{
    va_list va;
    int retval;
    char *p = type_spec;
    zval **object;
    zend_class_entry *ce;
    if (!this_ptr) {
        RETURN_IF_ZERO_ARGS(num_args, p, 0);
        va_start(va, type_spec);
        retval = zend_parse_va_args(num_args, type_spec, &va, 0 TSRMLS_CC);
        va_end(va);
    } else {
        p++;
        RETURN_IF_ZERO_ARGS(num_args, p, 0);
        va_start(va, type_spec);
        object = va_arg(va, zval **);
        ce = va_arg(va, zend_class_entry *);
        *object = this_ptr;
        if (ce && !instanceof_function(Z_OBJCE_P(this_ptr), ce TSRMLS_CC)) {
            zend_error(E_CORE_ERROR, "%s::%s() must be derived from %s::%s",
                ce->name, get_active_function_name(TSRMLS_C), Z_OBJCE_P(this_ptr)->name, get_active_function_name(TSRMLS_C));
        }
        retval = zend_parse_va_args(num_args, p, &va, 0 TSRMLS_CC);
        va_end(va);
    }
    return retval;
}

最簡(jiǎn)單的獲取函數(shù)調(diào)用者傳遞過來的參數(shù)便是使用zend_parse_parameters()函數(shù)。

zend_parse_parameters() 函數(shù)的前幾個(gè)參數(shù)我們直接用內(nèi)核里宏來生成便可以了,形式為:ZEND_NUM_ARGS() TSRMLS_CC,注意兩者之間有個(gè)空格,但是沒有逗號(hào)。從名字可以看出,ZEND_NUM_ARGS()代表著參數(shù)的個(gè)數(shù)。

緊接著需要傳遞給zend_parse_parameters()函數(shù)的參數(shù)是一個(gè)用于格式化的字符串,就像printf的第一個(gè)參數(shù)一樣。下面表示了最常用的幾個(gè)符號(hào)。

type_spec是格式化字符串,其常見的含義如下:
參數(shù)   代表著的類型
b    Boolean
l    Integer 整型
d    Floating point 浮點(diǎn)型
s    String 字符串
r    Resource 資源
a    Array 數(shù)組
o    Object instance 對(duì)象
O    Object instance of a specified type 特定類型的對(duì)象
z    Non-specific zval 任意類型~
Z    zval**類型
f    表示函數(shù)、方法名稱,PHP5.1里貌似木有... ...

3、if (Z_TYPE_P(needle) == IS_STRING)

Z_TYPE_P
文件位置:Zend/zend_operators.h
#define Z_TYPE_P(zval_p)    Z_TYPE(*zval_p)
#define Z_TYPE(zval)        (zval).type

4、if (!Z_STRLEN_P(needle)) {

Z_STRLEN_P
文件位置:Zend/zend_operators.h
#define Z_STRLEN_P(zval_p)        Z_STRLEN(*zval_p)
#define Z_STRLEN(zval)            (zval).value.str.len

5、php_memnstr(haystack, Z_STRVAL_P(needle), Z_STRLEN_P(needle), haystack + haystack_len);

文件位置:main/php.h
#define php_memnstr zend_memnstr
文件位置:Zend/zend_operators.h
static inline char *
zend_memnstr(char *haystack, char *needle, int needle_len, char *end)
{
    char *p = haystack;
    char ne = needle[needle_len-1];
    if (needle_len == 1) {
        return (char *)memchr(p, *needle, (end-p));
    }
    if (needle_len > end-haystack) {
        return NULL;
    }
    end -= needle_len;
    while (p <= end) {
        if ((p = (char *)memchr(p, *needle, (end-p+1))) && ne == p[needle_len-1]) {
            if (!memcmp(needle, p, needle_len-1)) {
                return p;
            }
        }
        if (p == NULL) {
            return NULL;
        }
        p++;
    }
    return NULL;
}

核心函數(shù)

memchr memcmp

zend_memnstr 代碼分析

舉例:

strstr('hello word!','world');
zend_memnstr(char *haystack, char *needle, int needle_len, char *end)
char *haystack = "hello word!";
char *needle = "world";
int needle_len = strlen(needle);
char *end = haystack + strlen(haystack) 尾部指針
char *p = haystack 字符首元素地址
char ne = needle[needle_len-1] needle 尾部單個(gè)字符 d
end -= needle_len  // 初始:4231185 減后:4231180
(p = (char *)memchr(p, *needle, (end-p+1))) && ne == p[needle_len-1]
p = (char *)memchr(p, *needle, (end-p+1) // char *p = "world!";
ne == p[needle_len-1] // p[needle_len-1] == d
if (!memcmp(needle, p, needle_len-1)) //world == world
return p

引用

https://www.runoob.com/cprogramming/c-function-memcmp.html

http://www.dbjr.com.cn/article/77667.htm

http://www.dbjr.com.cn/article/210253.htm

以上就是PHP strstr源碼分析的詳細(xì)內(nèi)容,更多關(guān)于PHP strstr的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • php curl常用的5個(gè)經(jīng)典例子

    php curl常用的5個(gè)經(jīng)典例子

    下面小編就為大家?guī)硪黄猵hp curl常用的5個(gè)經(jīng)典例子。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-01-01
  • php獲取文件名稱和擴(kuò)展名的方法

    php獲取文件名稱和擴(kuò)展名的方法

    本篇文章主要介紹了php獲取文件名稱和擴(kuò)展名的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-02-02
  • php計(jì)算當(dāng)前程序執(zhí)行時(shí)間示例

    php計(jì)算當(dāng)前程序執(zhí)行時(shí)間示例

    這篇文章主要介紹了php計(jì)算當(dāng)前程序執(zhí)行時(shí)間示例,需要的朋友可以參考下
    2014-04-04
  • php判斷用戶是否關(guān)注微信公眾號(hào)

    php判斷用戶是否關(guān)注微信公眾號(hào)

    這篇文章主要為大家詳細(xì)介紹了php判斷用戶是否關(guān)注微信公眾號(hào),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-07-07
  • 在PHP中靈活使用foreach+list處理多維數(shù)組的方法

    在PHP中靈活使用foreach+list處理多維數(shù)組的方法

    這篇文章主要介紹了在PHP中靈活使用foreach+list處理多維數(shù)組的方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-01-01
  • Laravel5.1 框架關(guān)聯(lián)模型之后操作實(shí)例分析

    Laravel5.1 框架關(guān)聯(lián)模型之后操作實(shí)例分析

    這篇文章主要介紹了Laravel5.1 框架關(guān)聯(lián)模型之后操作,結(jié)合實(shí)例形式分析了laravel5.1框架寫入關(guān)聯(lián)模型、更新關(guān)聯(lián)關(guān)系等相關(guān)操作技巧與注意事項(xiàng),需要的朋友可以參考下
    2020-01-01
  • 微信公眾平臺(tái)開發(fā)之配置與請(qǐng)求

    微信公眾平臺(tái)開發(fā)之配置與請(qǐng)求

    微信公眾平臺(tái)是騰訊公司在微信的基礎(chǔ)上新增的功能模塊,通過這一平臺(tái),個(gè)人和企業(yè)都可以打造一個(gè)微信的公眾號(hào),并實(shí)現(xiàn)和特定群體的文字、圖片、語(yǔ)音的全方位溝通、互動(dòng)。本文給大家介紹微信公眾平臺(tái)開發(fā)之配置與請(qǐng)求,需要的朋友可以參考下
    2015-08-08
  • laravel框架語(yǔ)言包拓展實(shí)現(xiàn)方法分析

    laravel框架語(yǔ)言包拓展實(shí)現(xiàn)方法分析

    這篇文章主要介紹了laravel框架語(yǔ)言包拓展實(shí)現(xiàn)方法,結(jié)合實(shí)例形式分析了laravel語(yǔ)言包的具體配置與使用方法,需要的朋友可以參考下
    2019-11-11
  • PHP調(diào)用VC編寫的COM組件實(shí)例

    PHP調(diào)用VC編寫的COM組件實(shí)例

    最近項(xiàng)目需要PHP來解析二進(jìn)制數(shù)據(jù),如果直接PHP做比較麻煩,就想到VC編寫COM組件來做,提供PHP調(diào)用。文章將介紹VC編寫COM組件提供PHP調(diào)用,實(shí)現(xiàn)一個(gè)計(jì)算兩個(gè)數(shù)字相加的功能
    2014-03-03
  • PHP基于yii框架實(shí)現(xiàn)生成ICO圖標(biāo)

    PHP基于yii框架實(shí)現(xiàn)生成ICO圖標(biāo)

    本文給大家分享了2則php生成ICO圖標(biāo)的代碼,第一款是基于YII框架實(shí)現(xiàn)的,第二款是純php編寫,都非常的不錯(cuò),有需要的小伙伴可以參考下
    2015-11-11

最新評(píng)論