ホームページ  >  記事  >  バックエンド開発  >  PHP ソース コードの読み取り: strpos、strstr、stripos、stristr 関数

PHP ソース コードの読み取り: strpos、strstr、stripos、stristr 関数

WBOY
WBOYオリジナル
2016-06-20 12:27:021030ブラウズ

github に PHP ソースコードに関するより詳細なコメントがあります。興味があれば、見てスターを付けてください。 PHP5.4のソースコードのアノテーション。追加された注釈は、コミット レコードを通じて表示できます。

strpos

mixed strpos ( string $haystack, mixed $needle [, int $offset = 0 ] )

offset を指定した場合は、offset 位置から検索を開始します。オフセットを負の値にすることはできません。

干し草の山で針が最初に出現した位置を返します。干し草の山で針が見つからない場合は FALSE を返します。

needle、needle が文字列でない場合は、整数値に変換され、その値の ASCII 文字が割り当てられます。以下の例を参照してください。

$str = "hello";$pos = strpos($str, 111);// 111的ASCII值是o,因此$pos = 4

strpos コアソースコード

if (Z_TYPE_P(needle) == IS_STRING) {     if (!Z_STRLEN_P(needle)) {          php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty needle");          RETURN_FALSE;     }     // 调用php_memnstr函数查找needle     found = php_memnstr(haystack + offset,                            Z_STRVAL_P(needle),                            Z_STRLEN_P(needle),                            haystack + haystack_len);     } else {          // 如果不是字符串,转换成数字并赋值为该数字的ASCII字符。          if (php_needle_char(needle, needle_char TSRMLS_CC) != SUCCESS) {               RETURN_FALSE;          }          //设置结束字符          needle_char[1] = 0;          found = php_memnstr(haystack + offset,                            needle_char,                            1,                            haystack + haystack_len);    }}

注意すべき点の 1 つは、needle が文字列でない場合、php_needle_char 関数が呼び出されて、needle を整数とその ASCII 値に変換することです。

検索関数

この関数は最終的に found を返し、php_memnstr 関数は検索メソッドを実装します。次に、php_memnstr 関数の動作を確認します。

#define php_memnstr zend_memnstr

php_memnstr は、関数 zend_memnstr のマクロ定義です。次のように zend_memnstr 関数を確認してください。

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次    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;}
最初の最適化。p が空の場合は、needle の最初の文字が p に表示されないことを意味します。この関数は大文字と小文字を区別します。

needle が haystack に存在しない場合は、FALSE を返します。

before_needle が true の場合は、 haystack 内で針が初めて出現する位置より前の文字列 🎜>strstr コアのソースコード

string strstr ( string $haystack, mixed $needle [, bool $before_needle = false ] ) 返回needle在haystack中第一次出现的位置到结束的字符串。

strstr 関数の前半strpos と似ていますが、strstr 関数は位置を見つけた後、strstr 関数を呼び出すときに渡される before_needle 変数を文字列として返す必要がある点が異なります。 🎜>

コアソースコード

if (found) {        // 计算出found的位置        found_offset = found - haystack;        if (part) {            RETURN_STRINGL(haystack, found_offset, 1);        } else {            RETURN_STRINGL(found, haystack_len - found_offset, 1);        }}

はい、見つかりましたphp_stristr から取得したので、引き続き php_stristr 関数を調べます。

この関数の機能は、文字列を小文字に変換し、php_mennstr 関数を呼び出して文字列内のニードルを見つけることです。

mixed stripos ( string $haystack, string $needle [, int $offset = 0 ] ) 不区分大小写的strpos。实现方式跟下面的类似,主要是使用一份拷贝然后将需要比较的字符串转换成小写字符后进行再进行查找。
概要

strpos/stripos は位置を返しますが、位置は 0 から計算されるため、検索の判断には === FALSE を使用する方が適しています。 🎜>

PHP のソース コードを読むことで、一方では特定の関数の具体的な実装原理を知ることができ、他方ではプログラミングの最適化を学ぶことができます。ソリューション。

この記事はこれで終わりです。まだ質問や提案がありましたら、オリジナルの記事ですので、何か間違っていることがあれば、お知らせください。記事内でお知らせします。

最後に、github 上の PHP ソース コードにさらに詳細な注釈を付けました。興味があれば、見てスターを付けてください。 PHP5.4のソースコードのアノテーション。追加された注釈は、コミット レコードを通じて表示できます。

string stristr ( string $haystack, mixed $needle [, bool $before_needle = false ] ) 不区分大小写的strstr。

著者がより良い記事を書くためのヒントを提供します。ありがとうございます!

著者に報酬を与える

著者がより良い記事を書けるようにサポートするためのヒント、ありがとう!

// 拷贝一份haystackhaystack_dup = estrndup(haystack, haystack_len);if (Z_TYPE_P(needle) == IS_STRING) {    char *orig_needle;    if (!Z_STRLEN_P(needle)) {        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty needle");        efree(haystack_dup);        RETURN_FALSE;    }    orig_needle = estrndup(Z_STRVAL_P(needle), Z_STRLEN_P(needle));    // 调用php_stristr函数找出orig_needle的值。    found = php_stristr(haystack_dup, orig_needle,    haystack_len, Z_STRLEN_P(needle));    efree(orig_needle);} else {    if (php_needle_char(needle, needle_char TSRMLS_CC) != SUCCESS) {        efree(haystack_dup);        RETURN_FALSE;    }    needle_char[1] = 0;    found = php_stristr(haystack_dup, needle_char,    haystack_len, 1);}if (found) {    found_offset = found - haystack_dup;    if (part) {        RETVAL_STRINGL(haystack, found_offset, 1);    } else {        RETVAL_STRINGL(haystack + found_offset, haystack_len - found_offset, 1);    }} else {    RETVAL_FALSE;}// 释放变量efree(haystack_dup);
支払い方法を選択してください

PHPAPI char *php_stristr(char *s, char *t, size_t s_len, size_t t_len){    php_strtolower(s, s_len);    php_strtolower(t, t_len);    return php_memnstr(s, t, t_len, s + s_len);} 

著者について: hoohack

働いている人ハードルーキー個人ホームページ · 私の記事 · 3 ·

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。