• 0 رای - 0 میانگین
  • 1
  • 2
  • 3
  • 4
  • 5
رفتار غیرمنتظره تابع strripos
#1
در برنامم یه مشکل عجیب پیش اومده بود که با کلی دردسر ردش رو گرفتم آخر فهمیدم علتش زیر سر تابع strripos است!

تا اینجا اینقدر حدس زدم و تست کردم تا رسیدم به اینکه اگر مقدار پارامتر needle در این تابع یک رشتهء تک بایتی با مقدار اسکی بزرگتر از 127 باشه، تابع مقدار false برمیگردونه.

کد تست:

کد پی‌اچ‌پی:
<?php

error_reporting
(E_ALL);
ini_set('display_errors''1');

echo 
'strripos: ';
var_dump(strripos(chr(128), chr(128)));

echo 
'<br>strrpos: ';
var_dump(strrpos(chr(128), chr(128)));

echo 
'<br>strpos: ';
var_dump(strpos(chr(128), chr(128)));

echo 
'<br>stripos: ';
var_dump(stripos(chr(128), chr(128)));

?>

خروجی:
کد:
strripos:

boolean false


strrpos:

int 0


strpos:

int 0


stripos:

int 0

نمیدونم آیا این یک باگه یا چه علت دیگری میتونه داشته باشه!
  پاسخ
تشکر شده توسط :
#2
به نظر که باگه
(۱۳۹۴ تير ۰۲, ۰۲:۲۰ ق.ظ)vejmad نوشته: در برنامم یه مشکل عجیب پیش اومده بود که با کلی دردسر ردش رو گرفتم آخر فهمیدم علتش زیر سر تابع strripos است!

تا اینجا اینقدر حدس زدم و تست کردم تا رسیدم به اینکه اگر مقدار پارامتر needle در این تابع یک رشتهء تک بایتی با مقدار اسکی بزرگتر از 127 باشه، تابع مقدار false برمیگردونه.

کد تست:

کد پی‌اچ‌پی:
<?php

error_reporting
(E_ALL);
ini_set('display_errors''1');

echo 
'strripos: ';
var_dump(strripos(chr(128), chr(128)));

echo 
'<br>strrpos: ';
var_dump(strrpos(chr(128), chr(128)));

echo 
'<br>strpos: ';
var_dump(strpos(chr(128), chr(128)));

echo 
'<br>stripos: ';
var_dump(stripos(chr(128), chr(128)));

?>

خروجی:
کد:
strripos:

boolean false


strrpos:

int 0


strpos:

int 0


stripos:

int 0

نمیدونم آیا این یک باگه یا چه علت دیگری میتونه داشته باشه!
  پاسخ
تشکر شده توسط : vejmad
#3
کد:
echo 'strripos: ';
var_dump(  mb_strripos(chr(128), chr(128),0,'UTF-8')   );

echo '<br>strrpos: ';
var_dump(mb_strrpos(chr(128), chr(128),0,'UTF-8'));

echo '<br>strpos: ';
var_dump(mb_strpos(chr(128), chr(128),0,'UTF-8'));

echo '<br>stripos: ';
var_dump(mb_stripos(chr(128), chr(128),0,'UTF-8'));
اینطوری مشکل حل میشه، احتمالاً به خاطر مختلف بودن جدول های اسکی 8 بیتی هست، حالا چرا فقط تو این تابع! خدا میدونه...
هر که با مرغ هوا دوست شود - خوابش آرامترین خواب جهان خواهد بود.
  پاسخ
تشکر شده توسط : vejmad
#4
فرق strripos با strrpos فقط اینه که اولی به case حروف حساس نیست.
پس احتمالش زیاده مشکل به اونجا برمیگرده که این تابع در داخل خودش میاد و کاراکترهای needle و haystack رو هر دو به حروف بزرگ یا کوچک تغییر میده و بعد مقایسه میکنه، یا درواقع در همون جریان مقایسه بایت به بایت این کار رو صورت میده به هر شکلی. و بازم حدس میزنم که یجا توی این کار اومدن بهینه سازی خاصی بکنن که چیزی این وسط از زیر دستشون در رفته و پیشبینی نکرده بودن شاید یک شرطی چیزی نذاشتن یا بهرصورت درست عمل نمیکنه و فقط روی کاراکترهای عادی و استاندارد که کد اسکی زیر 128 دارن تست کردن و بنابراین متوجه این باگ نشدن. البته سختی کشف این باگ یکی هم بخاطر اینه که فقط در حالتی که needle تک بایتی باشه رخ میده و در بقیهء حالات این پدیده دیده نمیشه و تابع جواب درست میده.
خلاصه نمیدونم ولی فکر کنم یه چیزی توی این مایه ها باشه و ربطی به کدهای تغییر case در این تابع داشته باشه (و احتمالا بخاطر نوعی بهینه سازی سطح پایین در این مورد).
ضمنا میدونید که این توابع سورسشون در زبان سی هست.
  پاسخ
تشکر شده توسط :
#5
یه جایی خونده بودم که توی PHP 5 این تابع به همون تابع stripos اشاره می کنه، ولی مثل اینکه شواهد چیز دیگه ای میگه...
هر که با مرغ هوا دوست شود - خوابش آرامترین خواب جهان خواهد بود.
  پاسخ
تشکر شده توسط :
#6
بدین طریق به اطلاع عموم رساندیم: http://stackoverflow.com/questions/31017...s-function
خواه پند گیرند و خواه ملال Big Grin

دیگه وقت و حوصله Bug report پر کردن ندارم!
  پاسخ
تشکر شده توسط :


پرش به انجمن:


کاربران در حال بازدید این موضوع: 1 مهمان