Skip to content
This repository was archived by the owner on Apr 8, 2026. It is now read-only.

PHP Remote File Copy

Sebastian Tschan edited this page Nov 16, 2016 · 2 revisions

A feature that is often requested is to upload files via a given URL. The following code snippet provides a demo script which implements this feature with progress reporting to the user:


/*
 * Remote File Copy PHP Script 2.0.0
 *
 * Copyright 2012, Sebastian Tschan
 * https://blueimp.net
 *
 * Licensed under the MIT license:
 * http://www.opensource.org/licenses/MIT
 */

$upload_dir = __DIR__."/files";

if (empty($_REQUEST["url"])) {
?>




Remote File Copy



    exit; } $url = !empty($_REQUEST["url"]) && preg_match("|^http(s)?://.+$|", stripslashes($_REQUEST["url"])) ? stripslashes($_REQUEST["url"]) : null; $callback = !empty($_REQUEST["callback"]) && preg_match("|^\w+$|", $_REQUEST["callback"]) ? $_REQUEST["callback"] : "callback"; $use_curl = false;defined("CURLOPT_PROGRESSFUNCTION"); $temp_file = tempnam(sys_get_temp_dir(), "upload-"); $fileinfo = new stdClass(); $fileinfo->name = trim(basename($url), ".\x00..\x20"); // 1KB of initial data, required by Webkit browsers: echo "".str_repeat("0", 1000).""; function event_callback ($message) { global $callback; echo ""; } function get_file_path () { global $upload_dir, $fileinfo, $temp_file; return $upload_dir."/".basename($fileinfo->name).'.'.basename($temp_file).'.dat'; } function stream_notification_callback ($notification_code, $severity, $message, $message_code, $bytes_transferred, $bytes_max) { global $fileinfo; switch($notification_code) { case STREAM_NOTIFY_FILE_SIZE_IS: $fileinfo->size = $bytes_max; break; case STREAM_NOTIFY_MIME_TYPE_IS: $fileinfo->type = $message; break; case STREAM_NOTIFY_PROGRESS: if (!$bytes_transferred) { event_callback(array("send" => $fileinfo)); } event_callback(array("progress" => array("loaded" => $bytes_transferred, "total" => $bytes_max))); break; } } function curl_progress_callback ($curl_resource, $total, $loaded) { global $fileinfo; if (!$loaded) { if (!isset($fileinfo->size)) { $fileinfo->size = $total; event_callback(array("send" => $fileinfo)); } } event_callback(array("progress" => array("loaded" => $loaded, "total" => $total))); } if (!$url) { $success = false; } else if ($use_curl) { $fp = fopen($temp_file, "w"); $ch = curl_init($url); curl_setopt($ch, CURLOPT_NOPROGRESS, false ); curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, "curl_progress_callback"); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_FILE, $fp); $success = curl_exec($ch); $curl_info = curl_getinfo($ch); if (!$success) { $err = array("message" => curl_error($ch)); } curl_close($ch); fclose($fp); $fileinfo->size = $curl_info["size_download"]; $fileinfo->type = $curl_info["content_type"]; } else { $ctx = stream_context_create(); stream_context_set_params($ctx, array("notification" => "stream_notification_callback")); $success = copy($url, $temp_file, $ctx); if (!$success) { $err = error_get_last(); } } if ($success) { $success = rename($temp_file, get_file_path()); } if ($success) { event_callback(array("done" => $fileinfo)); } else { unlink($temp_file); if (!$err) { $err = array("message" => "Invalid url parameter"); } event_callback(array("fail" => $err)); }

    Clone this wiki locally