تابع strtok() در PHP
تابع strtok() یکی از توابع مفید در PHP برای جدا کردن رشتهها به توکنها (قطعات) براساس مجموعهای از نویسههای جداکننده است. این تابع مشابه تابع strtok در زبان C عمل میکند و برای پردازش رشتههای بزرگ یا زمانی که میخواهید توکنها را بهصورت مرحلهای بدست آورید، بسیار مناسب است. در ادامه به نحوه کار، مثالهای کاربردی، محدودیتها و جایگزینها میپردازیم.
نحو و رفتار پایه
نحو تابع به صورت زیر است:
strtok(string $str, string $token): string|falseنکات کلیدی:
- در فراخوانی اول باید رشتهٔ اصلی و مجموعهٔ کاراکترهای جداکننده (token) را ارسال کنید.
- فراخوانیهای بعدی برای ادامهٔ پردازش باید strtok(NULL, $token) باشند تا پردازش از محل قبلی ادامه یابد.
- پارامتر token یک رشته است که هر یک از کاراکترهای آن بهعنوان جداکننده تفسیر میشوند — به عبارت دیگر مجموعهای از کاراکترها، نه یک زیررشته.
- تابع در پایان رشته مقدار boolean false بازمیگرداند.
مثال ساده
$str = "Hello, world; this:is a-test";
$tok = strtok($str, " ,;:-");
while ($tok !== false) {
echo $tok . PHP_EOL;
$tok = strtok(NULL, " ,;:-");
}در این مثال ابتدا رشته وارد میشود و مجموعه جداکننده شامل فاصله و علائم نگارشی مختلف است. با حلقه while و فراخوانی strtok(NULL, …) توکنها یکییکی خوانده و چاپ میشوند. strtok توکنهای خالی را بین جداکنندههای متوالی تولید نمیکند (یعنی چند جداکنندهٔ پشتسرهم مانند چند فاصله باعث تولید توکن خالی نمیشود).
کاربردها و مزایا
- پردازش مرحلهای رشتههای بزرگ بدون ساختن آرایه کامل از توکنها (حافظه کمتر نسبت به explode در برخی موارد).
- وقتی نیاز دارید توکنها را یکییکی مصرف کنید یا پردازش سنگین روی هر توکن انجام دهید.
- قابلیت تغییر مجموعه جداکننده در فراخوانیهای بعدی (با ارسال NULL به عنوان رشته) برای حالتهای پیچیدهتر.
مقایسه با توابع دیگر
| تابع | رفتار اصلی | مناسب برای |
|---|---|---|
| strtok() | توکندهی مرحلهای بر اساس مجموعهٔ کاراکترها | خواندن توکنها یکییکی، حافظه کمتر |
| explode() | تقسیم بر اساس زیررشته دقیق | وقتی جداکننده دقیق و ثابتی دارید و نیاز به آرایه کامل دارید |
| preg_split() | تقسیم بر اساس الگوی regex (قابل تنظیم بسیار) | زمانی که نیاز به کنترل پیچیدهتر، پشتیبانی از یونیکد یا فیلتر کردن توکنهای خالی دارید |
| str_getcsv()/fgetcsv() | تحلیل CSV با قواعد مخصوص | وقتی دادهها بهصورت CSV هستند |
نکات مهم و محدودیتها
- token بهعنوان مجموعهای از کاراکترها تعبیر میشود؛ اگر جداکننده شما زیررشته چندکاراکتری است (مثلاً “–>”)، strtok کارآمد نیست. برای این حالت از explode یا preg_split استفاده کنید.
- strtok با رشتههای چندبایتی (UTF-8) ممکن است رفتار ناخواسته داشته باشد، زیرا بر بایتها کار میکند. اگر از کاراکترهای یونیکد بهعنوان جداکننده استفاده میکنید، از preg_split با پرچم /u یا کتابخانهٔ mbstring بهره ببرید.
- تابع توکنهای خالی میان جداکنندههای متوالی را بازنمیگرداند؛ اگر نیاز به نگهداری توکنهای خالی دارید، از explode استفاده کنید یا از preg_split با گزینهٔ مناسب بهره ببرید.
- strtok از وضعیت داخلی استفاده میکند؛ بنابراین همزمان در دو مکان مختلف روی یک رشته خاص استفادهٔ تو در تو میتواند منجر به نتایج ناپایدار شود. برای پردازش همزمان یا بازگشتی، بهتر است از preg_split یا explode استفاده کنید.
مثال پیشرفته — تغییر جداکننده در میانهٔ پردازش
$s = "a,b;c|d e";
$tok = strtok($s, ",;");
while ($tok !== false) {
echo $tok . PHP_EOL;
// حالا میخواهیم جداکنندهها را تغییر دهیم
$tok = strtok(NULL, "| ");
}در این کد ابتدا جداکنندهها کاما و سمیکالن هستند و سپس با فراخوانی strtok(NULL, “| “) مجموعهٔ جداکننده تغییر میکند و پردازش ادامه مییابد. این انعطاف مفید است اما باید مراقب وضعیت داخلی تابع باشید تا به هم نریزد.
مثال مقایسه رفتار strtok و explode
$s = "one,,two,,three";
$tokens_explode = explode(",", $s);
$tokens_strtok = [];
$tok = strtok($s, ",");
while ($tok !== false) {
$tokens_strtok[] = $tok;
$tok = strtok(NULL, ",");
}
var_dump($tokens_explode);
var_dump($tokens_strtok);در خروجی میبینید explode توکنهای خالی بین کاماها را حفظ میکند، اما strtok آنها را حذف میکند. بنابراین هنگام انتخاب تابع به این تفاوت دقت کنید.
راهنمای کاربردی و بهترین شیوهها
- اگر میخواهید توکنها را یکبهیک بخوانید و حافظه اهمیت دارد، strtok انتخاب مناسبی است.
- برای دادههای CSV از توابع مخصوص CSV استفاده کنید، نه strtok.
- برای پشتیبانی از یونیکد یا جداکنندههای چندکاراکتری از preg_split یا explode استفاده کنید.
- از strtok در کدهای همزمان یا بازگشتی که نیاز به وضعیت مستقل دارند، اجتناب کنید؛ وضعیت داخلی آن میتواند منجر به باگ شود.
نتیجهگیری
strtok() یک ابزار ساده و قدرتمند برای توکندهی مرحلهای در PHP است که در موارد مشخصی مزیتهای حافظهای و کارایی دارد. با این حال محدودیتهایی مانند عدم پشتیبانی بومی از یونیکد و رفتار بر اساس کاراکترهای جداکننده وجود دارد. با شناخت دقیق نیازهای خود (آیا جداکننده زیررشته است، آیا توکنهای خالی مهماند، آیا یونیکد مورد استفاده است) میتوانید بهترین تابع از بین strtok، explode، preg_split یا توابع CSV را انتخاب کنید.
آیا این مطلب برای شما مفید بود ؟



