PHP7 คีย์โน๊ตสำคัญจากงาน phpConf จาก Rasmus Lerdorf

เมื่อสัปดาห์ก่อนผมไปร่วมงาน PHPConf.Asia 2015 ที่สิงคโปร์มาครับ งานนี้ก็มีคนดังหลายคนมาพูด หนึ่งในนั้นก็คือ Rasmus Lerdorf ผู้คิดค้นภาษา PHP ขึ้นมา สไลด์ที่ใช้ในการนำเสนอ อยู่ที่นี่ (Click) สไลด์นี้ใช้ประกอบเนื้อหาที่อธิบายในโพสนี้เลยครับ

ช่วง Keynote

สิ่งที่รัสมูตมาพูดในงานในช่วง Keynote วันแรกเกี่ยวกับ PHP7 ว่ามีอะไรใหม่บ้าง (คนละแนวกับ Pierre ตอนที่มาพูดใน Thailand PHP User Group Meetup #1 / BKK Meetup / Code Mania)

รัสมูตบอกว่า แรกเริ่มเดิมทีเมื่อปี 1995 (20 ปีแล้ว) เค้าโพสลง Newsgroup ว่าเค้าสร้างเครื่องมือสำหรับช่วยสร้าง Personal Home Page ขึ้นมา คือนึกสภาพถึงตอนปีนั้นนะครับ คือคนเขียนเว็บถ้าไม่เขียนเป็น Static Content ก็ต้องหัดเขียน CGI ให้เป็น ใช้ Perl ได้ ซึ่งคนทั่วไป มาแตะ Perl ก็เกิดอาการมึนๆ ได้ เขาก็เลยเขียนเครื่องมือด้วยภาษา C เพื่ออ่านและแปลผลสคริปต์อีกที ทำให้การเขียนเว็บทำได้ง่ายขึ้นมาก และนั่นก็กลายเป็น PHP นั่นเอง

แต่ไหนแต่ไร PHP นั้นไม่ได้เกิดมาเพื่อโปรแกรมเมอร์ตัวพ่อที่สามารถเขียนโลกทั้งใบได้ด้วยภาษาอะไรก็ได้อยู่แล้ว แต่กลับเป็นกลุ่มที่อาจจะไม่เคยเขียนโปรแกรมมาก่อนเลย

PHP มีจุดเปลี่ยนที่สำคัญอยู่หลายครั้ง เช่น จากตอน PHP 4 > PHP 5 > PHP 5.3 ส่วน PHP 6 ก็แท้งก่อนคลอด จึงเป็นที่มาของการที่เรามีเวอร์ชั่นต่อไปของ PHP เป็นเวอร์ชั่น 7

แคชระดับสอง

สำหรับ PHP7 นั้น เป้าหมายหลักนั้นเพื่อแข่งขันกับ HHVM โดยเฉพาะ มีการปรับส่วนเมมโมรี่ให้ใช้งานน้อยลง ทำงานได้ไวขึ้น มีการสร้างไฟล์เป็นแคชระดับสอง สำหรับ Opcode. (ถ้าเทียบเคียงกับ Java มันก็คือพวกไฟล์ .class) ดูภาพประกอบ

PHP7 Secondary File-based cache
PHP7 Secondary File-based cache

จากภาพจะเห็นว่ามีไฟล์ index.php.bin โผล่มาด้วย ตรงนี้คือไฟล์ที่เป็นแคชนั่นเอง ซึ่งถ้ามีการอ่านโค้ดเข้า Interpreter แล้ว จะถูกโหลดเก็บไว้ใน SHM OpCache ทำให้สามารถทำงานได้เร็วขึ้นประมาณ 10 เท่า

— ตามความเข้าใจผม มันก็คือเหมือนกับ APC / Zend OpCache cache นั่นเอง แต่จุดที่แตกต่างเห็นจะเป็นแคชทั้งสองเลเวลถูกนำมาใช้ในโหมด CLI ด้วย (ปกติเวลาพิมพ์คำสั่งผ่าน Command Line มันจะไม่ได้ใช้ Opcode Cache) ตรงนี้ต้องเข้าใจว่า index.php.bin นี่ไม่เหมือน Bytecode ซะทีเดียว เพราะว่า PHP จะไม่ทำ JIT (Just-in-time Compiler) ตรงนี้ควรมองเป็นแคชระดับไฟล์มากกว่า

Abstract Syntax Tree

มี Abstract Syntax Tree แล้ว ตรงนี้เขาบอกว่าในส่วนเครื่องมือจำพวก Code Static Analyser จะทำงานได้ง่ายขึ้น

PHP7 AST

Return Type

รวมถึงส่วนที่รอคอยก็คือระบุประเภทของ Return Type ได้แล้ว

php7 return type
php7 return type

คือในเวอร์ชั่นก่อนๆ ตัวแปรไม่จำเป็นต้องกำหนดประเภทเลย ด้านหนึ่งคือมันง่ายมาก ใช้ยังไงก็ได้ และนั่นเป็นจุดขายของ PHP แต่ในระยะยาว มันกลับกลายเป็นมะเร็งของ PHP เสียเอง ที่ทำให้ Programmer บางส่วนไม่อยากเข้ามาจับ สิ่งที่ PHP พยายามทำในเวอร์ชั่นต่อจากนี้ จะไม่ได้เป็นการทำเพื่อคนเริ่มต้นเขียนโปรแกรมอีกต่อไป แต่จะเป็นการทำคีโมรักษาส่วนที่กลายเป็นจุดอ่อนของ PHP เอง

Strict Scalar Type

ส่วนของ scalar type ก็สามารถประกาศได้แล้ว รวมถึงใช้ Static Analysis เช็คได้ด้วย

Scalar Type

ตรงนี้สำคัญ ก็คือว่า มันไม่ได้ทำงานอัตโนมัติ ไม่อย่างนั้นจะเกิดปัญหากับโค้ดชุดเก่าๆ มากมาย เพราะว่าโค้ดชุดเก่าๆ เราไม่เคยเขียนเพื่อระบุ Type เลย ดังนั้น ถ้าหากโปรเจคของเราทำขึ้นมาใน PHP7 โดยเฉพาะ และต้องการใช้คุณสมบัติอย่างเต็มที่ จะต้องประกาศ declare(strict_types=1) เพื่อบอกว่า เราจริงจังนะ กับการระบุ Type นี้ ไม่อย่างนั้นจากภาพตัวอย่าง ตรง Function Singnature เรารับ $msg เป็น String แม้ว่าเราส่ง Inteter เข้าไป มันจะทำการ Casting เป็น String ให้อัตโนมัติ

Exceptions on Fatals

ตัว  Fatal Error มักจะเป็นปัญหาใน PHP version ก่อนๆ จากคนเขียนเองที่ไม่ได้ตรวจสอบตัวแปร ว่ามันเป็น Object หรือเปล่า และเนื่องจากมันเป็นอะไรก็ได้ ดังนั้น มันอาจจะไม่ได้เป็นอะไรเลย

Fatal error: Call to a member function method() on a non-object

ตอนนี้ เราสามารถ Try / Catch มันได้แล้ว

PHP7 - Fatal Exception
PHP7 – Fatal Exception

Deprecated Functions

นอกจากการปรับแต่งเพิ่มความแข็งแรงของภาษาแล้ว ฟังก์ชั่นที่ประกาศเลิกใช้งาน ก็ถูกกำจัดออกด้วย ลิสต์ยาวเป็นหางว่าวเลยทีเดียว

- ext/ereg (use ext/pcre instead)
- preg_replace() eval modifier (use preg_replace_callback() instead)
- ext/mysql (use ext/mysqli or ext/pdo_mysql instead)
- Assignment of new by reference
- Scoped calls of non-static methods from incompatible $this context

- dl() in php-fpm
- set_magic_quotes_runtime() and magic_quotes_runtime()
- set_socket_blocking() (use stream_set_blocking() instead)
- mcrypt_generic_end() (use mcrypt_generic_deinit() instead)
- mcrypt_ecb, mcrypt_cbc, mcrypt_cfb and mcrypt_ofb 
  (use mcrypt_encrypt() and mcrypt_decrypt() instead)
- datefmt_set_timezone_id() and IntlDateFormatter::setTimeZoneID() 
  (use datefmt_set_timezone() or IntlDateFormatter::setTimeZone() instead)

- xsl.security_prefs (use XsltProcessor::setSecurityPrefs() instead)
- iconv.input_encoding, iconv.output_encoding, iconv.internal_encoding,
  mbstring.http_input, mbstring.http_output and mbstring.internal_encoding
  (use php.input_encoding, php.internal_encoding and php.output_encoding instead)

- $is_dst parameter of the mktime() and gmmktime() functions
- # style comments in ini files (use ; style comments instead)
- String category names in setlocale() (use LC_* constants instead)
- Unsafe curl file uploads (use CurlFile instead)
- PDO::PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT driver option 
  (use PDO::ATTR_EMULATE_PREPARES instead)
- CN_match and SNI_server_name stream context option (use peer_name instead)

ตรงนี้บล็อก Somkiat.cc มีเขียนอธิบายไว้เพิ่ม….

Size of Internal Structure

มาดูด้านโครงสร้างข้างใน PHP บ้าง เพื่อให้มันเร็วขึ้น โครงสร้างข้อมูล (zval) จึงถูกปรับแต่งให้ขนาดเล็กลง การปรับแต่ง ส่งผลโดยตรงกับ PHP Extension จะต้องคอมไฟล์ใหม่ทั้งหมดใน PHP7 ดังนั้น ถ้าใครมีใช้ Extension ในเวอร์ชั่นก่อนๆ ต้องดูรายละเอียดให้ดีว่ามีซัพพอร์ตใน PHP7 หรือยัง

PHP7 - Internal Structure zval changed
PHP7 – Internal Structure zval changed

 

ประสิทธิภาพ

— เข้าใจว่าหลักๆ ของการประสิทธิภาพของความเร็วเกิดขึ้นจากการที่ไปศึกษาลักษณะของ PHP App แล้วมา Profiling PHP ให้เหมาะสมมากขึ้น รวมถึงการเปลี่ยนขนาด Internal Structure ที่พูดถึงก่อนหน้าด้วย ซึ่งส่งผลให้ขนาดเมมโมรี่ที่ใช้นั้นลดลงอย่างมีนัยสำคัญ

ประเด็นเรื่องประสิทธิภาพนี้ ต้องการจะนำมาแข่งขันกับ HHVM โดยเฉพาะ ถ้าหากดูจากสไลด์ จะพบว่าทั้ง PHP7 และ HHVM ประสิทธิภาพยังแข่งขันในระดับสูสี ไม่ได้เรียกว่า PHP7 นำโด่ง หรือ HHVM นำโด่ง และก็ยังขึ้นอยู่กับตัวแอพลิเคชั่นที่นำมาใช้ด้วย บางตัว PHP7 นำ ในขณะที่บางตัว HHVM ยังนำอยู่

ความน่าสนใจและตลกไปพร้อมๆกัน คือ ตัวของ PHP เอง สามารถคอมไพล์ โดยทำการ Optimized ตัว PHP เองจากโค้ดของ PHP ได้ด้วย ในสไลด์นั้น เค้ายกตัวอย่างของ WordPress ขึ้นมา ด้วยการ จูน PHP7 ให้มีความเร็วยอดเยี่ยมโดยเฉพาะ เมื่อใช้กับ WordPress โดยใช้วิธีคอมไพล์แบบ GCC Feedback-Directed Optimization (FDO) [สไลด์]

make clean
make -j8 prof-gen
...
sapi/cgi/php-cgi -T 1000 /var/www/wordpress/index.php > /dev/null
make prof-clean
make -j8 prof-use

(ใช้ WordPress index.php รันจำนวน 1000 ครั้งแล้วทำการจูน PHP ให้เข้ากับ WordPress)

วิธีการนี้เป็นการขูดรีดพลังเฮือกสุดท้ายขึ้นมาได้ ตรงนี้เค้าแค่พูดสั้นๆ ขำๆ เพราะว่าประสิทธิภาพเมื่อรัน WordPress ด้วย PHP7 นั้นมันยังช้ากว่า HHVM อยู่นิดหน่อย เลยแบบว่าบอกว่า จริงๆ มันขูดพลังได้อีกนิดหน่อยนะ อะไรอย่างนี้ จากภาพจะเห็นว่า ถ้าใช้ PHP7 มันจะได้ Req/sec อยู่ 627 พอขูดรีดพลังเฮือกสุดท้าย ได้อยู่ที่ 664 ตามหลัง HHVM อยู่ 2 req/s

php7 WordPress Benchmark
php7 WordPress Benchmark

การเปรียบเทียบประสิทธิภาพ หลักๆ เค้าใช้ Framework / CMS ที่มีอยู่ในท้องตลาดมาทำการเปรียบเทียบ ตรงนี้ผมขอไม่ลงรายละเอียดเพิ่มนะครับ ไปอ่านต่อใน Slide เลยจ้า

 

 

Vagrant Box

รัสมูตเองมี Vagrant Box สำหรับให้ใครก็ได้โคลนไปลองเล่น ข้างใน บรรจุเครื่องมือสำหรับคอมไฟล์ PHP เอาไว้แล้ว สามารถเอาไปลองเล่นกับ PHP7 ได้เลย จริงๆ เครื่องมือสำหรับลองเล่นกับ PHP มีอยู่หลายตัว ใน Sitepoint มีกล่าวถึงไว้แล้ว ตรงนี้คนที่เป็น QA ควรไปหามาลองเล่น เพื่อตรวจสอบดูว่าเมื่อเราต้องปรับไปใช้ PHP7 แล้ว แอพของเรามีอะไรที่เป็นปัญหาหรือต้องปรับเปลี่ยนหรือไม่ ข้อดีของ Vagrant Box ที่รัสมูตทำไว้คือ มันสามารถ Switch เวอร์ชั่น PHP ที่จะใช้ได้ง่ายมาก พร้อมกับทิ้งท้ายไว้ว่า อย่าลืมทดสอบกันนะจ๊ะๆๆ ถ้ามีปัญหาอะไรก็รีบบอกมา จะได้รีบแก้ให้ ก่อนที่ PHP7 Release แล้วก็มาบ่นกันว่ามีบัก ดังนั้น ตอนนี้รีบเอาไปช่วยเทสนะจ๊ะ

 

Warp up

สรุปแล้ว PHP7 นั้น เน้นเรื่องความเร็วที่พยายามจะถีบตัวเองขึ้นมา ยุบโครงสร้างที่ใหญ่เกินไปให้เล็กแล้วใช้เมมโมรี่น้อยลง โละทิ้งพวกฟังก์ชั่นเก่าแก่ที่ไม่สนับสนุนให้ใช้ต่อแล้วทิ้ง กับเพิ่มความแข็งแรงกับวิธีการใช้ภาษาแบบใหม่ๆ ตามเทรนที่กำลังเป็นที่นิยมเพิ่มเข้ามา

ระยะเวลาเคลื่อนตัวคงต้องอาศัยเวลาอย่างน้อยๆ สามปี กว่าจะเริ่มขยับเวอร์ชั่นกันทั้งอุตสาหกรรม (3 ปีคือระยะเวลา Supported ของ PHP แต่ละเวอร์ชั่น) หรือพูดง่ายๆว่า 3 ปี เวอร์ชั่นที่ออกตอนนี้ทั้งหมด มันจะตายเรียบร้อย (PHP 5.4, 5.5, 5.6) ซึ่งตอนนี้ PHP 5.4 ก็ตายนำไปแล้ว ไม่มีแพชออกมีอีกต่อไป

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

การปรับมา PHP7 นอกเหนือจาก Deprecated Function แล้ว มีรูปแบบ Syntax ที่เพิ่มและปรับเปลี่ยนนิดหน่อย ดูในส่วน Backward Incompatible Change ส่วนตัวผมว่า การปรับ Major Version ครั้งนี้ทำได้ดีกว่าสมัยก่อนอยู่ที่ค่อนข้างกระอักเลือด

สุดท้าย PHP7 กำลังจะออกในไม่กี่วันข้างหน้าแล้ว ใครสร้างโปรเจคใหม่ก็ลองเข้าไปลุยเลย ส่วนของเก่า ถ้าไม่มีเทส อย่ารีบลุยเข้าไปเปลี่ยนเด็ดขาดนะจ๊ะ ใครเปลี่ยนแล้วได้ผลเป็นยังไง มาคอมเม้นต์ทิ้งไว้ด้วย

 

ขอบคุณ

ขอบคุณบริษัทของผมเองที่ช่วยสปอนเซอร์ค่าใช้จ่ายในการไปสิงคโปร์ส่วนหนึ่งให้ด้วย ส่วนที่เหลือก็เป็นเงินส่วนตัว นี่อาจจะเรียกว่าเป็นครั้งแรกในการเสียเงินเดินทางไป Conference ต่างประเทศระยะเวลาสั้นๆ ที่เสียเงินหลักหมื่น ถามว่าคุ้มมั๊ย มันคุ้มครับ สิ่งที่คุ้มนั้นไม่ใช่การที่ไปนั่งฟัง Speaker พูด แต่เป็นเสื้อของแถม เอ้ย!…. แต่เป็นการที่ได้ไปพูดคุยกับกลุ่ม PHP User Group ในแถบ South-East Asia และก็คนที่มีความสนใจแบบเดียวกัน ทำงานในบริษัท และใช้ PHP ใน Enterprise เช่นเดียวกัน

 

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

 

6 thoughts on “PHP7 คีย์โน๊ตสำคัญจากงาน phpConf จาก Rasmus Lerdorf

  • 2015-10-05 at 10:46
    Permalink

    ขอบคุณครับที่ช่วยสรุป เข้าใจง่ายดีครับ ^^

    Reply
  • 2015-10-18 at 02:52
    Permalink

    ชอบบทส่งท้ายที่สุดเลยอ่ะค่ะ

    Reply
  • 2015-12-05 at 23:52
    Permalink

    “มี Abstract Syntax Tree แล้ว” ?

    Abstract Syntax Tree ไม่ใช่ feature นะ แต่เป็นโครงสร้างข้อมูลที่ได้จากการ parse
    ซึ่งตรงกันข้ามกับ Concrete Syntax Tree

    Reply
    • 2015-12-06 at 08:00
      Permalink

      ขอบคุณครับที่ช่วยขยายความให้ :)

      Reply
  • 2016-06-19 at 19:17
    Permalink

    ผมเป็นคนหนึ่งที่รัก PHP มาก เพราะมันทำให้ผมมีรายได้ ^__^

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *