ค่าคอนฟิกในโปรแกรมที่ติดตั้งมาส่วนใหญ่ โดยดีฟอลต์จะถูกตั้งค่ามาให้สามารถรันและใช้งานบนเครื่องทั่วไปได้ ทำให้บางครั้งเมื่อมีปริมาณการใช้งานเพิ่มมากขึ้น อาจจะมีปัญหาในการใช้งาน
ลองมาดูวิธีการตรวจสอบ และแก้ไขปัญหาการอัปโหลดไฟล์ขนาดใหญ่ด้วย PHP ที่รันโหมด FPM ทำงานร่วมกับ nginx เป็นเว็บเซิร์ฟเวอร์กัน ว่าจะต้องแก้ไขคอนฟิกอะไรบ้าง เพื่อให้สามารถอัปโหดลไฟล์ขนาดใหญ่ตามที่เราต้องการได้
ในที่นี้จะใช้โปรแกรม WordPress 4.8.2 ทดสอบบน Ubuntu 16.04 ซึ่งถ้าไม่แก้ไขคอนฟิก จะติดปัญหาการอัปโหลดไฟล์ขนาดใหญ่ เพราะโปรแกรมนี้ถูกพัฒนาด้วยภาษา PHP
ตัวอย่างการทดสอบอัปโหลดไฟล์ขนาดใหญ่ (ประมาณ 64M) ในหน้าจอ Insert Media ของ WordPress
ขึ้นข้อความแถบสีแดงว่า exceeds the maximum upload size for this size
สังเกตข้อความด้านล่างแสดง Maximum upload file size: 2MB
ค่าคอนฟิกที่เป็นตัวกำหนดขนาดไฟล์สูงสุดที่อัปโหลดได้ใน PHP คือ upload_max_filesize โดยดีฟอลต์จากการติดตั้ง จะถูกจำกัดให้สามารถอัปโหลดไฟล์ได้แค่ 2M เท่านั้น
และเนื่องจากการอัปโหลดไฟล์ใน PHP จะเป็นการส่งข้อมูลโดยใช้เมธอดแบบ POST ดังนั้นต้องแก้ไขค่าคอนฟิก post_max_size ด้วย เพราะเป็นค่าที่กำหนดขนาดข้อมูลสูงสุดที่สามารถส่งข้อมูลแบบ POST ได้
ไฟล์คอนฟิก PHP ที่รันโหมด FPM บน Ubuntu 16.04 คือ /etc/php/7.0/fpm/php.ini
เช่นถ้าเราต้องการให้สามารถอัปโหลดไฟล์ได้สูงสุด 128MB เราต้องแก้ไขค่าคอนฟิกทั้งสองค่าให้เป็น 128M เพื่อให้สามารถอัปโหลดไฟล์ได้ขนาดสูงสุด ตามที่เราต้องการได้
alice@u16:~$ sudo vi /etc/php/7.0/fpm/php.ini ; Maximum size of POST data that PHP will accept. ; Its value may be 0 to disable the limit. It is ignored if POST data reading ; is disabled through enable_post_data_reading. ; http://php.net/post-max-size post_max_size = 128M ; Maximum allowed size for uploaded files. ; http://php.net/upload-max-filesize upload_max_filesize = 128M
ใช้คำสั่ง systemctl restart เพื่อรีสตาร์ตเซอร์วิส PHP ที่รันโหมด FPM
alice@u16:~$ sudo systemctl restart php7.0-fpm
รีโหลดหน้าเว็บ WordPress ใหม่ แล้วลองเข้าหน้า Insert Media อีกครั้ง
สังเกตข้อความด้านล่างจะเปลี่ยนเป็น Maximum upload file size: 128MB
กดปุ่ม Select Files ทดลองอัปโหลดไฟล์ขนาดใหญ่อีกครั้ง
ก็ยังไม่สามารถอัปโหลดได้ แต่ข้อความ error ที่แสดงจะเปลี่ยนไป ขึ้น HTTP error แทน
ถึงแม้เราแก้ไขค่าคอนฟิกเพื่อให้อัปโหลดไฟล์ขนาดใหญ่ใน PHP ไปแล้ว แต่ตอนนี้ยังมีปัญหาอีกส่วนหนึ่งคือเว็บเซิร์ฟเวอร์ ซึ่งในที่นี้เราใช้ nginx
เวลาที่เราคิดว่าน่าจะเป็นปัญหาที่เว็บเซิร์ฟเวอร์ nginx แนะนำให้ลองดูไฟล์ /var/log/nginx/error.log
อย่างในปัญหานี้ ในไฟล์ error.log แสดงข้อความ client intended to send too large body
alice@u16:~$ tail /var/log/nginx/error.log
2017/10/19 17:22:44 [error] 3162#3162: *1 client intended to send too large body: 66430314 bytes, client: 192.168.1.2, server: _, request: "POST /wp-admin/async-upload.php HTTP/1.1", host: "192.168.1.1", referrer: "http://192.168.1.1/wp-admin/post-new.php"
เว็บเซิร์ฟเวอร์ nginx จะมีค่าคอนฟิกดีฟอลต์ กำหนดขนาดข้อมูลสูงสุดที่ client จะส่งได้ ซึ่งดีฟอลต์จะกำหนดไว้แค่ 1m เท่านั้น
จากหน้าเว็บของ nginx แสดงการใช้งานค่าคอนฟิก Module ngx_http_core_module
Syntax: client_max_body_size size;
Default: client_max_body_size 1m;
Context: http, server, location
ทดลองเพิ่มค่าคอนฟิก client_max_body_size ภายใต้หัวข้อคอนฟิก http โดยกำหนดไว้ที่ 128m
alice@u16:~$ sudo vi /etc/nginx/nginx.conf
http {
....
client_max_body_size 128m;
รีสตาร์ตเว็บเซิร์ฟเวอร์ nginx
alice@u16:~$ sudo systemctl restart nginx
ทดลองอัปโหลดไฟล์ใน WordPress อีกครั้ง
ตอนนี้ขึ้นอีก error คือ Unable to create directory wp-content/uploads ซึ่งจริงๆ แล้วไม่เกี่ยวกับปัญหาขนาดไฟล์ใหญ่ หรือค่าคอนฟิกแล้วที่เพิ่งแก้ไขไป แต่เป็นเพราะไฟล์ที่ถูกอัปโหลดไป ไม่สามารถบันทึกบนเว็บเซิร์ฟเวอร์ได้ เป็นปัญหาเรื่อง permission
การแก้ไขปัญหานี้ ต้องสร้างไดเรคทอรี uploads และตั้งค่า permission เป็น 777 เพื่อให้เว็บเซิร์ฟเวอร์สามารถเขียนไฟล์ในนี้ได้
alice@u16:~$ cd /var/www/html/wordpress/wp-content/ alice@u16:/var/www/html/wordpress/wp-content$ mkdir uploads alice@u16:/var/www/html/wordpress/wp-content$ chmod 777 uploads/ alice@u16:/var/www/html/wordpress/wp-content$
ทดลองอัปโหลดไฟล์ใน WordPress อีกครั้ง ตอนนี้น่าจะอัปโหลดไฟล์ได้แล้ว
ตัวอย่างไฟล์ที่บันทึกบนเซิร์ฟเวอร์ได้
alice@u16:/var/www/html/wordpress/wp-content/uploads/2017/10$ ls -l
-rw-rw-rw- 1 www-data www-data 67449725 Oct 19 18:28 test.mp4
ในที่นี้ใช้ WordPress ในการทดสอบ แต่โปรแกรมอื่นๆ ที่ถูกพัฒนาด้วยภาษา PHP ก็น่าจะเจอปัญหาคล้ายๆ กัน ลองนำไปใช้แก้ปัญหากันดูครับ