PHP

Home

PHP Tutorial
Knowledge Developer Database Internet Resource
การอัพโหลด
1. อัพโหลดไฟล์
2. ฟอร์มอัพโหลด
 
PHP ระดับสูง
1. การอัพโหลด
2. ฟังก์ชันเมล์และเครือข่าย
3. วันที่และเวลา
4. กราฟฟิกและภาพ
 
PHP
PHP เบื้องต้น
การสร้างโปรแกรมประยุกต์เว็บ
PHP ระดับสูง
 
Internet
PHP
SSI
HTML
AJAX
 
PHP ระดับสูง > การอัพโหลด

ฟอร์มอัพโหลด

การทำงานหนึ่งของ PHP ที่มีประโยชน์มากคือ สนับสนุนการอัพโหลด HTTP ตามปกติใช้ฟอร์ม HTML ตามตัวอย่างในภาพ 3.1.1


ภาพ 3.1.1 ฟอร์ม HTML สำหรับโหลดไฟล์

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

ในการอัพโหลดไฟล์ ต้องใช้ไวยากรณ์ HTML เฉพาะวัตถุประสงค์ HTML สำหรับฟอร์มนี้ได้รับการแสดงในรายการคำสั่ง 18.1

รายการคำสั่ง 3.1.1 คำสั่งของไฟล์ simple_upload.html

 

<form action="simple_upload.php" method="post" enctype="multipart/form-data">
<table width="400" border="0">
<tr>
<td width="100">อัพโหลดโดย</td>
<td><input name="username" type="text" size="30" maxlength="60"/>
<input name="MAX_FILE_SIZE" type="hidden" value="50000"/> </td>
</tr>
<tr>
<td>ไฟล์ข้อความ</td>
<td><input name="textfile" type="file" id="textfile"></td>
</tr>
<tr>
<td>ภาพ</td>
<td><input name="imagefile" type="file" id="imagefile"/></td>
</tr>
<tr>
<td>&nbsp;</td>
<td><input type="submit" name="Submit" value="upload"/></td>
</tr>
</table>
</form>

หมายเหตุ    ฟอร์มนี้ใช้ POST การอัพโหลดไฟล์ทำงานได้กับเมธอด PUT ที่สนับสนุนโดย Netscape Composer และ Amaya ซึ่งไม่ทำงานกับ GET

ส่วนการทำงานพิเศษในฟอร์ม คือ

  • ใน <form> tag  ต้องตั้งค่าคุณลักษณะ enctype="multipart/form-data" เพื่อให้แม่ข่ายทราบว่าไฟล์กำลังมากับสารสนเทศฟอร์มปกติ
  • กำหนดขนาดไฟล์อัพโหลดด้วยฟิลด์ MAX_FILE_SIZE เป็นฟิลด์ซ่อน
    <input name="MAX_FILE_SIZE" type="hidden" value="50000"/>
  • ต้องมี input ของประเภทไฟล์ ดังนี้
    <input name="userfile1" type="file" id="textfile">
    <input name="userfile1" type="file" id="imagefile">

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

คำสั่งด้านแม่ข่าย

การเข้าถึงไฟล์อัพโหลดสามารถอ่านได้ผ่าน superglobal array ชื่อ $_FILES ที่เก็บ 1 element ด้วยคีย์ชื่อเดียวกับฟิลด์ <input> จากไฟล์ HTML และเก็บค่าเป็นสารสนเทศของการอัพโหลด

ตามตัวอย่างข้างบน ฟอร์ม HTML มีฟิลด์ชื่อ userfile จะส่งผ่านไปยัง PHP ด้วย 4 ตัวแปร

  1. $userfile เก็บไฟล์ชั่วคราวบนแม่ข่ายเว็บ
  2. $userfile_name เก็บชื่อไฟล์บนระบบของผู้ใช้
  3. $userfile_size เก็บขนาดของไฟล์เป็นไบต์
  4. $userfile_type เก็บประเภท MIME ของไฟล์เช่น text/plain, image/jpg

ค่าที่เข้าถึงได้ $_FILES array เป็นดังนี้

$_FILES['userfile']['tmp_name'] ="z:/web_uploads/phpc7.tmp"
$_FILES['userfile']['name'] = "widelogo.jpg"
$_FILES['userfile']['size'] = "24000"
$_FILES['userfile']['type'] = "image/jpg"
$_FILES['userfile']['error'] = "0"

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

ขั้นตอนการประมวลผลไฟล์อัพโหลด มีดังนี้

  1. ดูรหัสความผิดพลาดที่เกิดจากการอัพโหลด
  2. ถ้ารหัสความผิดพลาดชี้ว่าการอัพโหลดเรียบร้อย ให้ทำการตรวจสอบหรือสแกนไวรัส
  3. จากนั้นให้ย้ายไฟล์ไปยังปลายทางที่ต้องการจัดเก็บ

