ข้ามไปที่เนื้อหาหลัก

การ Generate XML ด้วย PHP


เป็นการกลับมาเจอกันอีกครั้งกับ CI ( Codeigniter ) งานที่ได้รับมอบหมายคือ ให้เขียนสคริปสร้าง XML Feed จากฐานข้อมูลที่มีจำนวนข้อมูลเยอะๆ ยอมรับเลยครับว่านี่เป็นครั้งแรกที่ได้จับงานแนวๆ นี้ ก็จัดไปครับ ทำการเชื่อมตารางดึงข้อมูลมาทีเดียว แล้วยัดลง SimepleXML แล้วจัดเรียงข้อมูลนิดหน่อย ก่อนนำไปแสดงผลบน Browser ปรากฏว่า บรึ้ม โกโก้ครั้น ใช้หน่วยความจำเยอะจน Server น็อคเอาท์ ละทีนี้ทำไงละ ก็ลองงมๆ ไปอ่านเจอบทความตามลิ้งค์ด้านล่างเข้า



http://narhinen.net/2011/01/15/Serving-large-xml-files.html
http://codeinthehole.com/writing/creating-large-xml-files-with-php/

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

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

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

http://stackoverflow.com/questions/13536032/generating-an-xml-file-with-large-amounts-of-data-and-avoid-memory-cap

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


สุดท้ายนี้ ผมจึงสรุปข้อผิดพลาดของผมออกมาได้ดังนี้
  1. เราไม่จำเป็นต้อง Query ทุกข้อมูลภายในครั้งเดียวเสมอไป ซึ่งบางครั้งจำนวนข้อมูลก็มีมากเกินไป เราสามารถลดทอนได้ด้วยการใช้ Limit ตัดเอาข้อมูลบางช่วงมาทำงานก่อนจากนั้น จึงค่อยๆ ทำในส่วนต่อไปจนถึงข้อมูลชุดสุดท้าย ทำแบบนี่จะช่วยลดการใช้งาน Ram ของ Server
  2. ผมเสียเวลางม และจมอยู่กับการที่ไปแก้ไขเรื่องหน่วยความจำ และเวลาในการเรียกข้อมูลเพื่อรองรับการรันสคริปในระยะเวลานานๆ ซึ่งแท้จริงนั่นไม่ไช่ประเด็นเลย แต่ที่ควรทำ คือ การเขียนอย่างไรให้ไม่ใช้หน่วยความจำมากเกินไป ซึ่งจะได้ตามคำแนะนำในบทความจากลิ้งค์ที่ 3
  3. อย่ายึดติดกับการใช้ประโยชน์จาก PHP ฟังก์ชันมากเกินไป บางทีไม่ได้ศึกษาให้เข้าใจว่ามันมีการใช้หน่วยความจำเยอะหรือไม่? ซึ่งท้ายที่สุด ก็จบด้วยการ echo string ออกมาแบบธรรมดาเลย
ก็เหมือนกับทุกครั้ง สิ่งที่ผมนำมาแชร์นั้น ก็เปรียบเสหมือนเรื่องเล่าประจำวัน อาจจะไม่ได้ถูกที่สุด 100% สามารถโต้แย้งกันได้ตลอดเวลาครับ ผิดพลาดประการใดก็ฝากมา ณ ที่นี้ด้วยครับ

ความคิดเห็น

โพสต์ยอดนิยมจากบล็อกนี้

การเพิ่ม Font ภาษาไทยอื่นๆ เข้าไปใช้งานใน MPDF

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

มาเข้าใจ และใช้ Datatable ดึงข้อมูลแบบ Server-side ด้วย PHP, MySQL กันเถอะ

มีช่วงหนึงผมเคยนำ datatable มาพัฒนาในงานแต่เกิดปัญหาเนื่องจากมีข้อมูลขนาดใหญ่ ทำให้เกิดการโหลดในครั้งแรกที่โหลดหน้าเพจนั้นๆ เนื่องจากผมใช้ Ajax ในการโหลดข้อมูลทั้งหมดมาในครั้งเดียวด้วยจำนวนข้อมูล 1000 ขึ้น ซึ่งตอนนั้นผมคิดว่าการทำ preload น่าจะช่วยได้ แต่ว่าถ้า user เกิดเผลอไปกด refesh หรือแก้ไขข้อมูลเวลากลับมาที่หน้าข้อมูลก็ต้องโหลดใหม่อีก ทำให้ผมเลิกใช้ datatable ไปเลย เพราะคิดว่ามันคงไม่เหมาะ แต่ในความจริงแล้ว datatable ก็ได้มีสิ่งที่มาแก้ในจุดนั้นได้ ซึ่งเรียกว่า server-side โดยการที่อนุญาตให้เรา query ข้อมูลออกมาก่อนแล้วส่งมาให้ datatable อ่านข้อมูลในจำนวนที่น้อยลง หลักการก็เหมือนๆ กับบทความการทำสร้าง XML จากข้อมูลขนาดใหญ่นั่นแหละครับ แต่มีเงื่อนไขเพียงแต่ว่า ต้อง Filter และส่งข้อมูลออกมาในรูปแบบที่ตรงตามหลักของ datatable เท่านั้น ( บางครั้งเวลาเข้าไปอ่าน Document หรือดู Example จะงงๆ ว่าอะไรเยอะแยะ ) โดยวันนี้จะมาแนะนำการใช้งานแบบง่ายๆ กันเลย :D

การใช้งาน คำสั่ง file_exists() อย่างเข้าใจ

นี่อาจจะไม่เรื่องใหม่อะไรสำหรับ Professional ทั้งหลาย แต่ว่าสำหรับผมที่เข้าใจ และใช้งานอย่างผิดๆ มาตลอด จนบางทีก็เข้าใจว่า เราเขียนผิด หรือ คำสั่งมันใช้งานไม่ได้ วันนี้จะขอมาพูดถึงเรื่องของคำสั่ง PHP ที่ชื่อ file_exists เป็นคำสั่งที่ใช้สำหรับตรวจสอบไฟล์ว่ามีอยู่จริงหรือไม่? ตัวอย่างการใช้งานแบบผิดๆ ที่ผมใช้ก็คือ file_exists('/images/news/helloworld.jpg'); ผลลัพธ์ที่ได้คือ FALSE ถึงแม้ว้าจะมีไฟล์นั้นอยู่จริงก็ตาม ซึ่งในความเป็นจริงแล้ว การใช้งานที่ถูกต้องคือ file_exists($_SERVER['DOCUMENT_ROOT'] . '/images/news/helloworld.jpg'); จากตัวอย่างที่ถูกต้อง ทำให้เข้าใจแบบง่ายๆ ว่าคำสั่ง file_exists นั้นใช้สำหรับเช็ค path ในโฟลเดอร์จริงๆ เท่านั้น ไม่สามารถเช็คจาก URL ได้ อันนี้เป็นเรื่องง่ายๆ ที่ผมเข้าใจผิดมาอยู่นานเลยทีเดียวเลยต้องขอลงบันทึกเตือนตัวเองไว้อีกที :3