1. การอัปโหลดไฟล์
เพื่อให้ผู้ใช้ของลูกค้าอัปโหลดไฟล์เราต้องระบุแบบฟอร์มในส่วนต่อประสานผู้ใช้เพื่อส่งคำขอไปยังอัปโหลดไฟล์ เนื่องจากไฟล์ที่อัปโหลดเป็นข้อมูลพิเศษซึ่งแตกต่างจากข้อมูลโพสต์อื่น ๆ เราต้องตั้งค่าการเข้ารหัสพิเศษสำหรับแบบฟอร์ม:
คัดลอกรหัสดังนี้: <form action = "upload.php" method = "post" enctype = "multipart/form-data"> </form>
คุณอาจไม่คุ้นเคยกับแอตทริบิวต์ Enctype ข้างต้นเพราะมักจะถูกละเว้น อย่างไรก็ตามหากคำขอโพสต์ HTTP มีทั้งข้อมูลปกติและข้อมูลคล้ายไฟล์ควรเพิ่มแอตทริบิวต์นี้ซึ่งสามารถปรับปรุงความเข้ากันได้สำหรับเบราว์เซอร์ต่างๆ
ต่อไปเราต้องเพิ่มฟิลด์ลงในแบบฟอร์มเพื่ออัปโหลดไฟล์:
คัดลอกรหัสดังต่อไปนี้: <อินพุต type = "file" name = "attightment">
ฟิลด์ไฟล์ข้างต้นอาจทำงานแตกต่างกันในเบราว์เซอร์ต่างๆ สำหรับเบราว์เซอร์ส่วนใหญ่ฟิลด์ข้างต้นจะถูกแสดงเป็นกล่องข้อความด้วยปุ่มเรียกดู ด้วยวิธีนี้ผู้ใช้สามารถป้อนพา ธ ไฟล์ลงในกล่องข้อความด้วยตัวเองหรือเลือกไฟล์ที่จะอัปโหลดจากฮาร์ดดิสก์ท้องถิ่นผ่านปุ่มท่องเว็บ อย่างไรก็ตามใน Safari ของ Apple ดูเหมือนว่าสามารถใช้การท่องได้เท่านั้น แน่นอนคุณยังสามารถปรับแต่งรูปแบบของกล่องอัปโหลดนี้เพื่อให้ดูสง่างามกว่าสไตล์เริ่มต้น
ด้านล่างเพื่ออธิบายวิธีจัดการการอัปโหลดไฟล์ให้ดีขึ้นให้ยกตัวอย่างที่สมบูรณ์ ตัวอย่างเช่นแบบฟอร์มต่อไปนี้อนุญาตให้ผู้ใช้อัปโหลดไฟล์แนบไปยังเซิร์ฟเวอร์ท้องถิ่นของฉัน:
คัดลอกรหัสดังนี้: <p> โปรดอัปโหลดไฟล์แนบของคุณ: </p>
<form action = "upload.php" method = "post" enctype = "multipart/form-data">
<input type = "file" name = "attainment">
<อินพุตประเภท = "ส่ง" value = "อัปโหลดไฟล์แนบ">
</form>
เคล็ดลับ: คุณสามารถตั้งค่าสูงสุดที่อนุญาตให้อัปโหลดไฟล์ผ่าน UPLOAD_MAX_FILESIZE ใน php.ini นอกจากนี้ยังมี post_max_size ที่สามารถใช้ในการตั้งค่าข้อมูลฟอร์มสูงสุดที่ได้รับอนุญาตให้อัปโหลด โดยการตั้งค่าฟิลด์นี้ อย่างไรก็ตามโปรดทราบว่าค่าของหลังจะต้องมากกว่าเดิมเพราะอดีตเป็นส่วนหนึ่งของข้อมูลแบบฟอร์มของหลัง
รูปที่ 1. แบบฟอร์มอัปโหลดที่แสดงใน Firefox
เมื่อส่งแบบฟอร์มนี้คำขอ HTTP จะถูกส่งไปยัง upload.php เพื่อที่จะแสดงข้อมูลเฉพาะที่สามารถใช้ใน upload.php ฉันพิมพ์ออกมาใน upload.php:
การคัดลอกรหัสมีดังนี้:
ส่วนหัว ('เนื้อหาประเภท: ข้อความ/ธรรมดา');
print_r ($ _ ไฟล์);
มาทดลองใช้กันเถอะ
คัดลอกรหัสดังนี้: อาร์เรย์
-
[ไฟล์แนบ] => อาร์เรย์
-
[ชื่อ] => boy.jpg
[type] => image/jpeg
[tmp_name] => d: /xampp/tmp/php1168.tmp
[ข้อผิดพลาด] => 0
[ขนาด] => 11490
-
-
ข้างต้นคือข้อมูลทั้งหมดเกี่ยวกับไฟล์ที่อัปโหลดในปัจจุบันในอาร์เรย์ส่วนกลางหลังจากอัปโหลดไฟล์ อย่างไรก็ตามเราสามารถมั่นใจได้ว่าข้อมูลนี้ปลอดภัยจะเกิดอะไรขึ้นถ้าชื่อหรือข้อมูลอื่น ๆ ได้รับการดัดแปลงด้วย เราต้องระมัดระวังเกี่ยวกับข้อมูลจากลูกค้าเสมอ!
แต่ละส่วนของคำขอ HTTP เฉพาะ
เพื่อให้เข้าใจการอัปโหลดไฟล์ได้ดีขึ้นเราต้องตรวจสอบข้อมูลเฉพาะที่มีอยู่ในคำขอ HTTP ที่ส่งโดยไคลเอนต์ สิ่งที่แนบมาที่ฉันอัปโหลดมาก่อนคือโลโก้ของบล็อกนี้เพราะมันเป็นภาพมันไม่เหมาะสำหรับเราที่จะทำการทดลองข้างต้น ดังนั้นฉันอัปโหลดไฟล์ข้อความ test.Text อีกครั้งซึ่งมีเนื้อหาต่อไปนี้:
การคัดลอกรหัสมีดังนี้:
360W
360 วัน
ชีวิตของเว็บบอย
ตกลง. ตอนนี้ฉันอัปโหลดไฟล์ข้อความนี้และส่งออกใน upload.php:
การคัดลอกรหัสมีดังนี้:
อาร์เรย์
-
[ไฟล์แนบ] => อาร์เรย์
-
[ชื่อ] => test.txt
[ประเภท] => ข้อความ/ธรรมดา
[tmp_name] => d: /xampp/tmp/php51c0.tmp
[ข้อผิดพลาด] => 0
[ขนาด] => 40
-
-
มาดูคำขอโพสต์ HTTP ที่ส่งโดยเบราว์เซอร์ที่เกี่ยวข้อง (ฉันละเว้นส่วนหัวเสริมบางส่วน):
การคัดลอกรหัสมีดังนี้:
post /upload.php http /1.1
โฮสต์: www.360weboy.me
ผู้อ้างอิง: http://www.360weboy.me/
multipart/form-data; ------------------------------------------------------ -------------------------
ความยาวเนื้อหา: 234
----------------------------------- 24464570528145
เนื้อหา--ฟอร์ม: ชื่อ;
ประเภทเนื้อหา: ข้อความ/ธรรมดา
360weboy
360 วัน
ชีวิตของเว็บบอย
-------------------------------- 24464570528145-
มีหลายฟิลด์ในรูปแบบการร้องขอชื่อชื่อไฟล์และประเภทเนื้อหา test.txt และข้อความรูปแบบไฟล์ที่อัปโหลด/ธรรมดา (แสดงถึงไฟล์ข้อความ) จากนั้นเราจะเห็นว่าบรรทัดต่อไปนี้เป็นเนื้อหาเฉพาะในไฟล์ที่อัปโหลด
2. การเสริมสร้างความปลอดภัย
เพื่อปรับปรุงความปลอดภัยในการอัปโหลดไฟล์เราจำเป็นต้องตรวจสอบ TMP_NAME และขนาดในอาร์เรย์ทั่วโลก $ _files เพื่อให้แน่ใจว่าไฟล์ที่ชี้ไปที่ TMP_NAME นั้นเป็นไฟล์ที่อัปโหลดโดยผู้ใช้บนไคลเอนต์แทนที่จะชี้ไปที่สิ่งต่าง ๆ เช่น /etc /passwd คุณสามารถใช้ฟังก์ชั่น is_uploaded_file () ใน PHP เพื่อตัดสินต่อไปนี้ ::
การคัดลอกรหัสมีดังนี้:
$ filename = $ _files ['เอกสารแนบ'] ['tmp_name'];
if (is_uploaded_file ($ filename)) {
/ * เป็นไฟล์ที่อัปโหลด
-
ในบางกรณีหลังจากผู้ใช้อัปโหลดไฟล์เนื้อหาของไฟล์ที่อัปโหลดสำเร็จอาจปรากฏขึ้นต่อผู้ใช้เพื่อดูดังนั้นการตรวจสอบรหัสด้านบนมีความสำคัญอย่างยิ่ง
อีกสิ่งหนึ่งที่ต้องตรวจสอบคือประเภท MIME ของไฟล์อัปโหลดซึ่งเป็นฟิลด์ประเภทของอาร์เรย์เอาต์พุตใน Upload.php ด้านบน สิ่งที่ฉันอัปโหลดในตัวอย่างแรกคือรูปภาพดังนั้นค่าของ $ _files ['attainment'] ['type'] คือ 'image/jpeg' หากคุณวางแผนที่จะยอมรับภาพประเภท MIME เช่น Image/PNG, Image/JPEG, Image/GIF, Image/X-PNG และ Image/P-JPEG ทางฝั่งเซิร์ฟเวอร์คุณสามารถใช้รหัสที่คล้ายกับต่อไปนี้เพื่อตรวจสอบ (เพียงแค่ดูที่มัน) ตัวอย่างรหัสเฉพาะเช่นข้อผิดพลาดควรปฏิบัติตามกลไกในระบบของคุณ):
การคัดลอกรหัสมีดังนี้:
$ owlow_mimes = array (
'Image/png',
'image/x-png'
'รูปภาพ/gif',
'Image/jpeg',
'รูปภาพ/pjpeg'
-
$ image = $ _files ['เอกสารแนบ'];
if (! in_array ($ image ['type'], $ owlow_mimes)) {
ตาย ('ขออภัยรูปแบบไฟล์ที่คุณอัปโหลดไม่ถูกต้องเรายอมรับไฟล์รูปภาพเท่านั้น');
-
// ดำเนินการต่อเพื่อดำเนินการต่อไฟล์รูปภาพที่อัปโหลด
อย่างที่คุณเห็นเรามั่นใจได้ว่าประเภท MIME ของไฟล์ตรงตามข้อกำหนดด้านเซิร์ฟเวอร์ อย่างไรก็ตามมันไม่เพียงพอที่จะป้องกันไม่ให้ผู้ใช้ที่เป็นอันตรายจากการอัปโหลดไฟล์ที่เป็นอันตรายอื่น ๆ เนื่องจากผู้ใช้ที่เป็นอันตรายสามารถแกล้งทำเป็นปลอมแปลงโดยประเภท MIME นี้ ตัวอย่างเช่นผู้ใช้ทำรูปภาพ JPG เขียนรหัส PHP ที่เป็นอันตรายลงในข้อมูลเมตาของรูปภาพและบันทึกเป็นไฟล์ที่มีคำต่อท้ายชื่อ PHP เมื่ออัปโหลดไฟล์ที่เป็นอันตรายนี้จะถูกตรวจสอบได้สำเร็จทางฝั่งเซิร์ฟเวอร์สำหรับประเภท MIME ซึ่งถือเป็นรูปภาพและรหัส PHP ที่เป็นอันตรายภายในจะถูกดำเนินการ ข้อมูลเมตาของภาพเฉพาะนั้นคล้ายกับต่อไปนี้:
การคัดลอกรหัสมีดังนี้:
ชื่อไฟล์: image.jpg
ขนาดไฟล์: 182007 ไบต์
วันที่ไฟล์: 2012: 11: 27 7:45:10
ความละเอียด: 1197 x 478
ความคิดเห็น: passthru ($ _ post ['cmd']); __halt_compiler ();
เราจะเห็นว่ารหัส PHP ถูกเพิ่มลงในฟิลด์ความคิดเห็นของข้อมูลเมตาของภาพ ดังนั้นจึงเป็นที่ชัดเจนว่าเพื่อป้องกันสถานการณ์อันตรายที่คล้ายกันต้องทำการตรวจสอบที่จำเป็นของส่วนขยายของไฟล์ที่อัปโหลด รหัสต่อไปนี้ช่วยเพิ่มรหัสก่อนหน้าสำหรับการตรวจสอบประเภท MIME:
การคัดลอกรหัสมีดังนี้:
$ owlow_mimes = array (
'image/png' => '.png'
'image/x-png' => '.png'
'image/gif' => '.gif'
'image/jpeg' => '.jpg'
'image/pjpeg' => '.jpg'
-
$ image = $ _files ['เอกสารแนบ'];
if (! array_key_exists ($ image ['type'], $ owlow_mimes)) {
ตาย ('ขออภัยรูปแบบไฟล์ที่คุณอัปโหลดไม่ถูกต้องเรายอมรับไฟล์รูปภาพเท่านั้น');
-
// รับชื่อไฟล์ที่มีชื่อต่อท้ายที่ละเว้น:
$ filename = substr ($ image ['name'], 0, strpos ($ image ['name'], '.'));
// เพิ่มชื่อต่อท้าย
$ filename. = $ owlow_mimes [$ image ['type']];
// ดำเนินการดำเนินการต่อไป
ผ่านรหัสด้านบนเราตรวจสอบให้แน่ใจว่าแม้ว่าภาพที่อัปโหลด Metafile มีรหัส PHP ไฟล์ภาพจะถูกเปลี่ยนชื่อเป็นไฟล์ที่มีชื่อต่อท้ายและรูปแบบภาพดังนั้นรหัส PHP ในนั้นจะไม่ถูกเรียกใช้งาน รหัสข้างต้นจะไม่มีผลกระทบเชิงลบใด ๆ ต่อภาพที่อัปโหลดปกติ
หลังจากดำเนินการหลายขั้นตอนข้างต้นเพื่อปรับปรุงการตรวจสอบความปลอดภัยหากคุณเพียงแค่ต้องการบันทึกไฟล์ที่อัปโหลดไปยังไดเรกทอรีที่ระบุคุณสามารถใช้ฟังก์ชั่นเริ่มต้น move_uploaded_file ของ PHP เพื่อนำไปใช้งาน:
การคัดลอกรหัสมีดังนี้:
$ TMP_FILENAME = $ _FILES ['ไฟล์แนบ'] ['TMP_NAME'];
$ filename = '/path/to/attachment.txt';
if (move_uploaded_file (tmp_filename, $ filename)) {
/ * $ temp_filename ไฟล์อัปโหลดที่บันทึกไว้ในไดเรกทอรีชั่วคราวจากนั้นบันทึกไว้ในไฟล์ attach.txt ในไดเรกทอรีที่เกี่ยวข้องสำเร็จ
-
คุณอาจต้อง จำกัด ขนาดของไฟล์ที่อัปโหลดเพื่อให้คุณสามารถใช้ฟังก์ชั่นขนาดไฟล์เพื่อรับขนาดของไฟล์ที่อัปโหลดตัดสินและทำการประมวลผลเพิ่มเติม
โอเคเรามาเขียนสิ่งนี้ในตอนนี้เกี่ยวกับการอัปโหลดไฟล์ หวังว่าบทความเบื้องต้นนี้จะเป็นประโยชน์กับคุณ