รหัสความผิดพลาดใน $_FILES array แสดงในตาราง 3.1.2

ตาราง 3.1.2 ค่าของ $_FILES['error']

รหัส ค่า คำอธิบาย

UPLOAD_ERR_OK

1

การอัพโหลดเสร็จสมบูรณ์

UPLOAD_ERR_INI_SIZE

2

ขนาดไฟล์ใหญ่กว่าค่าของ upload_max_filesize ในไฟล์ php.ini

UPLOAD_ERR_FORM_SIZE

3

ขนาดไฟล์ใหญ่กว่าค่าที่ระบุในฟิลด์ MAX_FILE_SIZE ของฟอร์ม

UPLOAD_ERR_PARTIAL

4

ไฟล์อัพโหลดไม่เสร็จสมบูรณ์ (ส่วนใหญ่เกิดจากการใช้เวลามากเกินและถูกตัดออก)

UPLOAD_ERR_NO_FILE

5

ไม่มีไฟล์อัพโหลดกับคำขอ

UPLOAD_ERR_NO_TMP_DIR

6

ไม่มีการระบุไดเรคทอรีชั่วคราวในไฟล์ php.ini (รหัสเพิ่มใน php 5.0.3)

ถ้าไม่มีความผิดพลาด สามารถทำการสแกนไวรัส ตรวจสอบประเภทไฟล์ เช่น ตรวจสอบว่าเป็นประเภทไฟล์ภาพหรือไม่ เป็นต้น
เมื่อทราบว่าไฟล์อยู่ที่ไหนและเรียกว่าอะไร จากนั้นคัดลอกไปยังพื้นที่จัดเก็บในระบบไฟล์ ได้ ฟังก์ชันในการคัดลอกสามารถใช้ copy(), rename() รวมถึง move_uploaded_file() ที่ทำให้มั่นใจว่าการอัพโหลดไปยังแม่ข่ายเว็บ เมื่อสิ้นสุดการประมวลผลสคริปต์ ไฟล์ชั่วคราวจะถูกลบ

สคริปต์ตัวอย่าง simple_upload.php ทำการอัพโหลดไฟล์ข้อความและไฟล์ภาพ ทำการตรวจสอบและแยกการจัดเก็บตามประเภท

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

<?php

function messageError($in_error)
{

switch ($in_error)
{

case UPLOAD_ERR_INI_SIZE:
case UPLOAD_ERR_FORM_SIZE:
    echo "ขนาดไฟล์ใหญ่กว่าข้อกำหนด";
    break;
case UPLOAD_ERR_PARTIAL:
    echo "การโหลดไฟล์ไม่สำเร็จ";
    break;
case UPLOAD_ERR_NO_FILE:
    echo "ไม่ได้รับไฟล์";
    break;
case UPLOAD_ERR_NO_TMP_DIR:
    echo "ไม่มีได้กำหนดไดเรคทอรีอัพโหลด";
    break;
default:
    echo "ไม่ทราบสาเหตุความผิดพลาด";
    break;

}

}

function canUpload($in_err)
{

if ($in_err == UPLOAD_ERR_OK)
  return TRUE;
else
  return FALSE;

}

function uploadType($filename)
{

$ext = strtolower(pathinfo($filename,PATHINFO_EXTENSION));

switch ($ext)
{
// ตรวจสอบประเภทไฟล์

case 'txt':
    return 1;
    break;
case 'doc':
    return 2;
    break;
case 'rtf':
    return 2;
    break;
case 'jpg': case 'jpeg':
    return 3;
    break;
case 'gif':
    return 3;
    break;
case 'png':
    return 3;
    break;
case 'bmp':
    return 3;
    break;
default:
    echo "ประเภทไฟล์ไม่ถูกต้อง";
    return FALSE;

}

}

if (canUpload($_FILES['textfile']['error']))
{

$get_type = uploadType($_FILES['textfile']['name']);

if ($get_type == 1 || $get_type == 2)
    moveFile("../data/", $_FILES['textfile']['name'], $_FILES['textfile']['tmp_name']);

}
else
    messageError($_FILES['textfile']['error']); 

// คำสั่งอัพโหลดไฟล์ภาพ ...

}
?>

ส่วนหลักสคริปต์ คือ

ตรวจสอบความผิดพลาดการอัพโหลดด้วยฟังก์ชัน canUpload() ที่ใช้พารามิเตอร์ คือ $_Files['error'] ถ้าพารามิเตอร์เท่ากับ UPLOAD_ERR_OK ส่งค่าเป็น TRUE กรณีอื่น เป็น FALSE

