การใช้ curl ไป download file จากเซิร์ฟเวอร์อื่นๆ ไม่ได้ซับซ้อนเหมือนการอัพโหลดในตัวอย่าง curl: ส่งไฟล์ การทำงานค่อนข้างตรงไปตรงมาก คือ มีไฟล์ที่มี code curl ทำหน้าที่ request และมีไฟล์หรือโปรแกรมที่ทำหน้าที่จ่ายไฟล์ให้ โดยดัดแปลงให้แสดง error กลับมาในรูปแบบที่ง่ายกับการแสดง error ในฝั่งรีเควสท์
เพื่อความปลอดภัย จะมีการเขียนการตรวจสอบเล็กน้อย
- จะส่ง token มาและทั้ง 2 ไฟล์จะต้องมีค่าเท่าๆกัน ในความเป็นจริง ควรจะมีการเขียนที่ดีกว่านี้ เช่น เปลี่ยน token ตามช่วงเวลา
- ไม่ควรให้ร้องขอไฟล์โดยใช้ full path และเพื่อป้องกันการใช้ฝั่งรับในการ download ไฟล์อื่นๆ จึงต้องกำหนดโฟลเดอร์เริ่มต้นไว้ให้ดาวน์โหลดไฟล์ในโฟลเดอร์ที่กำหนดไว้เท่านั้น
<?php header('Cache-Control: no-cache, no-store, must-revalidate'); header('Expires: 0'); header('Pragma: no-cache'); $post = [ 'file' => 'test.docx', 'token' => $token, ]; $token = 'HH89VOiirgXlCdEqDrFs'; $url = 'http://localhost/snippets/PHP/download.php'; $ch = curl_init(); curl_setopt_array($ch, [ CURLOPT_ENCODING => 'UTF-8', CURLOPT_FRESH_CONNECT => true, CURLOPT_POST => 1, CURLOPT_POSTFIELDS => http_build_query($post), CURLOPT_RETURNTRANSFER => true, CURLOPT_URL => $url, ]); $result = curl_exec($ch); switch ($result) { case 'bad token':{ curl_close($ch); exit('check token in ' . $url); }break; case 'file not found':{ curl_close($ch); exit('file not found in target server.'); }break; default:{ header('Content-Disposition: attachment; filename="' . $post['file']); echo $result; } } curl_close($ch);
<?php $fileDir = '../assets/'; $token = 'HH89VOiirgXlCdEqDrFs'; if ($_REQUEST['token'] != $token) { exit('bad token'); } $file = $fileDir . $_REQUEST['file']; if (file_exists($file)) { header('Content-Description: File Transfer'); header('Content-Type: ' . mime_content_type($file)); header('Content-Disposition: attachment; filename="' . basename($file) . '"'); header('Expires: 0'); header('Cache-Control: must-revalidate'); header('Pragma: public'); header('Content-Length: ' . filesize($file)); //readfile($file); echo file_get_contents($file); } else { exit('file not found'); }
About the author