4) { fwrite(STDERR, "Usage: php download-file.php [expected-bytes]\n"); exit(64); } $url = $argv[1]; $destination = $argv[2]; $expectedBytes = null; if (isset($argv[3])) { if (!ctype_digit($argv[3])) { fwrite(STDERR, "Expected bytes must be a whole number.\n"); exit(64); } $expectedBytes = (int) $argv[3]; } $scheme = strtolower((string) parse_url($url, PHP_URL_SCHEME)); if (!in_array($scheme, ['http', 'https'], true)) { fwrite(STDERR, "URL must use http or https.\n"); exit(64); } $directory = dirname($destination); if (!is_dir($directory) && !mkdir($directory, 0700, true)) { fwrite(STDERR, "Could not create destination directory: {$directory}\n"); exit(1); } $temporary = $destination . '.part'; $file = fopen($temporary, 'wb'); if ($file === false) { fwrite(STDERR, "Could not open temporary file: {$temporary}\n"); exit(1); } $curl = curl_init($url); if ($curl === false) { fclose($file); @unlink($temporary); fwrite(STDERR, "Could not initialize cURL.\n"); exit(1); } curl_setopt_array($curl, [ CURLOPT_FILE => $file, CURLOPT_FOLLOWLOCATION => true, CURLOPT_MAXREDIRS => 5, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 60, CURLOPT_USERAGENT => 'ExampleDownloader/1.0', ]); $success = curl_exec($curl); $status = curl_getinfo($curl, CURLINFO_HTTP_CODE); $error = curl_error($curl); curl_close($curl); fclose($file); if ($success === false) { @unlink($temporary); fwrite(STDERR, "cURL error: {$error}\n"); exit(1); } if ($status < 200 || $status >= 300) { @unlink($temporary); fwrite(STDERR, "HTTP status: {$status}\n"); fwrite(STDERR, "Download failed; temporary file removed.\n"); exit(1); } $bytes = filesize($temporary); if ($bytes === false) { @unlink($temporary); fwrite(STDERR, "Could not read downloaded file size.\n"); exit(1); } if ($expectedBytes !== null && $bytes !== $expectedBytes) { @unlink($temporary); fwrite(STDERR, "Size mismatch: expected {$expectedBytes} bytes, got {$bytes} bytes.\n"); exit(1); } if (!rename($temporary, $destination)) { @unlink($temporary); fwrite(STDERR, "Could not move temporary file into place.\n"); exit(1); } echo "HTTP status: {$status}\n"; echo "Saved: {$destination}\n"; echo "Bytes: {$bytes}\n";