4 ฟีเจอร์ใหม่ใน PHP 7.4 ที่ช่วยให้เขียนโค้ดสะดวกขึ้น

ในขณะที่เรายังหาทางแก้ปัญหา call to undefined function: mysql_pconnect() กันอยู่ PHP 7.4 รุ่นเสถียรก็ได้ปล่อยออกมาให้เราได้ใช้งานกันแล้วเมื่อวันที่ 28 พฤศจิกายนที่ผ่านมา

ฟีเจอร์หลายๆ อย่างใน PHP 7.4 จะเน้นไปที่การทำให้เราสามารถเขียน PHP ได้สะดวกขึ้น โค้ดกระชับและอ่านง่ายขึ้น และมีฟีเจอร์ด้าน performance เพิ่มมาด้วยเช่นกัน (ส่วน JIT ต้องรอ PHP8 เหมือนเดิมนะ) วันนี้เราจะพาไปดูกันว่าฟีเจอร์ใหม่ๆ ที่น่าสนใจใน PHP 7.4 นั้นมีอะไรบ้าง

Spread operator ในอาเรย์

ใครเขียนจาวาสคริปท์มาก่อนคงจะร้องอ๋อ ส่วนใครที่ไม่เคยเขียน สามารถอธิบายได้สั้นๆ ว่ามันคือการรวมอาเรย์สองตัวเข้าด้วยกันแบบง่ายๆ

ปกติแล้วท่ามาตรฐานที่เราใช้กันก่อนหน้านี้คือใช้ฟังก์ชัน array_merge() เพื่อรวมอาเรย์สองตัว (อย่า foreach เพื่อรวมอาเรย์แบบสมัยผมหัดเขียนใหม่ๆ นะ) ประมาณนี้

<?php
$array1 = ['apple', 'banana', 'citrus'];
$array2 = ['dragonfruit', 'elderberries', 'fig'];

// ท่ามาตรฐาน
$fruits = array_merge( $array1, $array2 );

// ท่าที่ไม่ควรทำ
foreach ( $array2 as $value ) {
  $array1[] = $value;
}

ด้วย Spread operator จะทำให้เราสามารถรวมอาเรย์สองตัวเข้าด้วยกันได้ง่ายๆ เพียงแค่ใส่ ... นำหน้าตัวแปรเข้าไปแบบนี้

<?php
$array1 = ['apple', 'banana', 'citrus'];
$array2 = ['dragonfruit', 'elderberries', 'fig'];

// Spread operator ใน PHP 7.4
$fruits = [...$array1, ...$array2];

ในกรณีที่อาเรย์ของเราเป็นแบบ $key => $value จะมีข้อจำกัดอยู่อย่างหนึ่งคือมันจะใช้ได้เฉพาะกับคีย์ที่เป็นตัวเลขเท่านั้น ส่วนคีย์ที่เป็นข้อความจะไม่สามารถใช้งานได้ และถ้าทั้งสองอาเรย์มีคีย์เหมือนกัน มันจะขึ้นคีย์ใหม่ให้ ไม่ได้แทนค่าเหมือนอย่างใน array_merge()

<?php
// คีย์เป็นตัวเลขแบบนี้ ใช้ได้
$array1 = [
  1 => 'apple',
  2 => 'banana',
  3 => 'citrus',
];

// คีย์เป็นข้อความแบบนี้ ใช้ไม่ได้
$array2 = [
  'fruit1' => 'dragonfruit',
  'fruit2' => 'elderberries',
  'fruit3' => 'fig'
];

Arrow function

คนเขียนจาวาสคริปท์ร้องอ๋อกันอีกแล้ว แต่จริงๆ arrow function ของ PHP จะต่างกับของจาวาสคริปท์อยู่ตรงที่มันจะเป็น one-line statement เท่านั้น ลากปีกกาครอบเป็นฟังก์ชันเต็มๆ ไม่ได้

ส่วนที่เหมือนกันกับในวาจาสคริปท์คือเรื่องของสโคปตัวแปร โดยปกติตัวแปรในฟังก์ชันนั้นจะอยู่ในสโคปของตัวเอง ถ้าเราต้องการใช้ตัวแปรที่อยู่นอกฟังก์ชัน ต้องประกาศ use ก่อน แบบนี้

<?php
$array = [1, 2, 6, 9, 17];
$factor = 10;

$multiplied = array_map( function( $value ) use ( $factor ) {
  return $value * $factor;
}, $array );

