[Update] วิธีการเพิ่มขนาดอัปโหลดไฟล์ในเว็บไซต์บนสภาพแวดล้อม Nginx + PHP-FPM

หากใช้งาน Nginx + PHP-FPM ในการรันเว็บไซต์ แล้วเจอปัญหาการอัปโหลดไฟล์โดยมี Error แจ้งเตือนว่า "413 Request Entity Too Large" แบบนี้ สามารถแก้ไขได้ง่ายๆ โดยเพิ่มขนาดการอัปโหลดไฟล์ให้เพียงพอต่อการอัปโหลดในสภาพแวดล้อมที่กำลังใช้งานอยู่ ก็จะไม่เกิด Error ดังกล่าว ในบทความนี้จะมาแนะนำเนื้อหาไปพร้อมกับการใช้งานจริง

สวัสดีครับ POP จากบริษัท Classmethod (Thailand) ครับ

เราสามารถเพิ่มขนาดอัปโหลดไฟล์ในสภาพแวดล้อม Nginx + PHP-FPM ได้ตามต้องการ
ครั้งนี้จะกำหนดให้สามารถอัปโหลดไฟล์ได้มากกว่า 8MB โดยอัปโหลดได้สูงสุด 30MB ครับ

เป้าหมาย

เราจะเพิ่มขนาดการอัปโหลดไฟล์ในสภาพแวดล้อม Nginx + PHP-FPM

สิ่งที่ต้องมี

เตรียมสภาพแวดล้อมการเรียกใช้ PHP โดยใช้ Nginx บน EC2 Instance

  • ติดตั้ง EC2 Instance (Amazon Linux 2023) สำหรับใช้กับ Nginx และเชื่อมต่อกับ Instance ด้วย PuTTY หรือ Remote – SSH ใน VSCode แล้ว (ครั้งนี้จะใช้ VSCode)
    • กรณีเชื่อมต่อด้วย PuTTY จะใช้ Key pair .ppk
    • กรณีเชื่อมต่อด้วย Remote – SSH ใน VSCode จะใช้ Key pair .pem (แนะนำให้ใช้ Elastic IP เพื่อไม่ให้เกิดการเปลี่ยนแปลง Public IPv4 address เมื่อมีการ Stop/Start EC2 Instance)
  • ติดตั้ง PHP 8.2 และ Nginx ใน Amazon Linux 2023 และตั้งค่าการใช้งาน Nginx แล้ว

ดูตัวอย่างได้ที่ลิงก์ด้านล่างนี้

เตรียมไฟล์ทดสอบอัปโหลด

สามารถดาวน์โหลดไฟล์ตัวอย่างได้จากเว็บไซต์ทั่วไป โดยครั้งนี้จะใช้ไฟล์ทดสอบการอัปโหลดดังนี้

  • ขนาดไม่เกิน 2MB (ตัวอย่างคือ 0.99MB = 1,018KB)
  • ขนาดมากกว่า 8MB (ตัวอย่างคือ 28.5MB = 29,276KB

สร้างไฟล์ form.php

รันคำสั่งสร้างไฟล์ form.php

vi form.php

แล้วกดปุ่ม i ให้แสดง -- INSERT -- ด้านล่างซ้ายสุด แล้วคัดลอก code ด้านล่างนี้วางลงไป
แล้วกดปุ่ม Esc ตามด้วยพิมพ์ :x เพื่อบันทึก

<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  </head>
  <body>
    <form action="upload.php" method="post" enctype="multipart/form-data">
      file: <br />
      <input type="file" name="upfile" size="30" /><br />
      <br />
      <input type="submit" value="Upload" />
    </form>
  </body>
</html>

สร้างไฟล์ upload.php

รันคำสั่งสร้างไฟล์ upload.php

vi upload.php

แล้วคัดลอก code ด้านล่างนี้ลงไปเหมือนกับขั้นตอนที่แล้ว และทำการ save ครับ

<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  </head>
  <body>
    <p><?php

        if (is_uploaded_file($_FILES["upfile"]["tmp_name"])) {
          echo "file size =" . $_FILES["upfile"]["size"];
        } else {
          echo "error";
        }

    ?></p>
  </body>
</html>

ทดสอบอัปโหลดไฟล์

ในตัวอย่างนี้จะใช้ไฟล์สำหรับทดสอบอัปโหลดขนาดดังนี้

  • ขนาดไม่เกิน 2MB (ตัวอย่างคือ 0.99MB = 1,018KB)
  • ขนาดมากกว่า 8MB (ตัวอย่างคือ 28.5MB = 29,276KB)

เมื่อสร้างไฟล์ form.php และ upload.php เสร็จแล้ว ให้เปิดหน้าเว็บไซต์โดยใช้ Public IPv4 address ของ EC2 Instance ดังนี้

http://[Public IPv4 address]/form.php

แล้วจะแสดงหน้าจอแบบนี้

ต่อไปจะเป็นขั้นตอนการทดสอบอัปโหลดไฟล์

อัปโหลดไฟล์ขนาดไม่เกิน 2MB

ต่อไปจะทดสอบอัปโหลดไฟล์ขนาด 0.99MB = 1,018KB

คลิก Choose File แล้วเลือกไฟล์ที่ไม่เกิน 2MB และคลิก Upload

จะเห็นว่าแสดงเป็น file size=1042157 (0.99MB = 1,018KB) หมายความว่าเราสามารถอัปโหลดไฟล์ได้ตามปกติ

อัปโหลดไฟล์ขนาดมากกว่า 8MB

ต่อไปคลิก กลับมาที่หน้าเว็บไซต์ form.php เพื่อเตรียมอัปโหลดไฟล์ในขั้นตอนถัดไป
แล้วทดสอบอัปโหลดไฟล์ขนาด 28.5MB = 29,276KB

คลิก Choose File แล้วเลือกไฟล์ที่มากกว่า 8MB และคลิก Upload

จะเห็นว่าเกิด Error "413 Request Entity Too Large" เนื่องจากไฟล์มีขนาดใหญ่กว่าที่ค่าเริ่มต้นของระบบ Nginx ได้กำหนดไว้
เราสามารถเข้าไปตั้งค่าเพิ่มขนาดอัปโหลดไฟล์ด้วยตัวเองได้ง่ายๆ ในขั้นตอนถัดไป

เพิ่มขนาดอัปโหลดไฟล์ใน Nginx

ครั้งนี้จะเพิ่มขนาดการอัปโหลดไฟล์ให้กับ Nginx เป็น 30M

รันคำสั่ง vi เข้าไปที่ไฟล์ nginx.conf

vi /etc/nginx/nginx.conf

แล้วคัดลอก code ด้านล่างนี้วางลงในส่วนของ server แล้วทำการ save

client_max_body_size 30M;
client_body_buffer_size 30M;

TERMINAL (VSCode)

"...ไม่ได้แสดง code ส่วนล่าง..."

    server {
        listen       80;
        listen       [::]:80;
        server_name  _;
        root         /var/www/html;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        error_page 404 /404.html;
        location = /404.html {
        }

        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
        }

        client_max_body_size 30M;
        client_body_buffer_size 30M;
    }