ตรวจสอบประเภทไฟล์ด้วยฟังก์ชัน uploadType() และประเภทมีผลต่อการจัดเก็บ โดยไฟล์ข้อความเก็บที่ ../data/ และไฟล์ภาพเก็บที่ ../images/

ย้ายไฟล์ไปเก็บตามประเภทไฟล์ที่อ่านได้ด้วยฟังก์ชัน moveFile() ที่ต้องพารามิเตอร์ ไดเรคทอรีปลายทาง ชื่อไฟล์จาก $_Files['name'] และชื่อไฟล์ชั่วคราวจาก $_Files['tmp_name']

การจำกัดขนาดไฟล์

การจำกัดขนาดไฟล์อัพโหลดมีวิธีการที่ดีด้วยการกำหนดฟิลด์ด้วยชื่อ MAX_FILE_SIZE และค่าตามที่ต้องการ ตามปกติเป็นฟิลด์ซ่อนบนฟอร์มส่งค่าจากลูกข่าย ตามตัวอย่างบนฟอร์ม simple_upload.html คือ

<input name="MAX_FILE_SIZE" type="hidden" value="50000"/>

แม่ข่ายจะอ่านจากฟิลด์สำหรับประมวลความผิดพลาด UPLOAD_ERR_FORM_SIZE และต้องกำหนดค่าไว้ก่อน <input type=”file”>

การอัพโหลดหลายไฟล์

ตามตัวอย่าง simple_upload เป็นการอัพโหลด 2 ไฟล์ที่ใช้ชื่อฟิลด์ต่างกัน การตั้งชื่อที่ดีที่สนับสนุนการทำงานของโปรแกรม เช่น กำหนดชื่อฟิลด์เป็น “userfile1”, “userfile2” เป็นต้น การกำหนดเช่นนี้ ทำให้สามารถเขียนเป็นรอบได้สะดวก ตามตัวอย่าง multi_upload.php ดัดแปลงจาก simple_upload ให้ใช้กับ for loop

<?php  
$num_file = 5;

for ($i = 1; $i <= $num_file; $i++)
{

$userfile = "userfile".$i;

if ($_FILES[$userfile] != NULL)
{

if (canUpload($_FILES[$userfile]['error']))
{

$get_type = uploadType($_FILES[$userfile]['name']);

if ($get_type == 1 || $get_type == 2)
    moveFile("../data/", $_FILES[$userfile]['name'], $_FILES[$userfile]['tmp_name']);
elseif ($get_type == 3)
    moveFile("../images/", $_FILES[$userfile]['name'], $_FILES[$userfile]['tmp_name']);

}
else
{

messageError($_FILES['textfile']['error']);

}

}

}

?>

ปัญหาร่วม

มีหลายสิ่งที่ต้องสนใจเมื่อทำการอัพโหลด

  • ตัวอย่างก่อนสมมติว่าผู้ใช้ได้รับการรับรองมาแล้ว ตามปกติควรให้ผู้ที่ระบบรองได้ให้อัพโหลดบนเว็บ เช่น การลงทะเบียนสมาชิก
  • ถ้ายอมให้ผู้ใช้เชื่อถือไม่ได้หรือไม่ได้รับรองให้อัพโหลดไฟล์ ความคิดที่ดีคือ ระวังข้อมูลเหล่านี้จากสคริปต์ประสงค์ร้ายได้รับการอัพโหลดและเรียกใช้ นอกจากประเภทและข้อมูลของไฟล์แล้ว ชื่อไฟล์ที่อัพโหลดควรเปลี่ยนให้ “ปลอดภัย”
  • ถ้ากำลังใช้ Windows Server ให้ใช้ \\ แทนที่ \ ในพาร์ทของไฟล์
  • ถ้ามีปัญหาในการทำงานให้ตรวจไฟล์ php.ini ด้วยการตั้งค่าคำสั่ง upload_tmp_dir ให้ชี้ไปยังไดเรคทอรีที่เข้าถึง รวมถึงการปรับคำสั่ง memory_limit ถ้าต้องการอัพโหลดไฟล์ขนาดใหญ่คำสั่งนี้จะหาขนาดไฟล์ใหญ่ที่สุดที่สามารถอัพโหลด
  • ถ้า PHP กำลังเรียกใช้ในโหมด safe จะมีข่าวสารความผิดพลาดเกี่ยวกับการเข้าถึงไฟล์ชั่วคราว เรื่องนี้สามารถแก้ไขได้ทั้งการไม่เรียกใช้ในโหมด safe หรือการเขียนสคริปต์ที่ไม่ใช้ PHP ที่คัดลอกไฟล์ไปยังตำแหน่งเข้าถึงได้ จากนั้นประมวลผลสคริปต์นี้จากสคริปต์ PHP

 


  

สงวนลิขสิทธิ์ (C) widebase / Julaphak