ホームページ > バックエンド開発 > PHPチュートリアル > PHP の strpos 関数の詳細な分析

PHP の strpos 関数の詳細な分析

不言
リリース: 2023-04-03 13:24:02
オリジナル
2177 人が閲覧しました

この記事の内容は、PHP の strpos 関数の詳細な分析を共有することです。内容は非常に詳細です。困っている友人は参照してください。お役に立てれば幸いです。

概要

strpos は、文字列が別の文字列内に存在するかどうかを判断するために PHP でよく使用されます。この記事では、strpos 関数とその実装について紹介します。 . .

strposApplication

<?php
/* strpos示例 */

// test
echo &#39;match:&#39;, strpos(&#39;xasfsdfbk&#39;, &#39;xasfsdfbk&#39;) !== false ? &#39;true&#39; : &#39;false&#39;, &#39;;&#39;, PHP_EOL;
echo &#39;match:&#39;, strpos(&#39;xasfsdfbk&#39;, &#39;fbk&#39;) !== false ? &#39;true&#39; : &#39;false&#39;, &#39;;&#39;, PHP_EOL;
echo &#39;match:&#39;, strpos(&#39;xasfsdfbk&#39;, &#39;xs&#39;) != false ? &#39;true&#39; : &#39;false&#39;, &#39;;&#39;, PHP_EOL;
echo &#39;match:&#39;, strpos(&#39;xasfsdfbk&#39;, &#39;sfs&#39;) !== false ? &#39;true&#39; : &#39;false&#39;, &#39;;&#39;, PHP_EOL;

