เงื่อนไขในการเขียนโปรแกรม เป็นการกำหนดเส้นทางการทำงานของโปรแกรมตามที่เราต้องการ เราสามารถกำหนดการทำงานได้จาก ผลลัพท์ของการเปรียบเทียบ หรือ การคืนค่าของฟังก์ชั่น
คำสั่งเงื่อนไขในภาษา PHP มี 2 คำสั่งคือ
if... elseif... else... switch... case...
เงื่อนไข if… elseif… else… จะถูกแบ่งเป็น 3 แบบใหญ่ๆ คือ
- มีเงื่อนไขเดียว
- มีสองเงื่อนไข
- มีหลายเงื่อนไข
แบบเงื่อนไขเดียว จะทำงานก็ต่อเมื่อเงื่อนไขเป็นจริงเท่านั้น รูปแบบการเขียนคือ
<?php if (เงื่อนไข) { // ทำงานในส่วนนี้เมื่อเงื่อนไขเป็นจริง } // ตัวอย่าง $a = 10; if ( 2 < 5 ) { echo "สองน้อยกว่าห้า"; } if ($a + 5 < 20) { echo "สิบบวกห้าน้อยกว่ายี่สิบ"; } ?>
จะเห็นได้ว่า เราสามารถทำการคำนวนในเงื่อนไขได้ โปรแกรมจะทำการหาผลลัพท์จากการคำนวนก่อน จากนั้นจึงทำการเปรียบเทียบ ถ้าหากผลการเปรียบเทียบเป็นจริง จึงจะทำงานในส่วนของเงื่อนไข แต่ถ้าหากเงื่อนไขเป็นเท็จ จะข้ามส่วนเงื่อนไขนี้ไป
แบบสองเงื่อนไข เมื่อเงื่อนไขเป็นจริง จะทำงานในส่วน if แต่ถ้าเงื่อนไขเป็นเท็จจะทำงานในส่วน else
<?php if (เงื่อนไข) { // ทำงานเมื่อเงื่อนไขเป็นจริง } else { // ทำงานเมื่อเงื่อนไขเป็นเท็จ } // ตัวอย่าง $a = 10; if ($a < 10) { echo "เงื่อนไขเป็นจริง"; } else { echo "เงื่อนไขเป็นเท็จ"; } ?>
ไม่ยากใช่ไหมครับ คล้ายๆ กับแบบเงื่อนไขเดียว คือจะทำงานก็ต่อเมื่อเงื่อนไขเป็นจริง แต่เพิ่มการทำงานเมื่อเงื่อนไขเป็นเท็จด้วย ทำให้การทำงานของโปรแกรมเพิ่มเป็น 2 ทาง
แบบหลายเงื่อนไข การทำงาน 2 แบบแรก จะมีการเปรียบเทียบเงื่อนไขเพียงเงื่อนไขเดียว แต่ถ้าหากเราต้องการเปรียบเทียบหลายๆ เงื่อนไข โดยแต่ละเงื่อนไขจะทำงานไม่เหมือนกัน สามารถเขียนได้ดังนี้
<?php if (เงื่อนไข 1) { // ทำงานเมื่อเงื่อนไข 1 เป็นจริง } elseif (เงื่อนไข 2) { // ทำงานเมื่อเงื่อนไข 2 เป็นจริง } elseif (เงื่อนไข 3) { // ทำงานเมื่อเงื่อนไข 3 เป็นจริง } elseif (เงื่อนไข n) { // ทำงานเมื่อเงื่อนไข n เป็นจริง } else { // ทำงานเมื่อเงื่อไขข้างบนเป็นเท็จทั้งหมด } ?>
ลองมาดูโปรแกรมตัดเกรดง่ายๆ กัน
<?php $score = 79; if ($score > 80) { echo "Grade A"; } elseif ($score > 70) { echo "Grade B"; } elseif ($score > 60) { echo "Grade C"; } elseif ($score > 50) { echo "Grade D"; } else { echo "Grade F"; } ?>
ผลลัพท์ที่ได้คือ Grade B แล้วทำไมถึงเป็นแบบนี้ ในเมื่อเงื่อนไขอื่นๆ ก็เป็นจริงเหมือนกัน แต่ทำไมผลลัพท์ที่ได้ จึงเป็นแค่ Grade B เพราะการทำงานของ if..elseif.. เมื่อเจอเงื่อนไขที่เป็นจริงแล้ว จะทำงานที่เงื่อนไขนั้น และข้ามการทำงานของเงื่อนไขอื่นๆ ไป
นอกจากนั้น เรายังสามารถใช้เงื่อนไขซ้อนเงื่อนไขได้ด้วย ลองดูตัวอย่างครับ
<?php $a = 25; if ($a < 100) { if ($a < 50) { echo "a น้อยกว่า 50"; } else { echo "a มากกว่า 50"; } } ?>
จะเห็นว่า เราสามารถซ้อนเงื่อนไขกี่ชั้นก็ได้ ตามใจเรา (มากกว่านี้ก็ได้ครับ) แต่ในชีวิตจริงแล้ว สัก 3 – 4 ชั้น ก็เริ่มแย่แล้วล่ะครับ ตอนหา Jordan Matrix แทบแย่เลย
งั้นถ้าเราลองเขียนโดยไม่ใช่เครื่องหมายปีกกาล่ะ? ก็จะได้ตัวอย่างแบบนี้
<?php if (expression1) if (expression2) statement1; else statement2; // ลองเขียนใหม่ เผื่อจะเข้าใจง่ายขึ้น // แบบที่ 1 if (expression1) if (expression2) statement1; else statement2; // แบบที่ 2 if(expression1) if (expression2) statement1; else statement2; ?>
จากตัวอย่างข้างบนเป็นปัญหาของโปรแกรมเกือบทุกภาษา ปัญหานี้เรียกว่า Dangling else ถ้ามองโจทย์เป็นแบบที่ 1 ก็จะมองได้ว่า else เป็นของ if ตัวนอก แต่ถ้าเป็นแบบที่ 2 จะมองได้ว่า else เป็นของ if ตัวข้างใน ซึ่งการเขียนทั้ง 2 แบบ ถูกต้องตามหลักไวยากรณ์ของ if..else.. ทุกอย่าง แล้วปัญหานี้ โปรแกรมจะแก้ไขอย่างไร?
บางภาษาเช่น Ada จะมีการจบ if ด้วย end if ทำให้ไม่มีปัญหานี้เกิดขึ้น แต่ภาษา php ไม่มีการจบ if โปรแกรมจะถือว่า else ตัวใดๆ จะเป็นของ if ตัวที่อยู่ใกล้ที่สุด จะทำให้โปรแกรมไม่มีทางสับสน แต่คนเขียนนี่แหละจะสับสนเอง…
ทางแก้ปัญหาที่ (ผมคิดว่า) ถูกต้องคือ ใส่ block ให้มันซะ ไม่ว่าคำสั่งที่ทำงานหลังจาก if จะมีแค่คำสั่งเดียวก็ตาม เพราะนอกจากโปรแกรมจะดูเป็นระเบียบแล้ว ถ้าหากเรากลับมาอ่านทีหลัง จะไม่สับสนเอง แล้วยังกำหนดการทำงานได้ตามต้องการด้วย
<?php // ลองเขียนใหม่ if (expression1) { if (expression2) { statement1; } } else { statement2; } // else เป็นของ if ตัวแรก ไม่ใช่ if ที่อยู่ใกล้ที่สุด if(expression1) { if (expression2) { statement1; } else { statement2; } } // else เป็นของ if ตัวที่สอง ?>
ฝึกให้เป็นนิสัยเลยครับทุกๆ ครั้งที่เขียนเงื่อนไขให้ใส่ block ด้วย แม้ว่าจะทำงานแค่คำสั่งเดียวก็ตาม
เงื่อนไข switch… case…
switch… case… จะว่าไปมันก็ไม่เชิงเป็นเงื่อนไข เนื่องจากต้องมีการกำหนดค่าที่แน่นอนของตัวเลือก ไม่เหมือนกับ if ที่สามารถกำหนดเป็นช่วง หรือเป็นการคำนวนได้ ทำให้หลายๆ ภาษาอย่างเช่น Python ตัด switch… case… ออกไป รูปแบบการเขียนจะเป็นดังนี้
<?php $web = "cmdevhub"; switch ($web) { case: "cmdevhub" : echo "http://www.cmdevhub.com"; break; case: "pantip"; echo "http://www.pantip.com"; break; default: echo "ไม่ได้เลือกเว๊ป"; break; } ?>
จะเห็นว่าทางเลือกของ switch… case… นั้น จะมีเพียงทางเดียว ซึ่งจะว่าไป ก็ไม่ค่อยจะมีประโยชน์สำหรับโปรแกรมระดับสูงเท่าไหร่ ผมจำได้ว่าครั้งสุดท้ายที่เขียนโปรแกรมแล้วใช้ switch… case… แบบจริงจัง ก็เขียนภาษา C บน Dos แล้วจับแป้นลูกศรทั้ง 4 ตัวล่ะครับ
แต่ถ้าหากเรารู้ค่าที่แน่นอนและเส้นทางที่แน่นอน การใช้ switch… case… จะเป็นทางเลือกที่ดีมากกว่า if เนื่องจากเมื่อพบเปรียบเทียบแล้ว จะข้ามไปทำงานตามสิ่งที่ switch เจอเลยถ้าไม่พบ จะไปทำที่ default: แทน แต่ถ้าเป็น if จะทำการเปรียบเทียบไปเรื่อยๆ จนครบ ถ้าหากมีเงื่อนไขมากก็ต้องเปรียบเทียบจนครบ อันนี้ก็แล้วแต่ความเหมาะสมของโปรแกรมครับ
ตอนหน้าก็จะเป็นเรื่องคำสั่งวนรอบ (loop) ล่ะครับ