จากโค้ดตัวอย่างจะเห็นว่าแค่เราจะคูณเลขนิดเดียว แต่ต้องเขียนโค้ดยาวเหยียด (จริงๆ ผมว่ามันก็อ่านง่ายดีนะ) ใน PHP 7.4 เราสามารถ refactor โค้ดข้างบนให้สั้นลงได้ ด้วยการใช้ arrow function แทน

<?php
$array = [1, 2, 6, 9, 17];
$factor = 10;

$multiplied = array_map( fn($value) => $value * $factor, $array );

สั้นลงเนอะ

ไวยากรณ์ของ arrow function ใน PHP 7.4 จะเป็น fn( $params ... ) => return statement คือ statement ที่อยู่ข้างหลัง => จะเป็นค่าที่เราจะ return ออกจากฟังก์ชันเลย

และถ้าสังเกตุก็จะพบว่าใน return statement ของ arrow function เราสามารถเรียกใช้ตัวแปร $factor ที่อยู่นอกสโคปได้ในทันทีด้วย นั่นเพราะว่า arrow function จะสามารถเข้าถึงตัวแปรในสโคปที่มันอยู่ได้ทันที

Null Coalescing Assignment Operator

ชื่อยาวจัง เอาเป็นว่ามันคือการเช็คค่าตัวแปรและกำหนดค่าเริ่มต้นให้ตัวแปรนั้นๆ

คือการจะเช็คว่าตัวแปรมีคือหรือเปล่าเนี่ย มันมีหลายท่ามาก ไล่ได้ประมาณนี้

<?php
// สมัยโบราณ
if ( !isset( $name ) ) {
  $name = 'John Doe';
} 

// สมัยก่อน
$name = isset( $name ) ? $name : 'John Doe';

// สมัย PHP7 เรามี Null Coalescing Operator แล้ว
$name = $name ?? 'John Doe';

โค้ดทั้งหมดมีผลลัพธ์เดียวกัน คือตรวจสอบว่าตัวแปร $name มีค่าหรือไม่ ถ้ามีให้ใช้ค่านั้นเลย แต่ถ้าไม่มีให้กำหนดค่าลงไปว่า John Doe

ใน PHP 7.4 เจ้า ?? หรือ Null Coalescing นี้ ได้เพิ่มเวอร์ชัน Assignment ทำให้เราสามารถประกาศค่าตัวแปรและเช็ค null ได้โดยตรงเลยแบบนี้

<?php
// สมัย PHP 7.4
$name ??= 'John Doe';

จากตัวอย่างก็คือถ้าสมมุติ $name มีค่าอยู่แล้ว ก็จะใช้ค่าเดิมต่อไป แต่ถ้าไม่มีค่า ก็จะใช้ค่าเป็น John Doe แทน

รองรับ Type hinting ใน class properties

PHP โดนแซะมาอย่างยาวนานเรื่อง type hinting (เมื่อก่อนมันไม่มีด้วยซ้ำ) ทำให้อัปเดตหลังๆ ที่เน้นปรับปรุงตัวภาษานี้ มีเพิ่มฟีเจอร์เกี่ยวกับ type hinting เข้ามาถี่มาก และล่าสุดก็คือ type hinting ใน class properties

มันก็ตรงตัวมาก นั่นคือ properties ในคลาส สามารถกำหนด type hinting ได้แล้ว

<?php
namespace App;

class MyClass {
  // ล็อคค่าเป็น string เท่านั้น
  public string $name;

  public function __construct() {
    // กำหนดค่าเป็น bool แบบนี้พัง
    $this->name = false;

    // กำหนดค่าเป็น string แบบนี้ใช้ได้
    $this->name = 'WP63';
  }
}

type ที่สามารถใช้ได้ก็คือ bool, int, float, string, array, object, iterable, self, parent, รวมไปถึงชื่อคลาสและอินเตอร์เฟซต่างๆ

การกำหนด type hinting (ในแบบรวมๆ เลย) ​คือการบอกว่าค่าที่รับเข้ามา (หรือส่งออกไป) จะต้องเป็นตัวแปรประเภทที่กำหนดเท่านั้น ถ้าไม่ใช่มันก็จะพ่น error ออกมา

อ้าว แบบนี้ error เยอะขึ้นสิ แล้วมันดียังไง? เอาจริงๆ คือมันช่วยให้โปรแกรมเราบั๊กน้อยลงนะ คือเวลาโปรแกรมเราติดบั๊กเนี่ย นอกจากพวกลืมใส่เซมิโคลอนแล้ว ก็มี data type ของตัวแปรนี่แหละที่ก่อบั๊กมากมายมหาศาล อย่างฟังก์ชันบางตัว อาจจะคืนค่าออกมาเป็น int 0 หรือ bool false หรือ string null พวกนี้ถ้าตรวจค่าแบบ non-strict คือมันได้ผลออกมาเหมือนกันหมดเลยนะ