// code
strpos(&#39;xasfsdfbk&#39;, &#39;sfs&#39;);
ログイン後にコピー
警告: strpos この関数はブール値 FALSE を返す場合がありますが、同等の値を返す場合もあります。 of FALSE の非ブール値。詳細については、「ブール型」の章をお読みください。この関数の戻り値は、=== 演算子を使用してテストする必要があります。

strpos シリーズ関数

mb* 関連関数も利用可能です。たとえば、mb_strpos はマルチバイトの安全な strpos() 操作を実行します。文字数に関して。

PHP(strpos) ソース コード

strpos(ext/standard/string.c)

  • PHP ソース コード アドレス

PHP_FUNCTION(strpos)
{
    zval *needle;
    zend_string *haystack;
    char *found = NULL;
    char  needle_char[2];
    zend_long  offset = 0;

#ifndef FAST_ZPP
    if (zend_parse_parameters(ZEND_NUM_ARGS(), "Sz|l", &haystack, &needle, &offset) == FAILURE) {
        return;
    }
#else
    ZEND_PARSE_PARAMETERS_START(2, 3)
        Z_PARAM_STR(haystack)
        Z_PARAM_ZVAL(needle)
        Z_PARAM_OPTIONAL
        Z_PARAM_LONG(offset)
    ZEND_PARSE_PARAMETERS_END();
#endif

    if (offset < 0) {
        offset += (zend_long)ZSTR_LEN(haystack);
    }
    if (offset < 0 || (size_t)offset > ZSTR_LEN(haystack)) {
        php_error_docref(NULL, E_WARNING, "Offset not contained in string");
        RETURN_FALSE;
    }

    if (Z_TYPE_P(needle) == IS_STRING) {
        if (!Z_STRLEN_P(needle)) {
            php_error_docref(NULL, E_WARNING, "Empty needle");
            RETURN_FALSE;
        }

        found = (char*)php_memnstr(ZSTR_VAL(haystack) + offset,
                            Z_STRVAL_P(needle),
                            Z_STRLEN_P(needle),
                            ZSTR_VAL(haystack) + ZSTR_LEN(haystack));
    } else {
        if (php_needle_char(needle, needle_char) != SUCCESS) {
            RETURN_FALSE;
        }
        needle_char[1] = 0;

        found = (char*)php_memnstr(ZSTR_VAL(haystack) + offset,
                            needle_char,
                            1,
                            ZSTR_VAL(haystack) + ZSTR_LEN(haystack));
    }

    if (found) {
        RETURN_LONG(found - ZSTR_VAL(haystack));
    } else {
        RETURN_FALSE;
    }
}
ログイン後にコピー

php_memnstr(main/php.h)

  • PHP ソース コード アドレス

#define php_memnstr zend_memnstr /* 338 line*/
ログイン後にコピー

zend_memnstr(Zend/zend_operators. h)

  • PHP ソース コード アドレス

/*
 * 此函数的作用是在haystack中查找needle,如果不存在返回null,如果存在,返回指向haystack中needle头字符的指针
 */
zend_memnstr(const char *haystack, const char *needle, size_t needle_len, const char *end)
{
    const char *p = haystack;
    const char ne = needle[needle_len-1];
    ptrdiff_t off_p;
    size_t off_s;

    if (needle_len == 1) {
        return (const char *)memchr(p, *needle, (end-p));
    }

    off_p = end - haystack;
    off_s = (off_p > 0) ? (size_t)off_p : 0;

    if (needle_len > off_s) {
        return NULL;
    }

    if (EXPECTED(off_s < 1024 || needle_len < 3)) {
        // 第一个优化,只查找end - needle_len次
        end -= needle_len;

        while (p <= end) {
            // 第二个优化,先判断字符串的开头和结尾是否一样再判断整个字符串
            if ((p = (const 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;
    } else {
        return zend_memnstr_ex(haystack, needle, needle_len, end);
    }
}
ログイン後にコピー

memchr(string.h)

  • Linuxカーネル バージョン - ソース コード アドレス

/*
头文件:#include <string.h>

定义函数:void * memchr(const void *s, char c, size_t n);

函数说明:memchr()从头开始搜寻s 所指的内存内容前n 个字节,直到发现第一个值为c 的字节,则返回指向该字节的指针。

返回值:如果找到指定的字节则返回该字节的指针,否则返回0。
*/

#ifndef __HAVE_ARCH_MEMCHR
void *memchr(const void *s, int c, size_t n)
{
    const unsigned char *p = s;
    while (n-- != 0) {
            if ((unsigned char)c == *p++) {
            return (void *)(p - 1);
        }
    }
    return NULL;
}
EXPORT_SYMBOL(memchr);
#endif
ログイン後にコピー

memcmp(string.h)

  • Linux カーネル バージョン - ソース アドレス

/* 字符串函数memcmp
   原型:extern int memcmp(void *buf1, void *buf2, unsigned int count); 
   功能:比较内存区域buf1和buf2的前count个字节
   说明:当buf1<buf2时,返回值<0  
         当buf1=buf2时,返回值=0   
         当buf1>buf2时,返回值>0                                        
*/
#ifndef __HAVE_ARCH_MEMCMP
#undef memcmp
__visible int memcmp(const void *cs, const void *ct, size_t count)
{
    const unsigned char *su1, *su2;
    int res = 0;

    for (su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
        if ((res = *su1 - *su2) != 0)
            break;
    return res;
}
EXPORT_SYMBOL(memcmp);
#endif
ログイン後にコピー

Tip

strpos 関数では大文字と小文字が区別されます。

関連する推奨事項:

PHP でのロック メカニズムの適用

php ID を暗号化する方法

以上がPHP の strpos 関数の詳細な分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
関数説明バージョン
strpos最初に出現した文字列を検索PHP 4、PHP 5、PHP 7
stripos文字列の最初の出現を検索します (大文字と小文字は区別されません)PHP 5、PHP 7
strrpos指定された文字を計算しますターゲット文字列内の文字列が最後に出現する位置PHP 4、PHP 5、PHP 7
strriposの位置を計算します。ターゲット文字列内の指定された文字列 文字列内の最後の出現位置 (大文字と小文字は区別されません)PHP 5、PHP 7
mb_strpos別の文字列内に出現する文字列を検索する 文字列内で最初に出現する文字列の位置PHP 4 >= 4.0.6, PHP 5, PHP 7
strstr 文字列の位置の検索 初出 PHP 4, PHP 5, PHP 7
stristr case- strstr() 関数のバージョンを無視します PHP 4、PHP 5、PHP 7
substr_count 文字列の出現数をカウントします PHP 4, PHP 5, PHP 7