"...ไม่ได้แสดง code ส่วนล่าง..."


แล้วรันคำสั่ง Restart Nginx

systemctl restart nginx


แล้วเปิดหน้าเว็บไซต์ form.php และลองอัปโหลดไฟล์ที่มีขนาดมากกว่า 8MB อีกครั้ง

http://[Public IPv4 address]/form.php

จะเห็นว่าเปลี่ยนเป็น Error ตามเงื่อนไขที่เขียนไว้ในไฟล์ upload.php เนื่องจากการตั้งค่ายังไม่เสร็จสมบูรณ์ ให้ทำการตั้งค่าเพิ่มเติมในขั้นตอนถัดไป

ตั้งค่าเพิ่มเติม

ต่อไปรันคำสั่ง vi เข้าไปที่ไฟล์ php.ini

vi /etc/php.ini

แล้วค้นหาชื่อตามด้านล่างนี้เพื่อเปลี่ยนการตั้งค่าให้เป็น 30M ดังนี้
・พิมพ์ /upload_max_filesize + Enter แบบนี้แล้วกดปุ่ม i แล้วเปลี่ยนให้เป็น 30M และกดปุ่ม Esc
・พิมพ์ /post_max_size + Enter แล้วกดปุ่ม i แล้วเปลี่ยนให้เป็น 30MB เมื่อเสร็จแล้วทำการ save ได้เลย

upload_max_filesize = 30M
post_max_size = 30M
upload_max_filesize
post_max_size

แล้วรันคำสั่ง Restart PHP-FPM

systemctl restart php-fpm


แล้วเปิดหน้าเว็บไซต์ form.php และลองอัปโหลดไฟล์ที่มีขนาดมากกว่า 8MB อีกครั้ง

http://[Public IPv4 address]/form.php

จะเห็นว่าแสดงเป็น file size=29977967 (28.5MB = 29,276KB)
เพียงเท่านี้ก็สามารถอัปโหลดไฟล์ขนาดมากกว่า 8MB ได้แล้ว

สรุป

ผมได้มีโอกาสทำงานเกี่ยวกับการเขียนโปรแกรมมาบ้าง และตอนเขียนโปรแกรมเกี่ยวกับการอัปโหลดไฟล์จะเจอปัญหานี้บ่อย จึงได้นำมาเขียนลงในบทความนี้ให้กับผู้อ่านที่เจอปัญหาเดียวกับผมครับ

ผมหวังว่าบทความนี้จะเป็นประโยชน์ให้กับผู้อ่านได้นะครับ

POP (Tinnakorn Maneewong) จากบริษัท Classmethod (Thailand) ครับ !

บทความที่เกี่ยวข้อง