จะบอกว่าเราใช้ strict comparison (เครื่องหมาย ===) ตรวจสอบเอามันก็ได้ แต่ในหลายๆ ครั้งเรามักจะลืม หรือตรวจสอบไม่ครบ ดังนั้นล็อคประเภทข้อมูลไปเลยแน่นอนที่สุด

แถม: Preload ไฟล์ที่ใช้บ่อยเอาไว้ใน memory!

จริงๆ อันนี้ไกลตัวนิดนึง เพราะเราต้องแก้คอนฟิกของเซิร์ฟเวอร์ด้วย แต่รู้ไว้ไม่เสียหาย เผื่อใครต้องไปรันเซิร์ฟเวอร์เอง

คือปกติแล้วเวลาเราเปิดเว็บขึ้นมา ไฟล์ต่างๆ จะถูกเรียกใช้งานเป็นครั้งๆ ไป พอประมวลผลเสร็จก็เตะออกจากแรม ในขณะที่ไฟล์บางไฟล์นั้นมีการเรียกใช้บ่อยมาก การดึงเข้า ประมวลผล และเตะออกซ้ำๆ วนไปแบบนี้ทุกครั้งที่มี request เข้ามา ก็ทำให้เสียเวลาและแรมไปโดยใช่เหตุ

PHP 7.4 แก้ปัญหานี้ด้วยฟีเจอร์ Preload

การที่เราจะใช้ฟีเจอร์พรีโหลดได้ เราต้องเขียนสคริปท์พรีโหลดขึ้นมาไฟล์นึง (ไฟล์ .php ธรรมดานี่แหละ) และในไฟล์นี้ให้ include หรือใช้ opcache_compile_file() เรียกไปยังไฟล์ที่เราต้องการจะพรีโหลด จากนั้นเปิดไฟล์ php.ini ไปแก้ไขค่าตัวเลือก opcache.preload ให้ชี้ไปที่ไฟล์พรีโหลดของเรา เป็นอันเสร็จ

เมื่อเรามีสคริปท์พรีโหลดแล้วและทำการ start server ขึ้นมา PHP จะไปดึงเอาไฟล์พวกนี้มาเก็บเอาไว้ใน memory ตลอดเวลา เมื่อโค้ด PHP ของเรามีการเรียกใช้ไฟล์พวกนี้ ก็จะไม่ต้องเสียเวลาไปดึงเข้าดึงออกใหม่ แต่จะมีพร้อมใช้ได้เลยในแรม ทำให้โดยรวมโค้ดของเราจะทำงานได้เร็วขึ้น

แต่ว่าเมื่อเราพรีโหลดไฟล์เข้ามาแล้ว ไฟล์เวอร์ชันที่ถูกพรีโหลดจะค้างอยู่ในแรมตลอดเวลา ถ้าเราแก้ไขไฟล์นี้ ไฟล์ในแรมจะไม่ถูกแก้ไขไปด้วย ทางเดียวที่จะโหลดไฟล์เวอร์ชันใหม่เข้าแรมก็คือต้อง restart server ใหม่


PHP 7.4

ต้องบอกว่า PHP 7.4 เป็นอะไรที่ใหม่มาก และน่าจะต้องใช้เวลาอีกอย่างน้อยๆ เดือนหรือสองเดือน ถึงจะเริ่มเห็นโฮสต์ต่างๆ เริ่มรองรับ (แม้แต่ Cloudways และสแต็คคู่บุญอย่าง XAMPP ก็ยังรองรับถึงแค่ PHP 7.3 ในตอนที่เขียนโพสต์นี้อยู่)

ใครที่ต้องการลอง PHP 7.4 ตอนนี้ สามารถติดตั้งได้ผ่าน package manager ต่างๆ เช่น Homebrew ของแมค หรือ apt ของ Debian/Ubuntu ส่วนใครใช้วินโดวส์ จะไปดาวน์โหลด binary จากเว็บ PHP หรือติดตั้งผ่าน chocolatey หรือผ่าน WSL ก็ได้ตามที่สะดวกเลย

จริงๆ ยังมีอัปเดตอีกเพียบ สามารถอ่านตัวเต็มได้จาก PHP.net ครับ


Posted

in

by

Tags:

Comments

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.