-
رفتار دردسرساز switch
تست:
<?php
$v=0;
switch($v) {
case 'hello':
echo 'hello';
break;
case 'goodbye':
echo 'goodbye';
break;
default:
echo 'default';
break;
}
?>
خروجی: hello
این رفتار غیرمنتظره switch دیشب در برنامم یه باگ ایجاد کرده بود که قدم به قدم تست کردم تا رسیدم به switch و فهمیدم جریان چیه!
من switch رو به این شکل تغییر دادم تا دیگه نظیر چنین مواردی رخ ندن:
<?php
$v=0;
switch("$v") {
case 'hello':
echo 'hello';
break;
case 'goodbye':
echo 'goodbye';
break;
default:
echo 'default';
break;
}
?>
-
نقل قول: رفتار دردسرساز switch
این if و else هم همین مشکل رو دارن!
-
نقل قول: رفتار دردسرساز switch
البته با عملگر == این مشکل رو داره نه با ===
-
نقل قول: رفتار دردسرساز switch
من نمیخواستم از === استفاده کنم، چون گاهی ممکن بود یک رشته بهش بدم و گاهی هم مثل همین مثال یک عدد باشه. یعنی اینطوری انعطاف بیشتری داره.
نقل قول:
این if و else هم همین مشکل رو دارن!
راست میگی عجیبه ها!
var_dump('hello'==0);
true میده!
بنظر میرسه دوباره PHP گند زده :لبخند:
من تنها چیزی به این عجیبی و بدی که یادم هست ویژگی «رجیستر گلوبالز» بود.
اون زمان وقتی این ویژگی احمقانه رو دیدم و با دردسرهای امنیتی بزرگی که ایجاد میکرد مواجه شدم، مطمئن شدم که طراحانش یجورایی ناشی بودن!
الانم ظاهرا همون داستان داره به شکل دیگری تکرار میشه.
آخه چه وضعشه، انعطاف و زبان سطح بالا و دینامیک تایپ درست، ولی دیگه نه در این حد چیزهای عجیب و غیرمنتظره که میتونن براحتی باگ و مسائل امنیتی پنهان ایجاد کنن!
آدم به زبان برنامه نویسی هم نتونه اعتماد کنه دیگه سنگ روی سنگ بند نمیشه!!
-
نقل قول: رفتار دردسرساز switch
چه میکنه این php, مسی...
$v = 1;
$v = settype($v, 'null'); // object - float - integer ... (only for 0)
if($v == 'hello'){
echo 'hello';
}
elseif($v === 'goodbye'){
echo 'goodbye';
}
else{
echo 'no';
}
-
نقل قول: رفتار دردسرساز switch
این مسئله چیز خاصی نیست و PHP هم به قول شما گند نزده! مسئله اینه که ازنظر عملگر == رشته 'hello' و عدد 0 با هم برابر هستن. چرا؟ چون موقع تبدیل نوع رشته هایی که با عدد شروع نشه، مساوی صفر درنظر گرفته میشه ولی اگه با عدد شروع بشه، تا جایی که بتونه رو جدا میکنه و بقیه رو حذف میکنه. مثلاً '25hello' برابر با عدد 25 میشه. توی سایتش هم اشاره کرده (لینک) :
بهتره برای موارد اینچنین، از عملگر === استفاده کنید یا اینکه قبلش با یک if جداگانه، درصورت عددی بودن متغیر، اصلاً وارد switch نشین یا هر راهکار دیگه که مدنظرتونه.
-
نقل قول: رفتار دردسرساز switch
خب حالت جا اومد ؟ :بامزه: تا تو باشی یه متغیر رشته ای رو با 0 مقدار دهی نکنی :لبخند:
اینم میشد : $v="";
-
نقل قول: رفتار دردسرساز switch
جناب شهرکی پس اینی که مقدارش 1 میشه چی؟
$v = 1;
$v = settype($v, 'null');
echo $v.'<br>';
if($v == 'hello'){
echo 'hello';
}
elseif($v === 'goodbye'){
echo 'goodbye';
}
else{
echo 'no';
}
1 و hello که برابر نیست!
-
نقل قول: رفتار دردسرساز switch
نقل قول:
نوشته شده توسط
MMSHFE
این مسئله چیز خاصی نیست و PHP هم به قول شما گند نزده! مسئله اینه که ازنظر عملگر == رشته 'hello' و عدد 0 با هم برابر هستن. چرا؟ چون موقع تبدیل نوع رشته هایی که با عدد شروع نشه، مساوی صفر درنظر گرفته میشه ولی اگه با عدد شروع بشه، تا جایی که بتونه رو جدا میکنه و بقیه رو حذف میکنه. مثلاً '25hello' برابر با عدد 25 میشه. توی سایتش هم اشاره کرده (
لینک) :
مهندس اینا که گفتی همه توجیه بودن و یجورایی انگار طرز پیاده سازیش رو گفتید یا اینکه انگار یه محدودیت فنی در این زمینه وجود داره.
ما در سطح منطقی و انتظار برنامه نویس و امنیت برنامه باید بهش نگاه کنیم، و این زبان برنامه نویسی است که باید خودش رو با این انتظار تطبیق بده. شاید بخصوص که یک زبان برنامه نویسی سطح بالا باشه!
شما در کدام زبان دیگری چنین چیز عجیبی میبینید؟
چرا واسه اونا محدودیتی نبوده؟
چرا اونا رو به این شکل طراحی نکردن؟
مثلا در جاوااسکریپت، که همین الان با تست دارم بهتون میگم، و اونم یک زبان داینامیک تایپ و سطح بالا و مربوط به وب است و با داده های مشابهی سروکار داره:
<script>
document.write('0'==0);
</script>
خروجی: true
اما این:
<script>
document.write('hello'==0);
</script>
خروجی: false
جاوااسکریپت از این نظر و از نظر کاربرد به PHP خیلی شبیه است. اون عملگر === رو هم داره. ولی در همچین موردی چنین کاری نکرده و البته کسی هم انتظار نداره! همین غیرمنتظره بودن و عدم درک منطق از سوی برنامه نویس هست که درست نیست. اگر منطقی داره، باید برنامه نویس هم بفهمه و انتظار داشته باشه. ما از منطق و انتظار منطقی صحبت میکنیم، نه محدودیت های فنی و نحوهء پیاده سازی. درواقع هیچ محدودیت فنی و مشکل پیاده سازی در این مورد وجود نداره و میتونستن از منطقی مشابه بقیهء زبانهای دینامیک و سطح بالا و وبی پیروی کنن. اینطوری از این نظر که بین زبانها سازگاری وجود داشت هم خوب بود، و از این نظر که برنامه نویس گیج نشه و خطا نکنه هم خوب بود. یعنی حتی اگر منطقی برای این رفتار بنظرشون میرسید (که تاحالا ندیدم)، بازهم ممکن بود وزن این سازگاری و هماهنگی یادگیری و کار، بر اون منطق و فایده بچربه.
-
نقل قول: رفتار دردسرساز switch
اتفاقاً هست! اگه قبل از if با gettype نوع v$ رو نگاه کنید میبینید که نوشته bool و پر واضحه که ازنظر == هر مقداری بجز 0 و null و '' و امثال اون، برابر با true هست. درمقابل 1 هم وقتی بعنوان bool نگاه بشه، یعنی true پس شرط اول درسته. دقت کنید که توی settype نمیشه نوع متغیر رو null بگذاریم. اگه میخواین واقعاً null بشه باید بگین ;v = null$
-
نقل قول: رفتار دردسرساز switch
حرفتون درست.
پس این چیه؟
$v = "Colors";
echo $v.'<br>';
$v = settype($v, 'string');
echo $v.'<br>';
if($v === 'hello'){
echo 'hello';
}
elseif($v == 'goodbye'){
echo 'goodbye';
}
else{
echo 'no';
}
یکی این چند خطتو تحلیل کنه!
//
$v = 95;
echo $v.'<br>';
$v = settype($v, 'integer');
echo $v.'<br>';
if($v === 'hello'){
echo 'hello';
}
elseif($v == 'goodbye'){
echo 'goodbye';
}
else{
echo 'no';
}
-
نقل قول: رفتار دردسرساز switch
خوب این برمیگرده به معماری داخلی و نحوه پیاده سازی Implicit Type Casting داخلی PHP که البته حق با شماست (ازنظر من) و هیچکس هم ادعا نکرده PHP بدون نقصه. پیشنهاد میکنم بعنوان bug گزارش کنید تا توی minor upgrade بعدی اصلاح بشه.
-
نقل قول: رفتار دردسرساز switch
نقل قول:
نوشته شده توسط
colors
حرفتون درست.
پس این چیه؟
$v = "Colors";
echo $v.'<br>';
$v = settype($v, 'string');
echo $v.'<br>';
if($v === 'hello'){
echo 'hello';
}
elseif($v == 'goodbye'){
echo 'goodbye';
}
else{
echo 'no';
}
یکی این چند خطتو تحلیل کنه!
//
$v = 95;
echo $v.'<br>';
$v = settype($v, 'integer');
echo $v.'<br>';
if($v === 'hello'){
echo 'hello';
}
elseif($v == 'goodbye'){
echo 'goodbye';
}
else{
echo 'no';
}
این مدلیشو دیگه تا حالا ندیده بودم ، که تایپو استرینگ تعریف کنی ، بعد تو gettype ؛ bool برگردونه
-
نقل قول: رفتار دردسرساز switch
هیچ زبانی اندازهء PHP اینقدر بی بند و بار نیست :لبخند:
دیدید که جاوااسکریپت در این مورد اینطور فکر و عمل نمیکنه.
و البته فکر نمیکنم هیچ زبانی جز PHP هم چنین کاری کرده باشه. شاید حتی در کل تاریخ برنامه نویسی چنین موردی نبوده!!
راستی الان با پایتون هم اومدم تست کنم.
پایتون هم داینامیک تایپ هست، اما حتی 0=='0' رو هم به رسمیت نمیشناسه!
print(0=='0')
خروجی: False
-
نقل قول: رفتار دردسرساز switch
البته من شخصا PHP رو خیلی دوست دارم.
بقول یارو، این حرفا چیزی از ارزشهاش کم نمیکنه :لبخند:
آلترناتیو مناسبی سراغ ندارم که بتونه جای PHP رو بگیره.
یک زبان بازمتن، مجانی، با این همه انعطاف و راحتی و امکانات.
میگن دندون اسب پیشکشی رو که نمیشمارن!
درکل چیز خوبیه.
ولی این موارد رو باید قبول کرد که اشتباهات طراحی هستن.
یا حداقل باید نسبت بهشون خیلی مشکوک بود.
هرچیزی باید منطقی داشته باشه.
و باید تمامی جوانبش رو درنظر گرفت.
اگر این موارد رو توش اصلاح کنن خب زبان بهتری میشه!
ولی اینکه نه یک بار، بلکه چند بار نظیر چنین تصمیماتی در طراحی گرفته و اجرا میشن، آدم رو به یه فکرهایی و وحشت میندازه :لبخند:
-
نقل قول: رفتار دردسرساز switch
نقل قول:
نوشته شده توسط
colors
حرفتون درست.
پس این چیه؟
$v = "Colors";
echo $v.'<br>';
$v = settype($v, 'string');
echo $v.'<br>';
if($v === 'hello'){
echo 'hello';
}
elseif($v == 'goodbye'){
echo 'goodbye';
}
else{
echo 'no';
}
یکی این چند خطتو تحلیل کنه!
//
$v = 95;
echo $v.'<br>';
$v = settype($v, 'integer');
echo $v.'<br>';
if($v === 'hello'){
echo 'hello';
}
elseif($v == 'goodbye'){
echo 'goodbye';
}
else{
echo 'no';
}
آقا درست صحبت کنین یعنی چی PHP بی بند و باره؟ من تعصب دارم روش ها! کدتون اشتباهه. settype رو که اینطوری صدا نمیزنن. باید بنویسید:
$v = "Colors";
settype($v, 'string');
if($v === 'hello'){
echo 'hello';
}
elseif($v == 'goodbye'){
echo 'goodbye';
}
else{
echo 'no';
}
//output: no
یعنی اینکه خروجی settype رو دوباره توی متغیر v$ نگذارین. چون اینطوری باعث میشه نتیجه تبدیل که true (تونسته تبدیل کنه) یا false (نتونسته تبدیل کنه) توی v$ ذخیره بشه و طبیعیه که نوع متغیر v$ میشه boolean !
-
نقل قول: رفتار دردسرساز switch
میدونی چی میگم مهندس!
موضوع اینه که از نظر برنامه نویس وقتی اینطور مقایسه ها رو داریم انجام میدیم بطور معمول دنبال مقایسه بر اساس ارزش عددی اونا نیستیم.
ارزش عددی یک رشته، یعنی تبدیلش به عدد، توابع صریح خودش رو داره و بعضی وقتا که نیاز داریم انجام میدیم.
ولی اینکه PHP این رفتار و موارد معدود رو به کل مقایسه ها تعمیم بده، جالب نیست! چون در عمل احتمالش خیلی کمه که منظور ما از اون مقایسه همونی بوده باشه که PHP داره بر اساسش عمل میکنه، و احتمال اینکه اینطور مقایسه مفید باشه و به نتیجهء منطقی درستی در برنامه منجر بشه خیلی کمه.
اینکه یه عدد توی یه رشته باشه اگر کاراکترهای عددی به تنهایی باشن خب یه چیزی، ولی وقتی کاراکترهای دیگری هم هستن، یا در مثال ما اصلا هیچ کاراکتر رقم توی رشته نیست، خیلی احتمالش کمه که منظور مقایسهء بر اساس ارزش عددی بوده باشه.
در اینطور موارد باید مقایسهء رشته ای باید صورت بگیره و اون عدد به رشته تبدیل بشه و با رشتهء دیگر مقایسه بشه، نه اینکه رشته به عدد تبدیل بشه!
واقعا در منطق و الگوریتم برنامهء شما چقدر احتمال مقایسهء معنا دار چنین مواردی میره؟!
منظورم اینه که یک رشته رو بخواید بر اساس ارزش عددیش با عدد مقایسه کنید. البته در موارد عادی ما این کار رو زیاد انجام میدیم، اما در اینطور موارد خود اون رشته هم محتوی یک عدده. خیلی کم پیش میاد که کاراکترهای غیررقمی هم درش باشن و منظور ما مقایسه بر اساس ارزش عددی باشه، و بازهم کمتر از این پیش میاد که اصلا هیچ کاراکتر رقمی توش نباشه و منظور ما مقایسه بر اساس ارزش عددی بوده باشه.
منکه چیزی به ذهنم نمیرسه.
طبیعتا احتمالش کمه و احتمال بیشتر مقایسهء رشته ایه.
بقیهء زبانهای داینامیک هم از همین پیروی میکنن.
بعضیا حتی سختگیرتر هم هستن.
خود داینامیک تایپ بودن توسط بعضیا مورد انتقاده و از دید و جنبه هایی یجورایی بی بند و باری و مایهء ایجاد باگ و برنامه نویسی بی دقت تلقی میشه، بعد PHP اومده رفتار سلیقه ای و غیرمنتظره رو به حد اعلی رسونده؛ بخاطر همین میگم که خیلی بی بند و باره :لبخند:
البته من اعتقادی ندارم که داینامیک تایپ بودن خوب نیست، بلکه بنظر من حداقل در حیطهء زبانها و کاربردهای خاص خودش خیلی هم چیز خوبیه (مزایاش از معایبش خیلی بیشتره)، ولی PHP دیگه دنده خلاص رو زده رفته یجایی که اصلا معلوم نیست کجاست و چرا! داره خلاف زبانهای هم خانواده دیگر عمل میکنه، و منطقش هم مشخص نیست!
-
نقل قول: رفتار دردسرساز switch
نقل قول:
نوشته شده توسط
MMSHFE
یعنی اینکه خروجی settype رو دوباره توی متغیر v$ نگذارین. چون اینطوری باعث میشه نتیجه تبدیل که true (تونسته تبدیل کنه) یا false (نتونسته تبدیل کنه) توی v$ ذخیره بشه و طبیعیه که نوع متغیر v$ میشه boolean !
بله درسته حق با شماست. ولی در هرصورت تونسته تبدیل کنه و مقدار درست (1) رو داره برمیگردونه و اینجا بازم مقدار boolean رو داره با رشته goodbye برابر تشخیص میده!
-
نقل قول: رفتار دردسرساز switch
نقل قول:
نوشته شده توسط
MMSHFE
$v = "Colors";
settype($v, 'string');
if($v === 'hello'){
echo 'hello';
}
elseif($v == 'goodbye'){
echo 'goodbye';
}
else{
echo 'no';
}
//output: no
یعنی اینکه خروجی settype رو دوباره توی متغیر v$ نگذارین. چون اینطوری باعث میشه نتیجه تبدیل که true (تونسته تبدیل کنه) یا false (نتونسته تبدیل کنه) توی v$ ذخیره بشه و طبیعیه که نوع متغیر v$ میشه boolean !
خدا وکیلی اینقدر که محو دستوارت شده بودیم ، منم اصلا متوجه تعریف غلط settype نشده بودم "مثل همین دستوارت که من غلط نوشتم و درستش دستورات هست" ولی متوجه نشدید :لبخند:
نقل قول:
هیچ زبانی اندازهء PHP اینقدر بی بند و بار نیست
نه اینطورم نیست ، اتفاقاَ چون متغیرها صریح تعریف نمیشن و php بر اساس محتوی نوع رو مشخص میکنه این رفتار ها طبیعی هست ، چون تا جایی که ممکنه سعی میکنه نوع رو به هم تبدیل کنه ، خب البته حقم داره ، هی شما گیجش میکنین یه طرف عدد میدین یه طرف رشته ، طفلی تو رو دروایسی گیر میکنه !
مثلا مگه شما جرات دارین تو سی شارپ بگین(if ("0" == 0 :لبخند:
مظلوم گیر آوردین؟:لبخند:
به نظر من اینا خصوصیات خوبیه ،به شرطی که درست استفاده شه، ایراد نیست.
Type Juggling
Comparison Operators
-
نقل قول: رفتار دردسرساز switch
نقل قول:
نوشته شده توسط
colors
بله درسته حق با شماست. ولی در هرصورت تونسته تبدیل کنه و مقدار درست (1) رو داره برمیگردونه و اینجا بازم مقدار boolean رو داره با رشته goodbye برابر تشخیص میده!
بله درسته که تونسته تبدیل کنه ولی دقت کنید که elseif با == مقایسه کرده نه با ===
همه چیز با وجود اینکه بنظر میاد بی نظمی داره، از یک منطق خاص (که بهرحال ممکنه بنظر برخی درست نیاد) پیروی میکنه و اینطور نیست که کلاً منطق نداشته باشه.
-
نقل قول: رفتار دردسرساز switch
نقل قول:
نوشته شده توسط
colors
بله درسته حق با شماست. ولی در هرصورت تونسته تبدیل کنه و مقدار درست (1) رو داره برمیگردونه و اینجا بازم مقدار boolean رو داره با رشته goodbye برابر تشخیص میده!
از نظر php هر چیز غیر صفر و تهی، true میشه.
$a == $b //Equal TRUE if $a is equal to $b after type juggling.
$a === $b //Identical TRUE if $a is equal to $b, and they are of the same type.
دقت کنین که برای عملگر == اینطوریه که اول Type Juggling انجام میشه بعد شرط برابر بودن بررسی میشه ، ولی تو === Type Juggling نداریم.
یعنی به قول آقای شهرکی همه چیز با وجود اینکه بنظر میاد بی نظمی داره، از یک منطق خاص پیروی میکنه ، در واقع این ما هستیم که داریم بی نظمی ایجاد میکنیم و میخوایم همه چیز اونطور که ما میخوایم انجام شه در صورتی که تو خود مستندات php اینارو کامل توضیح داده.
$a=true;
$b="hello";
if($a==$b) //Type Juggling anjam mishe
echo "One";
if($a===$b) // Type Juggling anjam Nemishe , type ha check mishe bad mohtava
echo "Two";
//
//output: One
//
-
نقل قول: رفتار دردسرساز switch
نقل قول:
نوشته شده توسط
ابوذر محمودی
ا
$a=true;
$b="hello";
if($a==$b) //Type Juggling anjam mishe
echo "One";
if($a===$b) // Type Juggling anjam Nemishe , type ha check mishe bad mohtava
echo "Two";
//
//output: One
//
منطق جالبی نیست!
به نظرم مث بیشتر زبانهای دیگه نباید اینطور باشه!!
-
نقل قول: رفتار دردسرساز switch
خوب اگه قرار نبود اینطوری باشه، عملگر === رو میشه بگین دقیقاً برای چی گذاشتن؟ یکی از امکانات خوب PHP همین بحث تبدیل خودکار نوع متغیرهاست و البته حساس نبودن به نوع متغیرها. حالا گفته اگه جایی خواستین به نوع هم حساس باشین، اینهم عملگرشه. کجاش جالب نیست؟
-
نقل قول: رفتار دردسرساز switch
نقل قول:
نوشته شده توسط
MMSHFE
خوب اگه قرار نبود اینطوری باشه، عملگر === رو میشه بگین دقیقاً برای چی گذاشتن؟ یکی از امکانات خوب PHP همین بحث تبدیل خودکار نوع متغیرهاست و البته حساس نبودن به نوع متغیرها. حالا گفته اگه جایی خواستین به نوع هم حساس باشین، اینهم عملگرشه. کجاش جالب نیست؟
حق با شماست
-
نقل قول: رفتار دردسرساز switch
نقل قول:
نوشته شده توسط
ابوذر محمودی
نقل قول:
همه چیز با وجود اینکه بنظر میاد بی نظمی داره، از یک منطق خاص (که بهرحال ممکنه بنظر برخی درست نیاد) پیروی میکنه و اینطور نیست که کلاً منطق نداشته باشه.
بحث نظر نیست. باید دلیل منطقی و فایدهء کافی داشته باشه.
چرا زبانهای دیگه اینطور عمل نمیکنن؟ حتی زبانهای هم خانواده.
چیزهایی که شما تاحالا گفتی فقط اشاره به طرز کارکرد و منطق داخلی پیاده سازی خاص PHP برای اینطور عملیات بود. یعنی شما میگی PHP به هر شکلی که پیاده کرده بود و هرطور اون پیاده سازی کار میکرد، منطقی است و برنامه نویسان هم باید بپذیرن؟
همچین چیزی نیست!
این زبان برنامه نویسی و نحوهء پیاده سازی اونه که متاثر از منطق و انتظار و فایده در سطوح بالاتره. زبان برنامه نویسی است که بر اساس اون منطق و انتظارات باید طراحی بشه.
در سطح برنامه نویسی بگید این مورد خاص چه منطق و فایده ای داره جز اینکه غیرمنطقی و غیرمنتظره بنظر میاد و احتمال بیشترش اینه که با منظور برنامه نویس و منطق برنامه تطابق نداشته باشه و در نتیجه ایجاد باگ بکنه.
یه زمانی رجیسترگلوبالز رو هم با یکسری توجیهات خودشون طراحی کردن، و تا مدتها روش اصرار داشتن خیلی ها و هنوزم قبول نمیکردن و بعضیا همین الان هم قبول ندارن که یک طراحی اشتباه بود، ولی دست آخر مجبور شدن حذفش کنن! اگر واقعا طراحی درست و عاقلانه و سودمندی بود، پس چرا در عمل مجبور شدن حذفش کنن؟ کم چیزی نیست یک چنین تغییر اساسی بعد از مدتها در یک زبان برنامه نویسی.
----------------------------------------------------------
نقل قول:
از نظر php هر چیز غیر صفر و تهی، true میشه.
...
یعنی به قول آقای شهرکی همه چیز با وجود اینکه بنظر میاد بی نظمی داره، از یک منطق خاص پیروی میکنه ، در واقع این ما هستیم که داریم بی نظمی ایجاد میکنیم و میخوایم همه چیز اونطور که ما میخوایم انجام شه در صورتی که تو خود مستندات php اینارو کامل توضیح داده.
اون منطق نیست. یه راه حل و پیاده سازی رو خودشون فرض کردن و پیاده کردن بعد بهش میگن منطق؟
منم اینطوری میتونم یه منطق دیگه از خودم اختراع کنم و در یک زبان برنامه نویسی پیاده سازیش کنم، بعد برنامه نویسان باید بپذیرن و عاقلانه بدونن؟
و چرا زبانهای دیگر اینطور عمل نمیکنن؟ یعنی سلیقه ای بوده؟ اگر سلیقه ای نیست، پس منطق و معیارش چیه در هر موردی؟ نمیشه که در هر زبانی یک منطق متفاوت داشته باشه و به طرز کاملا متفاوتی رفتار کنه! حداقل بطور معمول اینطور نیست!!
در هیچ زبانی 'hello'==0 شرطی درست فرض نمیشه.
مگر زبانهای دیگری دینامیک تایپ نیستن و Implicit type conversion و این حرفا رو ندارن؟ پس چرا PHP یه طرفه و همهء زبانهای دیگه یه طرف دیگه؟ یعنی PHP خیلی نابغه بوده و نگرش جدید و مفیدتری رو ارائه کرده در این زمینه؟ منکه فکر نمیکنم!
----------------------------------------------------------
نقل قول:
خوب اگه قرار نبود اینطوری باشه، عملگر === رو میشه بگین دقیقاً برای چی گذاشتن؟ یکی از امکانات خوب PHP همین بحث تبدیل خودکار نوع متغیرهاست و البته حساس نبودن به نوع متغیرها. حالا گفته اگه جایی خواستین به نوع هم حساس باشین، اینهم عملگرشه. کجاش جالب نیست؟
مهندس بحث من اون یک مورد خاص بود، نه اینکه کلا با تبدیل خودکار نوع متغییرها و حساس نبودن به نوع مخالف باشن. زبانهای مشابه در این زمینه هستن که کم و بیش این کارها رو انجام میدن؛ مثل جاوااسکریپت که مثال زدم. ولی در تمام اون زبانها خیلی چیزها در این زمینه یکسان یا مشابه هستن یا حداقل منطقشون خیلی راحتتر قابل درک و قابل انتظاره برای برنامه نویس و کدی که توی برنامه کار میکنه در اکثر موارد منظورش همون نوع مقایسه است و درست عمل میکنه، ولی این یک مورد خاص در PHP که بر اساسش 'hello'==0 میشه، در هیچ زبانی مشابهش وجود نداره (شخصا سراغ ندارم) و چیزی در این حد غیرمنتظره و بدون منطق قابل درک در سطح برنامه نویس ندیدم تاحالا در این زمینه و احتمال بیشتر در منظور و منطق کدهای برنامه زمانی که چنین مقایسه هایی بخوان صورت بگیره بر خلاف چیزی است که PHP برای مقایسه درنظر میگیره.
-
نقل قول: رفتار دردسرساز switch
بحث تبدیل نوع خودکار و اینها برای کمک به برنامه نویسی راحتتر و سریعتر وجود دارن.
این تبدیل ها طوری هستن و بر اساس منطقی عمل میکنن که احتمال بیشتر در برنامه در کدها اونه که منظور همون بوده باشه و منطق برنامه به این شکل درست اجرا بشه. همینطور کشکی نیامدن یه فرضی بکنن و درستش کنن. سلیقه ای نیست که! در نهایت هم برنامه نویس سطح بالا میخواد با اون زبان کار بکنه و این ویژگیها باید قابل درک و انتظار و مفید برای برنامه نویس سطح بالا باشن، نه اینکه بیایم دلیل در سطح دودویی براش بیاریم که بله چون اینطور فرض کردن و اینطور پیاده سازی کردن پس اینطوری شده و منطقش اینه!!
نقل قول:
خوب اگه قرار نبود اینطوری باشه، عملگر === رو میشه بگین دقیقاً برای چی گذاشتن؟
عملگر === در زبانهای دیگر هم هست. مثل جاوااسکریپت. ولی اونا 'hello'==0 رو درست فرض نمیکنن!
یعنی اگر 'hello'==0 نشه، اونوقت باید همه این بند و بساط رو جمع کنن؟
یعنی این چیزا در زبان دیگری وجود نداره؟
یجوری صحبت میکنید انگار فقط در PHP دینامیک تایپ و تبدیل نوع و این چیزها رو داریم!
اگر قبول دارید در زبانهای دیگری هم این چیزها هست، پس منطق اونا چی بوده و چطور پیاده سازیش کردن که هیچکدام از اونا 'hello'==0 رو درست نمیگیرن؟
در PHP هم بنظر من اگر شده باید یه استثناء برای این مورد بذارن.
مثلا موقع مقایسهء رشته با عدد، اگر رشته واقعا محتوی یک عدد بود بیاد و رشته رو تبدیل به عدد بکنه و با عدد دیگر مقایسه کنه، ولی اگر رشته محتوی عدد نبود، دیگه نباید دو طرف رو برابر فرض کنه.
این قاعده ایه که در جاوااسکریپت اعمال شده. مثالش رو هم براتون گذاشتم.
-
نقل قول: رفتار دردسرساز switch
این اشکالی که شما پیدا کردی به نظر من دقیقا اسمش باگ هست و اشکال هم هست . قابل توجیه کردن هم نیست . و حدس میزنم این یه سرنخ بود که دستت اومد و من منتظر باگ های بعدی هم هستم . چون توجهت رو به این مساله جلب کرده امکانش هست که بازم موارد اینچنینی رو بهش برخورد کنی .
من یه نکته ایی رو می خوام یادآوری کنم به کسانی که در حال یادگیری هستند و احیانا اینجا رو می خونن :
این تاپیک داره به دوستانی که مثل من تازه کار هستند میگه که لطفا زبانی رو که باهاش برنامه می نویسید و مطالعه کنید و بشناسید . نه فقط کار با دیتابیس . بلکه زبان رو مطالعه باید کرد و گاهی باید تحقیقاتی رو در زمینه زبان های برنامه سازی مثل مدیریت حافظه ... مفسر ... نوع های داینامیک و ( اینکه اینها چه هستند و مزایاو معایب اونها رو باید درک کرد ... ) رو داشته باشید . گاهی آسیب پذیری ها رو دنبال کنید . مقالات پیشرفته تر ... مباحثی که نکات ( Tips ) ها رو بیان می کنند و دنبال کنید تا برنامه های بهینه بنویسید و مزایا و معایب زبان برنامه نویسی تون رو بشناسید .
-
نقل قول: رفتار دردسرساز switch
این حرف شما کاملاً صحیحه. امتیاز اصلی PHP که اینهم داریم میگیم Open Source هست هم همینه که میشه جزئیات طراحی داخلیش رو هم خوند و فقط با سعی و خطا مشکلات رو پیدا نکنیم! من هیچ جا نگفتم منطق PHP در این مورد درسته. فقط گفتم منطق و روش پیاده سازیش اینه و اینطور نیست که همینطوری رو هوا و هربار Random یک چیزی رو ارزیابی کنه. حالا اگه ازنظر من و شما این منطق پشت پرده، درست نیست، خوب میتونیم گزارش کنیم. مهمترین حسن جامعه Open Source هم همینه که به Bug Report اهمیت زیادی میدن و واقعاً رفع میکنن (فقط من گفتم منطقش چیه که موقتاً تا وقتی که بخواد رفع بشه، بدونید از چه سیستمی داره برای کار استفاده میکنه تا بتونید خودتون با سایر ابزارها توی کدهاتون جلوی بروز مشکلات احتمالی رو بگیرین). توی مدرک تخصصی ZCE هم بخاطر همین قبیل مسائله که یکسری از مفاهیم Core زبان PHP مطرح میشه و صرفاً توانایی تولید سایت با PHP مدنظر نیست.
-
نقل قول: رفتار دردسرساز switch
نقل قول:
نقل قول:
از نظر php هر چیز غیر صفر و تهی، true میشه.
اون منطق نیست. یه راه حل و پیاده سازی رو خودشون فرض کردن و پیاده کردن بعد بهش میگن منطق؟
اگه دقت کنی توی زبان سی هم ما بولین نداریم ، ولی اتفاقا خوبشو داریم یعنی هر چیز صفر و تهی F و بقیه T ، جاوا اسکریپتم همینطوره ، پس این مورد رو php از خودش در نیاورده.
نقل قول:
اگر قبول دارید در زبانهای دیگری هم این چیزها هست، پس منطق اونا چی بوده و چطور پیاده سازیش کردن که هیچکدام از اونا 'hello'==0 رو درست نمیگیرن
برای این مورد که میگی 'hello'==0 باید همه زبان هایی که دینامیک تایپ دارن رو بررسی کرد .
خب الان چرا تو سی وقتی متغیر کاراکتری x رو که توش حرف a داره رو با 97 تست میکنی باید برابر باشه؟ مگه a با 97 برابره؟
حالا a رو میگیم کد اسکیش برایر 97 هست ، ali چی؟
چرا به C این اشکال وارد نیست ولی الان به PHP این اشکال وارده؟
-
نقل قول: رفتار دردسرساز switch
نقل قول:
این اشکالی که شما پیدا کردی به نظر من دقیقا اسمش باگ هست و اشکال هم هست
دقیقا باگه؟ شما اینجا رو بررسی کنین :
<?php
$foo = "0"; // $foo is string (ASCII 48)
$foo += 2; // $foo is now an integer (2)
$foo = $foo + 1.3; // $foo is now a float (3.3)
$foo = 5 + "10 Little Piggies"; // $foo is integer (15)
$foo = 5 + "10 Small Pigs"; // $foo is integer (15)
?>
foo = 5 + "10 Small Pigs"; شما مستندات php رو مطالعه کردین که میگین باگه؟ بعد چطور بقیه رو توصیه می کنید که اول زبان رو مطالعه کنند؟
برای کسی که درست استفاده نکنه و آشنا نباشه با نوع طراحی اون زبان ، بله دقیقاَ باگ هست.
البته نه این که فکر کنید من تعصب خاصی دارم روش ، نه ، همه ما تو PL خوندیم که اینا جزو مسایل اولیه هست که تو طراحی زبان پیش میاد ، و صرف دانش کممون از تئوری های یک زبان نمیتونیم بگیم این ایراده ، باگه ، مشکله و ...
-
نقل قول: رفتار دردسرساز switch
خیلی وقتا پیش میاد که ما تو شرط ها گاهی از == و گاهی هم از === استفاده می کنیم ، اگه یک بار از خودمون میپرسیدیم فرق == با === چیه ، بعد به مستندات php رجوع میکردیم الان این مساله ای که خود php بهش با مثال اشاره کرده رو منسوب به باگ خطرناک نمیکردیم.
این مساله همین الان کشف نشده که بهش لقب کشف باگ میدیم ، کسان دیگه ای هم بودن که به این مساله برخوردن :
مثلا :
why-does-0-hello-return-true-in-php
-
نقل قول: رفتار دردسرساز switch
نقل قول:
نوشته شده توسط
ابوذر محمودی
اگه دقت کنی توی زبان سی هم ما بولین نداریم ، ولی اتفاقا خوبشو داریم یعنی هر چیز غیر صفر و تهی F و بقیه T ، جاوا اسکریپتم همینطوره ، پس این مورد رو php از خودش در نیاورده.
فکر کنم باید اون «غیر» رو حذف کنی!
بعدشم خب اینا چه ربطی به مورد ما داره؟
من بحثم یه چیزی مثل 'hello'==0 هست که هیچ معنی منطقی نمیده و فایده ای در برنامه نویسی نداره که بعکس منشاء مشکل و باگ میشه.
اتفاقا اینکه زبانهای دیگر هم باوجود این شباهت ها، 'hello'==0 رو قبول ندارن نشون میده که این مورد به موارد دیگری که ذکر کردی ربطی نداره و اگر موارد دیگر به اون شکل بود دلیل نمیشه اینطور موارد اینطوری باشه.
نقل قول:
برای این مورد که میگی 'hello'==0 باید همه زبان هایی که دینامیک تایپ دارن رو بررسی کرد .
بعید میدونم زبان دیگری پیدا کنید که اینطور باشه.
چون از نظر منطقی و فایدهء برنامه نویسی دلیل موجهی براش دیده نمیشه.
شما موردی پیدا کردید خبرمون کنید!
اگر خودتون هم منطق و فایده ای بنظرتون میرسه براش خب مطرح کنید!
من قبلا برای خلافش دلیل آوردم. استدلالهای بنده بنظرتون نادرست بود؟
نقل قول:
خب الان چرا تو سی وقتی متغیر کاراکتری x رو که توش حرف a داره رو با 97 تست میکنی باید برابر باشه؟ مگه a با 97 برابره؟
حالا a رو میگیم کد اسکیش برایر 97 هست ، ali چی؟
چرا به C این اشکال وارد نیست ولی الان به PHP این اشکال وارده؟
تاجاییکه یادمه، در سی کاراکتر و رشته دو نوع مجزا هستن.
رشته رو که اصلا نمیتونی بصورت مستقیم مقایسه کنی، و باید از توابع مخصوصش برای این کار استفاده کنی (فکر کنم اسم یکیش strcmp بود).
اونم که شما رشتهء ali رو مقایسه کردی نمیدونم عملا تست کردی و جواب میده یا نه، ولی بهرحال مقایسهء رشته با عدد بوسیلهء عملگر == یه چیز استاندارد و مشخص شده و معناداری نیست در زبان سی. احتمالا بخاطر همین فقط کاراکتر اولش رو دیده و به همون صورت تک کاراکتر اولش مقایسه کرده.
بعدم سی خب یک زبان سطح پایین و سیستمی است و مقایسش با زبان سطح بالا و وبی مثل PHP فکر نمیکنم زیاد جالب باشه! بهتره PHP رو با زبانهای هم خانواده و هم سطح خودش مقایسه کنیم. بهرحال سی هم زبان قدیمی ای است و از اون زمان خیلی چیزها بهتر شدن و اضافه شدن و تغییر کردن و سینتاکس و رفتار سی لزوما معیار و اثبات کلی برای تمام زبانها و تمام سطوح و کاربردها و تمام زمانها نیست.
نقل قول:
مگه a با 97 برابره؟
حالا a رو میگیم کد اسکیش برایر 97 هست
بله دیگه سی کاراکتر رو با عدد، بر اساس کد اسکی کاراکتر مقایسه میکنه. و این در سی خیلی کاربرد داره.
درحالیکه اینطور مقایسه ها در PHP بر اساس کد اسکی نیستن، پس باید یه منطق و فایدهء دیگری داشته باشن.
-
نقل قول: رفتار دردسرساز switch
ببین سی فکر میکنم اصلا داستانش از اساس فرق داره.
سی که مثل زبانهای سطح بالا نیست.
در سی شما شاید در ظاهر بیای و رشته رو با عدد مقایسه کنی، که حتی شاید تابع strcmp رو هم بتونی واسه این استفاده کنی و خطایی هم نده.
ولی موضوع اینه که سی خودش اصلا ایده ای در اینطور موارد نداره و اینطور مقایسه ها براش تعریف نشدن و معنا و استانداردی ندارن.
مقایسهء رشته و عدد در سی تعریف نشده و بی معناست.
مقایسهء رشته با عدد در زبانهای برنامه نویسی سطح بالا معنی داره، ولی در سی نه.
سی یک زبان سطح پایینه که یکسری چیزها رو اصلا چک نمیکنه. یعنی میخوام بگم اینکه وقتی به خیال خودتون عدد و رشته رو مقایسه میکنید خطایی نمیده، دلیل بر این نمیشه که اینطور مقایسه در سی تعریف شده و معنا و منطقی داره.
در سی مثلا شما میتونید براحتی از محدودهء یک آرایه هم خارج بشید و داده های شما با همدیگر و با کد اجرایی برنامه تداخل کنن؛ سی در زمان کامپایل و زمان اجرا به شما خطایی در این زمینه نمیده و فقط زمانی متوجه میشید مشکلی وجود داره که برنامه بطور غیرعادی/اشتباه عمل میکنه و جوابهای غلط میده و کارهای اشتباه میکنه یا اینکه کلا crash میکنه!
ولی بحثی که درمورد PHP داریم قضیش متفاوته و درمورد چیزهای تعریف شده و معنا دار و از قبل درنظر گرفته شده و فکر شده و طراحی شده است که PHP در زمان اجرا نسبت به اونا آگاهی و کنترل داره، و باید منطق و استانداری براشون وجود داشته باشه.
پس این مورد در سی و PHP فقط در ظاهر مشابه هستن، و در باطن از نظر ماهیتی قابل مقایسه نیستن.
رفتار سی در این مورد (مقایسهء رشته و عدد) تصادفی است، اما رفتار PHP از قبل پیشبینی شده و منطق و هدفی داره.
تازه اون مقایسهء کاراکتر و عدد هم که در سی معنا داره، بر اساس کد اسکی صورت میگیره و در برنامه های سی کاربرد زیادی داره. و یک خصیصهء اساسی اون کاراکتر با عدد واقعا با هم برابره که شرط درست درمیاد.
-
نقل قول: رفتار دردسرساز switch
نقل قول:
فکر کنم باید اون «غیر» رو حذف کنی!
خوب شد گفتی :لبخند: اشتباه تایپی بود
حالا مابقیش باشه بعداَ الان باید برم جایی وقت نیست تایپ کنم:گل:
-
نقل قول: رفتار دردسرساز switch
نقل قول:
اونم که شما رشتهء ali رو مقایسه کردی نمیدونم عملا تست کردی و جواب میده یا نه، ولی بهرحال مقایسهء رشته با عدد بوسیلهء عملگر == یه چیز استاندارد و مشخص شده و معناداری نیست در زبان سی. احتمالا بخاطر همین فقط کاراکتر اولش رو دیده و به همون صورت تک کاراکتر اولش مقایسه کرده.
درسته اصلا نمیشه و فقط کاراکتر اول رو میگیره ، البته من ali رو تست نکردم ab رو تست کردم و به صورت char s='ab' تعریف کردم.
نقل قول:
که بعکس منشاء مشکل و باگ میشه.
اینو دیگه یکم منصف باش ، مشکل و باگ از طرف کاربر ایجاد میشه ، اونم به خاطر عدم آشنایی با اون زبان ، وگرنه اینو که خود سایت php با مثال گفته دیگه.
$foo = 5 + "10 Little Piggies"; // $foo is integer (15)
$foo = 5 + "10 Small Pigs"; // $foo is integer (15)
ببین عدد رو با رشته جمع کرده ، یعنی تا جایی که تو رشته عدد بوده تبدیل کرده مابقی رو نه ، خب موقع مقایسه هم همین امر هست. چون تو مستندات ذکر شده که برای == نوع چک نمیشه ، اول تبدیل نوع انجام میشه به یک نوع قابل قیاس بعد شرط بررسی میشه و گفته اگه میخواین نوع هم مقایسه بشه از === استفاده شه.
نقل قول:
بعدم سی خب یک زبان سطح پایین و سیستمی است و مقایسش با زبان سطح بالا و وبی مثل PHP فکر نمیکنم زیاد جالب باشه! بهتره PHP رو با زبانهای هم خانواده و هم سطح خودش مقایسه کنیم.
اون که آره ، ولی خب یکم از مقایسه با جاوا اسکریپت آبرومندتره :لبخند:
-
نقل قول: رفتار دردسرساز switch
دوست گرامی این مثال شما ربطی به نمونه ایی که بالا گذاشتن نداره ! این از صحبت ما جداست :
نقل قول:
<?php
$foo = 5 + "10 Little Piggies"; // $foo is integer (15)
$foo = 5 + "10 Small Pigs"; // $foo is integer (15)
?>
در اینجا از از 10 به بعد نادیده گرفته میشه . در جاوا اسکریپت هم همینه و اصلا بحثی رو این نیست و ربطی به موضوع ما نداره .
نقل قول:
?php
$v=0;
switch($v) {
case 'hello':
echo 'hello';
break;
case 'goodbye':
echo 'goodbye';
break;
default:
echo 'default';
break;
}
?>
من به عنوان برنامه نویس اگر این کد رو بهم بدن و بگن کدام بخش اجرا میشه ؟ انتظارم و جواب echo default هست . شما همین و ببر توی جاوا اسکریپت و اجرا کن :
var v=0;
switch(v) {
case 'hello':
alert('hello');
break;
case 'goodbye':
alert('goodbye');
break;
default:
alert('default');
break;
}
حداقل در تستی که من انجام دادم بخش default اجرا شد و انتظار من و برآورده کرد ... حالا این دوستمون امتحان کرده و hello اجرا شده !!! و ما میگیم اشکال هست و واقعا هم در برنامه اشکال به وجود میاره ... شما هم انتظار همچین اجرایی رو ندارین .
دقت کن که منظور ما این مثال هایی که شما آوردی نیست .
-
نقل قول: رفتار دردسرساز switch
نقل قول:
سی که مثل زبانهای سطح بالا نیست.
:متفکر:
نقل قول:
سی یک زبان سطح پایینه
:متفکر:
اون حدیثت یادته؟
نقل قول:
یعنی میخوام بگم اینکه وقتی به خیال خودتون عدد و رشته رو مقایسه میکنید خطایی نمیده، دلیل بر این نمیشه که اینطور مقایسه در سی تعریف شده و معنا و منطقی داره.
یعنی پس به قول دوستان یک عدد باگ کشف شد:چشمک:
حالا حرف من چیه ؛ ما که از تئوری و دلایل تیمی که php رو طراحی کردن آگاهی کامل نداریم و صرفا فقط از خود زبان داریم استفاده میکنیم و کمی به مستنداتش آگاهی داریم.
اینکه من بیام چند تا مطلب تو سطح دانش خودم بگم و شما هم متقابلاَ ، چیزی رو تغییر نمیده ؛ درسته در این وسط خیلی چیزا به چالش کشیده میشه و جالبم هست ، ولی خروجی در آخر نخواهد داشت .
مگه اینکه گزارش کنین .
-
نقل قول: رفتار دردسرساز switch
یه مجری رادیو می گفت : تپق زدن بین حرف حق سخنران هست . ۰ یعنی کسی که مجری هست و مدام حرف می زنه یا سخنران هست حالا ممکنه یه لحظه توی حرف زدنش اشکالی پیش بیاد ) .
به نظر من باگ هم حق برنامه نویسه ... اگر زبانی طراحی نشه ! یا برنامه ایی نوشته نشه باگی هم به وجود نمیاد !!! ولی وقتی طراحی و نوشته شد بله باگ هم داره .
-
نقل قول: رفتار دردسرساز switch
نقل قول:
نوشته شده توسط
بهزاد علی محمدزاده
دوست گرامی این مثال شما ربطی به نمونه ایی که بالا گذاشتن نداره ! این از صحبت ما جداست :
در اینجا از از 10 به بعد نادیده گرفته میشه . در جاوا اسکریپت هم همینه و اصلا بحثی رو این نیست و ربطی به موضوع ما نداره .
من به عنوان برنامه نویس اگر این کد رو بهم بدن و بگن کدام بخش اجرا میشه ؟ انتظارم و جواب echo default هست . شما همین و ببر توی جاوا اسکریپت و اجرا کن :
var v=0;
switch(v) {
case 'hello':
alert('hello');
break;
case 'goodbye':
alert('goodbye');
break;
default:
alert('default');
break;
}
حداقل در تستی که من انجام دادم بخش default اجرا شد و انتظار من و برآورده کرد ... حالا این دوستمون امتحان کرده و hello اجرا شده !!! و ما میگیم اشکال هست و واقعا هم در برنامه اشکال به وجود میاره ... شما هم انتظار همچین اجرایی رو ندارین .
دقت کن که منظور ما این مثال هایی که شما آوردی نیست .
بهزاد عزیز اتفاقاَ داره دیگه ، چون این بخشی از تبدیل نوعش هست یا به قول خودشون type-juggling ، یک طرف نوع عددی هست و طرف دیگه نوع رشته که اولش هم عدده ، خب برای جمع باید دو طرف به نوع عددی تبدیل شه دیگه مگه نه؟
خب پیش فرض تو نوع عددی صفره دیگه ، وقتی پیدا نمیکنه پیش فرض 0 در نظر میگیره. خب موقع مقایسه با == هم اول تبدبل میکنه بعد مقایسه
من بحثم اینه که این باگ نیست چون تو مستندات سایت PHP برای == به همه این شبهه ها جواب داده.
اگه قراره باگ تلقی شه ، برای وقتی هست که برنامه نویس بدون آگاهی به type-juggling و == و === بیاد برنامه بنویسه.
-
نقل قول: رفتار دردسرساز switch
نقل قول:
نوشته شده توسط
بهزاد علی محمدزاده
یه مجری رادیو می گفت : تپق زدن بین حرف حق سخنران هست . ۰ یعنی کسی که مجری هست و مدام حرف می زنه یا سخنران هست حالا ممکنه یه لحظه توی حرف زدنش اشکالی پیش بیاد ) .
به نظر من باگ هم حق برنامه نویسه ... اگر زبانی طراحی نشه ! یا برنامه ایی نوشته نشه باگی هم به وجود نمیاد !!! ولی وقتی طراحی و نوشته شد بله باگ هم داره .
صدرصد.
تصحیح میکنم باگ حق مسلم ماست.:چشمک:
من که زیاد وقت ندارم بیام انجمن ، هر ماه یه دو سه روز میام ، ولی اگه کسی میخواد شرکت کنه خوبه مثل بقیه بحث های مشابه به جنجال کشیده نشه.
پیشاپیش ، پساپیش از کلیه عزیزان و همراهان گرامی ، اگه مطلبی گفتم که ناراحت شدن ، یا به نحوی دلخور شدن عذرخواهم.
-
نقل قول: رفتار دردسرساز switch
نقل قول:
نوشته شده توسط
ابوذر محمودی
درسته اصلا نمیشه و فقط کاراکتر اول رو میگیره ، البته من ali رو تست نکردم ab رو تست کردم و به صورت char s='ab' تعریف کردم.
شما برای مقدار کاراکتر فقط یک کاراکتر باید بذارید.
معلومه که وقتی مقدارش رو char تعریف کردید فقط کاراکتر اول رو میگیره.
بعد اومدی میگی رشته ali رو با عدد 97 مقایسه کردی!؟
نقل قول:
اینو دیگه یکم منصف باش ، مشکل و باگ از طرف کاربر ایجاد میشه ، اونم به خاطر عدم آشنایی با اون زبان ، وگرنه اینو که خود سایت php با مثال گفته دیگه.
$foo = 5 + "10 Little Piggies"; // $foo is integer (15)
$foo = 5 + "10 Small Pigs"; // $foo is integer (15)
ببین عدد رو با رشته جمع کرده ، یعنی تا جایی که تو رشته عدد بوده تبدیل کرده مابقی رو نه ، خب موقع مقایسه هم همین امر هست. چون تو مستندات ذکر شده که برای == نوع چک نمیشه ، اول تبدیل نوع انجام میشه به یک نوع قابل قیاس بعد شرط بررسی میشه و گفته اگه میخواین نوع هم مقایسه بشه از === استفاده شه.
اکثر زبانهای داینامیک تایپ تبدیل های خودکار و موارد مشابهی دارن، ولی نه دیگه درحد PHP به این شکلهای افراطی و غیرمنتظره (بخصوص مورد 'hello'==0).
مواردی که زبانهای دیگه دارن عملا در برنامه نویسی کاربرد زیاد دارن و وقتی چنان کدی در برنامه وجود داره، احتمال زیاد منظور برنامه نویس هم همون بوده از نظر منطقی و آماری.
الان این کدی که شما میاری کاربردش در برنامه نویس چقدره؟ اگر نگیم هیچی، ولی خیلی کمه. فرض کن طرف دوم یک متغییر بود که توش اون رشته در برنامه در زمان اجرا جای گرفته (میتونسته مقادیر دیگری هم داشته باشه)؛ در چنین مواردی بسیار محتمل است که مشکلی در برنامه وجود داشته که چنان مقداری در اون متغییر قرار گرفته و داره با یک عدد مقایسه یا جمع میشه. در زبانهای دیگر این منجر به خطا میشه، و به این شکل برنامه نویس یا کاربر مطلع میشه و از زیردست دررفتن و منجر به خسارت بیشتر شدن چنین مواردی جلوگیری میشه.
ربطی هم به این نداره که بگیم خب باید حتما عملگر === رو استفاده میکرد و تقصیر برنامه نویس بوده، وگرنه در تمام موارد باید از === استفاده کنیم چون در تمام موارد ممکنه چنین باگ و مشکلی در هرجایی از برنامه پیش بیاد. تمام باگها و اهمیتشون رو که نمیشه از قبل و با اطمینان زیاد پیشبینی کرد!
البته == میتونه تا یک حدی ناامن باشه، که هست. اصولا چیزهایی مثل داینامیک تایپ بودن و implicit type conversion مقداری ریسک دارن و میتونن باعث برنامه نویسی کم دقت تر و از زیردست در رفتن باگها بشن، ولی این ریسک درمقابل مزایا و راحتی و سرعتی که در برنامه نویسی ایجاد میکنن کمتره.
ولی این حدی که PHP اون رو ناامن کرده، اونم بخاطر مواردی که در برنامه نویسی کاربرد غالبی ندارن، دیگه نوبره! یعنی توی فکرم که طراحان PHP اینقدر کم دانش و بصیرت بودن که فقط دوتا جزییات و منطق فنی سطح پایین رو دیدن و فکر کردن چون زبانهای دینامیک از این کارها میکنن پس میشه تاهر حدی در این زمینه پیش رفت و هرکاری کرد همینطوری!!
قضاوت و استدلالهای اونا شاید مثل قضاوت و استدلالهای شماست. یعنی افرادی که در این زمینه ها هیچگونه دانش و تخصص و صلاحیتی ندارن. من باز حداقل چیزهایی در این موارد و در زبانهای مختلف خوندم تاحالا و متوجه شدم. چیزی که من تاحالا دیدم و برداشت کردم، همون موارد و استدلالهایی هست که تاحالا براتون گفتم.
نقل قول:
اون که آره ، ولی خب یکم از مقایسه با جاوا اسکریپت آبرومندتره :لبخند:
جاوااسکریپت مگه چشه؟
جاوااسکریپت زبانی با شباهت های ساختاری و نزدیکی کاربرد است که به بحث ما ارتباط دارن. ضمنا استاندارد و تشکیلاتی هم داره واسه خودش! جاوااسکریپت کوچکتر و کم کاربردتر از PHP هست، ولی از نظر ساختاری و استاندارد شدگی و علمی بودن فکر میکنم سرتر از PHP باشه! منم بخاطر همین مسائل و همچنین بلد بودن و در دسترس بودنش ازش بعنوان مثال استفاده کردم.
سی درمقابل، میتونه مقایسهء خیلی دورتری باشه. سی یک زبان برنامه نویسی سیستمی و قدیمی و سطح پایینه (و دیدید که حتی نمیشه مثال و مقایسهء درست و حسابی با PHP ازش درآورد!). درحالیکه PHP یک زبان جدیدتر و سطح بالا برای برنامه نویسی وب است.
از این نظرها جاوااسکریپت نزدیکی بیشتری به PHP داره تا سی.
اصولا هم چون صفحات و برنامه های وب ترکیبی از PHP و JS هستند، از نظر سازگاری کاربردی و یادگیری و برنامه نویسی این یک مزیت است که بین این دو زبان شباهت و رابطهء دوستانه ای برقرار باشه. یعنی طراحان PHP بجای اینکه ور دارن یک چنان چیزهایی رو اونطور باهاش رفتار کنن، اگر یجوری طراحی میکردن که از منطق و رفتار جاوااسکریپت تقلید کنه، میتونست در عمل خیلی مفیدتر باشه. مثلا من خیالم راحت باشه که یه چیزی رو اگر هم در سمت کلاینت و هم در سمت سرور باهاش سروکار دارم، منطق و رفتارشون شبیه همه و میتونم هردو رو به شکل یکسانی پیاده کنم و وقتی بین دو زبان سویچ میکنم مشکل یادگیری و گیج شدن و اشتباه کردن هم کمتر دارم.
-
نقل قول: رفتار دردسرساز switch
نقل قول:
نوشته شده توسط
بهزاد علی محمدزاده
در اینجا از از 10 به بعد نادیده گرفته میشه . در جاوا اسکریپت هم همینه و اصلا بحثی رو این نیست و ربطی به موضوع ما نداره.
خیر در جاوااسکریپت میاد و عدد رو به رشته تبدیل میکنه و دو رشته رو بهم میچسبونه:
<script>
alert(5+"10 Little Piggies");
</script>
البته مقایسه در این نمونه بین جاوااسکریپت و PHP مشکله و شاید بی معنی باشه، چون در جاوااسکریپت + عملگر الصاق رشته ای هم هست، ولی در PHP برای این کار یک عملگر دیگر (.) داره.
نقل قول:
حالا حرف من چیه ؛ ما که از تئوری و دلایل تیمی که php رو طراحی کردن آگاهی کامل نداریم و صرفا فقط از خود زبان داریم استفاده میکنیم و کمی به مستنداتش آگاهی داریم.
مگه PHP زبان بازمتن نیست؟
یعنی منبعی در این مورد نیست؟
یعنی استدلالشون رو بیان نکردن؟
یعنی به کسی ربطی نداشته و دیکتاتوری بوده؟
بعد چطور استدلال و نبوغ برتری داشتن که به ذهن هیچکس دیگری نمیرسه؟
بگردید پیدا کردید خبر بدید خب!
توی یک سایتی مقاله ای بود که از طراحی PHP انتقاد کرده بود و این موارد رو پیش کشیده بود؛ باید روی این مقاله هم حداقل افراد ذیصلاح و حتی مراجع رسمی PHP میامدن و یک بحث و پاسخی میذاشتن. ترجیحا باید بحثی میبود که مخالفان هم بتونن توش شرکت کنن.
نقل قول:
چون این بخشی از تبدیل نوعش هست یا به قول خودشون type-juggling ، یک طرف نوع عددی هست و طرف دیگه نوع رشته که اولش هم عدده ، خب برای جمع باید دو طرف به نوع عددی تبدیل شه دیگه مگه نه؟
خب پیش فرض تو نوع عددی صفره دیگه ، وقتی پیدا نمیکنه پیش فرض 0 در نظر میگیره. خب موقع مقایسه با == هم اول تبدبل میکنه بعد مقایسه
من بحثم اینه که این باگ نیست چون تو مستندات سایت PHP برای == به همه این شبهه ها جواب داده.
اگه قراره باگ تلقی شه ، برای وقتی هست که برنامه نویس بدون آگاهی به type-juggling و == و === بیاد برنامه بنویسه.
یه چیزی درست کردن به اسم type-juggling، بعد میگن دلیل و استدلالش اینه؟!
چطور در زبانهای هم خانوادهء دیگر چنین چیزی نداریم؟
منطق و فایدش چیه اونوقت؟
در زبانهای دیگر هم دینامیک تایپ و تبدیل نوع خودکار داریم، ولی نه دیگه به این صورت عجیب!
اصولا در زبانهای سطح بالا محدودیت های فنی و شکل پیاده سازی معنی ندارن در چنین مواردی؛ بلکه هدف باید منطق روشن و قابل انتظار در سطح برنامه نویسی و احتمال و فایده در اون سطح باشه.
الان چنین مواردی در برنامه نویسی کاربرد خیلی کمی دارن و بعکس چون برای برنامه نویسان منطق اونا روشن و قابل انتظار نیست، باعث بالا رفتن آمار باگ میشن.
هرچه حجم و دشواری یادگیری یک زبان کمتر باشه، و موقع برنامه نویسی نیاز به دقت کمتری برای تامین صحت و امنیت برنامه باشه، اون زبان بهتریه. شک دارید؟
اینا اومدن این چیز عجق وجق رو گذاشتن، فقط حجم و دشواری یادگیری رو زیاد کردن و احتمال باگزایی در برنامه ها رو!
باید بری این قضیه رو حتما بخونی هضم کنی و موقع برنامه نویسی هم مدام حواست باشه و دقت کنی بخاطرش که یوقت باعث ایجاد باگ نشه! این تا اینجا هزینه هاش؛ خب حالا بگید فایده هاش کجاست و چقدره اونوقت؟!
میتونستن براحتی وقتی عددی داره با رشته مقایسه بشه یک چک و شرطی بذارن که اگر رشته حاوی یک عدد نبود، نتیجهء مقایسه false بشه.
اگر این کار رو میکردن چه مشکلی پیش میامد کجای دنیا روی سرمون خراب میشد؟
اتفاقا دیگه یادگیری و آگاهی و دقت نمیخواست و باگهای کمتری در برنامه ها بوجود میامد.
-
نقل قول: رفتار دردسرساز switch
اینطور نیست که به انتقادها و مشکلات جواب ندن. اگه اینطوری بود که قسمتی به اسم bugs.php.net نداشتیم. من خودم این باگ رو گزارش کردم و گفتن درحال بررسی هستن و تا یکی دو روز دیگه جواب میدن. یکبار دیگه هم قبلاً یک باگ رو گزارش کرده بودم که توی Minor Upgrade بعدی، رفع شد و یک License نرم افزار Zend Studio هم بهم هدیه دادن. بهرحال هیچ برنامه ای کامل نیست. مهم اینه که تیم توسعه PHP به گزارشات کاربران اهمیت میده. نه اینکه مثل مایکروسافت باشه که تا وقتی شرکتی به بزرگی گوگل نباشی، جواب ایمیلهای پشتیبانیت رو هم نمیده.
-
نقل قول: رفتار دردسرساز switch
ببین این موردی که من مطرح کردم باگ نیست که توی قسمت باگ و به شکل و با محدودیت های گزارش باگ گزارش کنی.
این یه تصمیمگیری و طراحیه، که استدلال و هدفی پشتش بوده و باید باشه، و نیاز به بحث آزاد و ادامه دار تا مدتی داره، مثل همین کاری که ما اینجا کردیم.
اونا دلایل و اسناد خودشون رو میارن، ما میخونیم، بعد اگر قانع نشدیم دلایل و اسناد و ایرادها و سوالات و ابهامات خودمون رو مطرح میکنیم، و به همین شکل بحث ادامه پیدا میکنه تا یک زمانی به امید اینکه یک طرف قانع بشه یا از موضع خودش مقداری تغییر و اصلاح پیدا کنه، یا شاید هم دو طرف هردو مقداری تغییر و اصلاح بدن مواضع خودشون رو و این وسط به نتیجه و راه حل و تصمیم مشترک دیگری برسن.
خلاصه این یه بحثه. مثل بحث پارلمانی میمونه برای طراحی و تصویب یک قانون جدید، یا زیرسوال بردن و لغو یا اصلاح یک قانون موجود. باید بحث روش صورت بگیره. طرفداران و مخالفان آزادانه درش شرکت کنن. نیاز به زمان و آزادی و محیط و شرایط خودش داره. یوقتهایی نیاز میشه دیگرانی هم مطالبی بیارن، تحقیق بیشتری صورت بگیره و نتیجش ارائه بشه، و غیره. کار راحت و سریعی نیست مسلما!
اگر یک بحث در جای مناسب بصورت آزاد صورت بگیره، فرضا دیگران هم که استدلالها و اسناد دیگری دارن بتونن شرکت کنن، خیلی بهتر میشه. مثلا من از چندتا زبانی که میشناختم مثالهایی آوردم، اما یکی دیگه ممکنه زبانها و مثالهای بهتری رو بشناسه، یکی ممکنه اصلا متخصص طراحی زبانهای برنامه نویسی باشه یا بهرصورت اطلاعاتی از نحوهء تفکر و تصمیمگیری در این موارد داشته باشه و شاید دسترسی به منابع و اسنادی که ما ازشون خبر نداریم.
منهم دیگه در اون حد متخصص این کار نبودم، اما یه چیزایی در طول زمان خونده بودم دیده بودم فهمیده بودم گفتم و از عقل و منطق خودم هم کمک گرفتم.
-
نقل قول: رفتار دردسرساز switch
نقل قول:
من خودم این باگ رو گزارش کردم و گفتن درحال بررسی هستن و تا یکی دو روز دیگه جواب میدن
کدوم باگ رو؟!
من منطق رفتار PHP در مواردی مثل 'hello'==0 رو میگم.
مسلمه که اگر اینو بعنوان باگ گزارش کنی جواب میدن که این یک باگ نیست و خودمون میدونستیم و بر اساس طراحی و منطق خود زبان PHP است.
بحث ما بحث طراحی و منطق اشتباه یا حداقل غیربهینه است، نه باگ.
-
نقل قول: رفتار دردسرساز switch
حالا من اشاره به متخصصان طراحی زبانهای برنامه نویسی کردم، یه فکری بنظرم رسید!
میگم میشه سرچ و تحقیق کرد و یکسری متخصصان طراحی زبانهای برنامه نویسی رو پیدا کنیم و بهشون در این مورد ایمیل بزنیم و نظرشون رو بخوایم.
احتمال زیادی میدم که نظر اونها هم تاحد زیادی با نظر بنده شباهت داشته باشه!
بعید نمیدونم جوابهایی که میدن حال همتون رو بگیره!!
مثلا یکیشون میگه: PHP یک زبان بازمتن است که ابتدا بعنوان یک ابزار شخصی توسط یک فرد غیرمتخصص در امر طراحی زبانهای برنامه نویسی ایجاد شد و سپس به نحو بی قاعده و غیرعلمی ای توسعه پیدا کرد. رفتار این زبان معیاری برای طراحی زبانهای برنامه نویسی نیست و با اصول علمی این رشته سازگاری کافی ندارد!
:لبخند:
جون تو آدمای کار درست و دانشگاه دیده همینطوری صحبت میکنن!
من اینقدر دیدم تاحالا که خوب آشنا هستم با منطق و طرز صحبتشون.
چنین آدمایی کاری ندارن که PHP توسط 90 درصد وبسایتهای دنیا داره استفاده میشه و اینطور حرفا، و فقط از روی علم و منطق حرف میزنن.
اول و آخرش هم به احتمال زیاد داستان همینه.
ولی تمام اینا نباید شما PHP کاران و بازمتن دوستان عزیز رو ناامید کنه، چون در دنیای واقعی بیشتر چیزها ایدئال و بدون ضعف و نقص نیست.
مثلا ممکنه دات نت و زبانهایی مثل سی شارپ در کل بیشتر علمی و روی این اصول باشن، ولی در عمل و در دنیای واقعی اونا هم محدودیت ها و معایب خودشون رو دارن (که گاهی مستقیما به خود زبان هم مربوط نمیشه). محدودیت و عیب که فقط روی بحث طراحی نیست! و خیلی چیزها باوجود بی نقص نبودن کاملا مفید هستن و استفاده میشن، بخصوص که در خیلی شرایط اصلا جایگزین مناسب تری هم براشون وجود نداره.
-
نقل قول: رفتار دردسرساز switch
ببینید، گزارش Bug صرفاً به معنای وجود خطا در طراحی و نحوه کاربرده. من هم بعنوان SPL Problem گزارش کردم و گفتم این رفتار، اون چیزی که اغلب برنامه نویسان انتظار دارن نیست و ممکنه منجر به باگهای امنیتی توی برنامه های کاربران بشه. نه اینکه خودش یک باگه. توصیه هم کردم که switch لااقل مثل بقیه زبانهای Loose Type از strong type comparison استفاده کنه یا یک پارامتر دوم بهش اضافه کنن که هروقت کاربر خواست، بتونه نحوه عملکردش رو تنظیم کنه. اینم متن گزارشیه که فرستادم:
[2013-12-26 06:18 UTC] mmshfe at gmail dot com
Description:
------------
As mentioned in docs, switch statement is a loose type comparison tool. But this may be lead to a serious bug in user products. It would be really better to force it to use strong type comparison (or have an option such as an optional 2nd argument let the users to do so). In the real world, we have no other loose type languages that behaves like this. For example, in JavaScript, the result is fine. I mean, although being a loose type language is a good feature for PHP in overall; It should not be led to unexpected results those not shown in any other language (even the other loose type ones).
Test script:
---------------
$v = 0;
switch($v) {
case 'hello':
echo 'Hello';
break;
case 'Goodbye':
echo 'Goodbye';
break;
default:
echo 'Error';
break;
}
Expected result:
----------------
Error
Actual result:
--------------
Hello
--------------
[2013-12-26 06:29 UTC] mmshfe at gmail dot com
I really now the process flow. It uses if, elseif, else statements like this:
if($v == 'hello') {
echo 'Hello';
}
elseif($v == 'Goodbye') {
echo 'Goodbye';
}
else {
echo 'Error';
}
And 'hello' is converted to integer (with intval('hello') or anything similar) and because it does not contain an integer value at the beginning, it uses the default integer value (zero) and so, the first case becomes true. All I want to say is that this behavior is incorrect because approximately always it's not the behavior that the developer expected.
-
نقل قول: رفتار دردسرساز switch
نه اتفاقاً به استدلالهای دیگران هم کاملاً گوش میدن و اگه درست باشه، عمل هم میکنن. یک قسمت توی نوع گزارش هست که میشه بجای گزارش Bug بگین Feature Change Request هست و دلایلتون رو هم مطرح کنید.
-
نقل قول: رفتار دردسرساز switch
ایول قشنگ براشون توضیح دادی!
خوشم اومد.
ولی بنظر من کلا اینطور شرطها نباید true بشن، نه فقط در switch، بلکه در if هم چنین شرطی نباید true بشه.
عملا switch و if چندان فرقی با هم ندارن و میشه در خیلی موارد اونا رو بجای همدیگر استفاده کرد (در عمل هم میبینیم که در این زمینه برنامه نویسان انتخابهای متفاوت دارن).
بقول خودت این loose type comparison در هیچ زبان دیگری دیگه اینقدر بی بند و بار نیست که 'hello'==0 رو true فرض کنه. نمونه ای سراغ داری خلاف این؟
توضیح رو اگر کلی میدادی، نه اینکه بگی فقط برای switch است و برای سویچ استثناء یا آپشن بذارید، شاید بهتر بود.
گرچه فکر کنم اگر یه جو عقل درست و حسابی داشته باشن همین توضیحات شما هم باید جرقه رو براشون بزنه که بیشتر روی این قضیه از این دیدگاه که مطرح کردی فکر کنن.
ولی من این سابقه رو در یاروهای PHP قبلا احساس کردم که زیاد اهل پذیرفتن و اعتراف به اشتباهات خودشون نیستن. چون درمورد رجیستر گلوبالز دیده بودم این قضیه رو که هیچوقت به اینکه از اساس منطق و طراحی اشتباهی بوده اعتراف نکردن و تا آخر ازش دفاع میکردن!
هرچند امیدوارم حداقل در عمل دیگه اینقدر لجباز و خودبین نباشن و دست به تجدید نظر و اصلاح بزنن.
-
نقل قول: رفتار دردسرساز switch
حالا بحث if رو میشه با توجه به وجود عملگر === توجیه کرد و کاربر هم قطعاً اگه مستندات رو خوب خونده باشه، میدونه که چرا hello'==0' نتیجه true میده ولی انتظار از switch واقعاً type specific بودن هست.