ติดตามบทความล่าสุดของผู้เขียนได้ที่ phpinfo() Facebook Page
การใช้ตัวแปรในสตริง (String Interpolation)
บทความนี้เขียนขึ้นจากการสังเกตเห็นสมาชิกในไทยครีเอทหลายๆ คนนิยมและบอกต่อให้ใช้การเชื่อมต่อสตริง แทนที่จะใช้ตัวแปรในสตริง ทั้งๆ ที่ความสามารถนี้เป็นอะไรที่ทำให้ PHP (หรือภาษาอื่นที่มีความสามารถนี้เช่น Perl และ Ruby) มีจุดเด่น
บ่อยครั้งที่ผมเห็นหลายๆ คนนิยมเขียนโค้ดลักษณะนี้
$sql = "SELECT * FROM table";
$sql .= "WHERE id = '" . $id . "'";
ซึ่งก็มาจากการแนะนำบอกต่อกันมาว่าแบบนี้ดี ทำให้อ่านง่าย เห็นชัด
อันนี้ผมไม่เถียงครับ แต่ผลที่ตามมาในหลายๆ กระทู้ที่ผมสังเกต
วิธีเขียนแบบนี้นี่แหละที่ทำให้มือใหม่หลายๆ คนออกมาตั้งกระทู้ถามว่า "ฉันเขียนผิดตรงไหน"
เพราะการเขียนแบบเชื่อมต่อสตริง ทำให้เกิดข้อผิดพลาดได้ง่าย หากไม่ใช่คนที่คุ้นเคยกับ PHP
หรือช่างสังเกต อาจจะไม่รู้เลยว่าผิดตรงไหน อะไรยังไง
เช่น
$sql = "UPDATE table SET name = '" . $name . "', color = '" . $color . "'";
$sql .= "type = '" . $type . "' WHERE id = '" . $id . "'";
ลองหาที่ผิดดูครับ
วิธีที่เรียบง่ายกว่า แต่ไม่นิยมใช้กันเพราะ "ความเชื่อ"
เคยเป็นที่ถกเถียงกันในเว็บนักพัฒนาต่างประเทศว่าการเชื่อมต่อสตริงนั้น "ทำงานได้เร็วกว่า" การใช้ตัวแปรในสตริง
แต่หลังจากนั้นก็มีการทดสอบจนได้ผลว่า การเชื่อมต่อสตริงทำงานเร็วกว่าในกรณีที่ "มีการเชื่อมต่อแค่ครั้งเดียว"
แต่ถ้ามีมากกว่านั้นการใช้ตัวแปรในสตริงจะทำงานได้เร็วกว่า
$a = "Hello World $str";
$b = "Hello World " . $str; // เร็วกว่า
$a = "Hello World $str !!!";
$b = "Hello World " . $str . " !!!"; // แต่แบบนี้ไม่
และยิ่งไปกว่านั้น หากมีตัวแปรมากขึ้นเท่าไหร่ ความเร็วการทำงานก็จะต่างกันมากขึ้นเท่านั้น
$sql = "UPDATE table SET name = '" . $name . "', color = '" . $color . "'";
$sql .= ", type = '" . $type . "' WHERE id = '" . $id . "'";
$fastSQL = "UPDATE table SET name = '$name', color = '$color', type = '$type' WHERE id = '$id'"; // แบบนี้เร็วกว่ามาก
และความเชื่ออีกอย่างคือ คิดว่าการเชื่อมต่อสตริงทำให้อ่านง่ายกว่า
ลองมาดูกันชัดๆ ครับ
การเชื่อมต่อสตริง
$sql = "INSERT INTO table";
$sql .= "(first_name, last_name, username, password)";
$sql .= "VALUES ('" . $first_name . "','" . $last_name . "'"
$sql .= ",'" . $username . "','" . $password . "')";
การใช้ตัวแปรในสตริง
$sql = "
INSERT INTO table
(first_name, last_name, username, password)
VALUES
('$first_name','$last_name','$username','$password')
";
สำหรับคนอื่นผมไม่รู้ แต่สำหรับผมเองแล้ว แบบหลังอ่านและเขียนง่ายกว่าเยอะ (ทำงานได้เร็วกว่ามากด้วย)
อีกเหตุผลที่ไม่นิยมใช้ตัวแปรในสตริง อาจเป็นเพราะคนส่วนใหญ่ไม่เข้าใจรูปแบบการใช้
อีกเหตุผลที่ผมเดาเอาคือ เพราะไม่เข้าใจการใช้งานที่ถูกต้อง เลยต้องเปลี่ยนไปใช้การเชื่อมต่อสตริง
ผมเชื่อว่าหลายๆ คนต้องเคยมีปัญหาแบบนี้
echo "Test $item[0]['name']";
แล้วแสดงผลไม่ได้ตามต้องการ อาจจะแสดงผลเป็นคำว่า Array['name'] แล้วไม่เข้าใจว่าเกิดอะไรขึ้น
หรือ
echo "Test $item['name']";
แล้วเกิด Error
Parse error: syntax error, unexpected T_ENCAPSED_AND_WHITESPACE
ทั้งๆ ที่ echo "Test " . $item['name']; กลับใช้ได้ จึงทำให้เปลี่ยนไปใช้การเชื่อมต่อสตริง เพราะกลัวจะเกิด error อีก
และทำให้เกิดรูปแบบการเขียนโปรแกรม PHP ที่ไม่ดีขึ้นมาอีก 1 อย่างคือ
การนิยมย้ายค่าตัวแปรจาก array ให้เป็นตัวแปรเดี่ยวๆ ก่อนนำไปใช้งาน
โดยที่ไม่ได้เปลี่ยนแปลงค่าของมัน (เช่น escape หรือคำนวณเป็นค่าอื่น)
ใช้การเขียนแบบนี้เพียงเพื่อให้ใช้ในสตริงได้ง่ายๆ
$id = $_POST['id'];
$name = $_POST['name'];
$address = $_POST['address'];
$sql = "INSERT INTO users VALUES ('$id', '$name', '$address')";
ซึ่งเป็นวิธีการเขียนที่สิ้นเปลืองทั้งเวลา และทรัพยากร (มีตัวแปรในหน่วยความจำเยอะแยะไปหมด)
ทั้งๆ ที่ควรเขียนแบบนี้
$sql = "INSERT INTO users VALUES ('$_POST[id]', '$_POST[name]', '$_POST[address]')";
มาทำความเข้าใจรูปแบบโดยละเอียดกัน
การใช้ตัวแปรในสตริง (String Interpolation) ในภาษา PHP นั้น
จะเป็นการใช้สัญลักษณ์ $ ในสตริงแบบ Double Quote หรือ HereDoc
$a = 123;
$b = 456;
$c = 789;
echo "a = $a, b = $b, c = $c\n";
echo <<<DOC
a = $a
b = $b
c = $c
DOC;
แบบที่ 1 ใช้ชื่อตัวแปรตรงๆ
$a = 555;
echo "a is $a.";
แบบที่ 2 เข้าถึงสมาชิกใน array 1 มิติ โดยใช้ index
$a = array(123, 456, 789);
echo "สมาชิกตัวแรกของ a คือ $a[0] ตัวที่ 2 คือ $a[1] และสุดท้ายคือ $a[2]";
และต้องเป็นตัวเลขจำนวนเต็มเท่านั้น เป็นจุดทศนิยมไม่ได้ เพราะจะเกิด Error
$a = array(123, 456, 789);
echo "สมาชิกตัวแรกของ a คือ $a[0] ตัวที่ 2 คือ $a[1.0] และสุดท้ายคือ $a[2.0]";
// Parse error: syntax error, unexpected '.'
แบบที่ 3 เข้าถึงสมาชิกใน array 1 มิติ โดยใช้ key
รูปแบบคือ $array[key]
$ages = array('david' => 45, 'sally' => 20, 'john' => 31);
echo "David is $ages[david] years old\n";
echo "Sally is $ages[sally] years old\n";
echo "John is $ages[john] years old\n";
โดย key นั้นต้องไม่มี ' ล้อมรอบ และไม่มีช่องว่างหรือเครื่องหมายอื่นๆ นอกจากตัวอักษร
$stages = array('Level 1' => 'Forest');
echo "Welcome to stage 1 $stages[Level 1] !!!"; // Parse error: syntax error, unexpected T_ENCAPSED_AND_WHITESPACE
แบบที่ 4 เข้าถึงสมาชิกใน array หลายมิติ หรือเข้าถึงสมาชิกที่ key มีช่องว่างและตัวอักษรพิเศษ
รูปแบบคือ {$array['key1']['key2']}
สังเกตดูนะครับ เมื่อไหร่ที่เราใช้รูปแบบนี้ เราต้องล้อมรอบ key ที่เป็นสตริงด้วย ' (แต่ index ไม่ต้อง)
$users = array(
array(
'name' => 'Jack',
'MAC address' => '01:23:45:67:89:AB',
),
array(
'name' => 'Mike',
'MAC address' => '51:47:DF:EE:4C:13',
),
);
echo "User 1: {$users[0]['name']} - {$users[0]['MAC address']}\n";
echo "User 2: {$users[1]['name']} - {$users[1]['MAC address']}\n";
สำหรับการเข้าถึงตัวแปรในสตริงในแบบนี้ มันก็เหมือนกับการเชื่อมต่อสตริงนั่นแหละครับ เพียงแต่เขียนสั้นและอ่านง่ายกว่ามาก
ลองเปรียบเทียบดู
$users = array(
array(
'name' => 'Jack',
'MAC address' => '01:23:45:67:89:AB',
),
array(
'name' => 'Mike',
'MAC address' => '51:47:DF:EE:4C:13',
),
);
// แบบเชื่อมต่อสตริง
echo "User 2: " . $users[0.5 + 0.5]['name'] . " - " . $users[floor(0.3)]['MAC' . ' address'] . "\n";
// แบบนี้ไม่ต้องเปิดปิดสตริงให้เสียเวลา ลดความความเสี่ยงที่จะเกิดความผิดพลาดด้วย
echo "User 2: {$users[0.5 + 0.5]['name']} - {$users[floor(0.3)]['MAC' . ' address']}\n";
บทความที่เกี่ยวข้อง
ศึกษาเพิ่มเติม
ติดตามบทความล่าสุดของผู้เขียนได้ที่ phpinfo() Facebook Page