ویژگی تصویر

تابع stripos() در PHP

  /  PHP   /  تابع stripos() در PHP
بنر تبلیغاتی الف
آموزش PHP

تابع stripos() یکی از توابع کاربردی در PHP برای جستجوی یک زیررشته داخل رشته‌ای دیگر به‌صورت غیر حساس به حروف بزرگ و کوچک (case-insensitive) است. این تابع موقعیت اولین وقوع زیررشته را به صورت یک عدد صحیح (اندیس صفر‑مبنای بایت) برمی‌گرداند یا در صورت پیدا نشدن مقدار false را بازمی‌گرداند.

امضای تابع و مقدار بازگشتی

امضاint|false stripos(string $haystack, string $needle, int $offset = 0)
شرحجستجوی needle در haystack از موقعیت offset (اختیاری).
مقدار بازگشتیاندیس اولین وقوع (عدد صحیح >= 0) یا false اگر پیدا نشد.

نکات مهم و مسائل رایج

  • اندیس بازگردانده‌شده صفر-مبنایی است؛ یعنی اگر زیررشته در ابتدای رشته باشد مقدار 0 برمی‌گردد.
  • برای تشخیص اینکه زیررشته پیدا نشده، حتماً از مقایسه سخت (=== false) استفاده کنید؛ استفاده از == باعث اشتباه می‌شود چون 0 == false برقرار است.
  • تابع byte‑safe است و برای رشته‌های UTF-8 چندبایتی مناسب نیست؛ در آن موارد از mb_stripos استفاده کنید.
  • پارامتر $offset از PHP 7.1 به بعد می‌تواند عدد منفی هم باشد (شروع جستجو از انتهای رشته).

مثال‌های عملی

// مثال 1: جستجوی ساده (case-insensitive)
$haystack = "Hello World";
$needle = "world";

$pos = stripos($haystack, $needle);

if ($pos === false) {
    echo "Not found";
} else {
    echo "Found at position: $pos"; // خروجی: Found at position: 6
}

در این نمونه، تابع stripos زیررشته “world” را در “Hello World” پیدا می‌کند و اندیس 6 را برمی‌گرداند. توجه کنید که از مقایسه === false برای تشخیص عدم وجود استفاده شده است.

// مثال 2: اشتباه متداول با مقایسه == 
$haystack = "Apple";
$needle = "apple";

if (stripos($haystack, $needle) == false) {
    echo "Not found (WRONG)";
} else {
    echo "Found (WRONG)";
}
// این کد اشتباه است؛ چون مقدار برگردانده‌شده 0 است و 0 == false => true

این مثال نشان می‌دهد که استفاده از == می‌تواند باعث شود وقوع در ابتدای رشته به عنوان “پیدا نشد” تفسیر شود. همیشه از مقایسه نوع‌محور === استفاده کنید.

// مثال 3: پیدا کردن همه رخدادها با استفاده از offset
$haystack = "banana";
$needle = "an";
$offset = 0;
$positions = [];

while (($pos = stripos($haystack, $needle, $offset)) !== false) {
    $positions[] = $pos;
    $offset = $pos + 1; // ادامه جستجو پس از موقعیت فعلی
}

print_r($positions); // خروجی: Array ( [0] => 1 [1] => 3 )

در این کد، از حلقه استفاده شده تا همهٔ موقعیت‌های زیررشته “an” در “banana” پیدا شوند. توجه داشته باشید که برای جلوگیری از تکرار بین موقعیت‌ها، مقدار $offset هر بار یک واحد افزایش می‌یابد.

ملاحظات مربوط به چندبایتی (UTF-8)

توابع stripos و strpos بر بایت‌ها عمل می‌کنند، بنابراین برای رشته‌های UTF-8 ممکن است نتایج نامطلوب یا اندیس‌هایی برحسب بایت (نه کاراکتر) دریافت کنید. اگر با متون فارسی یا سایر کاراکترهای چندبایتی سر و کار دارید، از توابع mbstring استفاده کنید:

// مثال 4: استفاده از mb_stripos برای UTF-8
$haystack = "سلام دنیا";
$needle = "دنیا";

$pos = mb_stripos($haystack, $needle, 0, 'UTF-8');

if ($pos === false) {
    echo "Not found";
} else {
    echo "Found at position (characters): $pos";
}

در اینجا mb_stripos اندیس را بر حسب کاراکتر باز می‌گرداند و برای رشته‌های UTF-8 مناسب است. توجه کنید که ممکن است لازم باشد اکستنشن mbstring روی سرور فعال باشد.

عملکرد و جایگزین‌ها

  • برای جستجوی ساده و مستقیم، stripos سریع‌تر و سبک‌تر از یک preg_match است.
  • اگر نیاز به الگوهای پیچیده دارید یا جستجوی با قواعد regex می‌خواهید، از preg_match یا توابع مشابه استفاده کنید؛ ولی برای یک substring ثابت خیر.
  • برای پشتیبانی از چندبایتی و مقایسه بر اساس زبان، mb_stripos یا توابع ICU/mb_* مناسب‌ترند.

مثال مقایسه عملکرد (موقت)

در بارگذاری‌های بزرگ و جستجوهای تکراری، استفاده از stripos نسبت به regex هزینهٔ پردازشی کمتر دارد. اگر با هزاران جستجو در رشته‌های بلند مواجهید، بهتر است قبل از انتخاب به‌صورت عملی تست کنید و پروفایل بگیرید.

موارد لبه‌ای و نکات ایمنی

  • اگر مقدار $needle خالی باشد، رفتار تابع در نسخه‌های مختلف PHP متفاوت بوده است؛ معمولاً stripos مقدار 0 برمی‌گرداند (زیررشتهٔ خالی همیشه در موقعیت صفر قرار می‌گیرد)، اما بهتر است قبل از فراخوانی تابع، وجود زیررشته را چک کنید.
  • در مقابل SQL injection یا XSS تابعی برای پاکسازی نیست؛ این تابع فقط جستجو می‌کند و نباید برای پاکسازی داده‌ها استفاده شود.
  • مقایسه نوع‌محور هنگام بررسی نتیجه الزامی است: if (stripos(...) !== false).

خلاصه و توصیه‌های کاربردی

  • از stripos برای جستجوی سریع و case-insensitive بین رشته‌ها استفاده کنید.
  • برای رشته‌های UTF-8 و زبان‌های غیرلاتین از mb_stripos استفاده کنید.
  • همیشه نتیجه را با === false یا !== false بررسی کنید تا خطاهای منطقی جلوگرفته شود.
  • در صورت جستجوهای پیچیده یا نیاز به الگو، regex انتخاب مناسب‌تری است، اما هزینهٔ بیشتری دارد.

با رعایت نکات بالا می‌توانید از stripos() به شکلی امن و مؤثر در پروژه‌های PHP خود استفاده کنید و از اشتباهات رایج در مقایسه و رشته‌های چندبایتی جلوگیری کنید.

آیا این مطلب برای شما مفید بود ؟

خیر
بله
موضوعات شما در انجمن: