J'ai un fichier pdf sur mon serveur. Je veux créer un tel lien que, l'utilisateur peut cliquer dessus et télécharger ce fichier pdf. J'utilise le travail de cadre de Zend avec Php.Comment télécharger un fichier existant en PHP
Répondre
Placez ce code dans un fichier php et appelez-le f.e. "Download.php":
<?php
$fullPath = "path/to/your/file.ext";
if ($fd = fopen ($fullPath, "r")) {
$fsize = filesize($fullPath);
$path_parts = pathinfo($fullPath);
$ext = strtolower($path_parts["extension"]);
header("Content-type: application/pdf");
header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\"");
header("Content-length: $fsize");
header("Cache-control: private");
while(!feof($fd)) {
$buffer = fread($fd, 2048);
echo $buffer;
}
}
fclose ($fd);
exit;
?>
Exemple: placer ce type de lien dans le document où le téléchargement de fichier est offert:
<a href="download.php?download_file=some_file.pdf">Download here</a>
Plus de détail:
Je ne sais pas si Zend fournit une classe pour cela. En général, ceci est réalisé en utilisant la fonction d'en-tête. jetez un oeil sur le site PHP:
http://php.net/manual/en/function.header.php
Il existe quelques exemples de téléchargement de fichiers.
Bonne chance!
header("Content-type: application/pdf");
header("Content-Disposition: attachment; filename=filename.pdf");
$pdfiledata = file_get_contents($filename);
echo $pdfiledata;
Court, concis et précis, bien que je préfère utiliser 'fpassthru' http://us3.php.net/manual/fr/function.fpassthru.php que' file_get_contents' http: //us3.php .net/manual/fr/function.file-get-contents.php –
hors-sujet: je vous suggérerais plus à propos de fpassthru. est-ce plus sûr? Je ne l'ai jamais su. – thevikas
Ceci est horrible pour la performance, en vidant le contenu du fichier en mémoire. J'aurais aimé avoir des downvotes à gauche. – NullUserException
J'utilise l'assistant d'action réutilisable this pour envoyer des fichiers aux utilisateurs. Cela fonctionne bien et c'est mieux que de se débrouiller avec les en-têtes.
Je suppose qu'il y a une raison pour laquelle vous ne pouvez pas simplement lier directement au pdf, comme la nécessité d'authentifier l'utilisateur. Dans ce cas, vous devrez définir les en-têtes appropriés, et, comme d'autres l'ont noté, vous pouvez utiliser get_file_contents pour servir le pdf. Cependant, l'utilisation de get_file_contents nécessite que vous lisiez le fichier en mémoire avant d'envoyer la réponse. Si le fichier est volumineux ou si vous recevez plusieurs demandes à la fois, vous pouvez facilement manquer de mémoire. Une excellente solution si vous utilisez Apache ou Lighttpd est d'utiliser XSendFile. Avec XSendFile, vous définissez l'en-tête de réponse X-Sendfile sur le chemin du fichier, et votre serveur Web sert le fichier directement à partir du disque - sans révéler l'emplacement du fichier sur le disque.
Le problème avec cette solution est que le module doit être installé sur Apache, et il doit être configuré pour fonctionner avec Lighttpd.
Une fois XSendFile est installé, votre code d'action Zend Framework ressemblerait à quelque chose comme ce qui suit:
// user auth or other code here -- there has to be a reason you're not
// just pointing to the pdf file directly
$this->_helper->layout->disableLayout();
$this->_helper->viewRenderer->setNoRender();
$this->getResponse()->setHeader('Content-type', 'application/pdf')
->setHeader('X-Sendfile', 'path-to-file')
->sendResponse();
J'ai toujours utilisé la fonction become_file_download de la bibliothèque source BalPHP ouverte que vous pouvez brancher et jouer (bâton) dans votre projet tout de suite. Il permet:
- téléchargement instantané du fichier
- facilement spécifier params comme type de contenu, la vie du cache, la taille de la mémoire tampon.
- Prend en charge les transactions en plusieurs parties permettant des téléchargements plus rapides qui ne tueront pas votre serveur pour les gros transferts de fichiers.
- Prend en charge la fonctionnalité de pause/reprise.
- Et ETAG pour la mise en cache:
Vous pouvez trouver la dernière version ici: http://github.com/balupton/balphp/blob/master/trunk/lib/core/functions/_files.funcs.php#L75
Et là, il est exemplaire et collé en date du 27 Août 2010:
/**
* Become a file download, should be the last script that runs in your program
*
* http://tools.ietf.org/id/draft-ietf-http-range-retrieval-00.txt
*
* @version 3, July 18, 2009 (Added suport for data)
* @since 2, August 11, 2007
*
* @author Benjamin "balupton" Lupton <[email protected]> - {@link http://www.balupton.com/}
*
* @param string $file_path
* @param string $content_type
* @param int $buffer_size
* @param string $file_name
* @param timestamp $file_time
*
* @return boolean true on success, false on error
*/
function become_file_download ($file_path_or_data, $content_type = NULL, $buffer_size = null, $file_name = null, $file_time = null, $expires = null) {
// Prepare
if (empty($buffer_size))
$buffer_size = 4096;
if (empty($content_type))
$content_type = 'application/force-download';
// Check if we are data
$file_descriptor = null;
if (file_exists($file_path_or_data) && $file_descriptor = fopen($file_path_or_data, 'rb')) {
// We could be a file
// Set some variables
$file_data = null;
$file_path = $file_path_or_data;
$file_name = $file_name ? $file_name : basename($file_path);
$file_size = filesize($file_path);
$file_time = filemtime($file_path);
$etag = md5($file_time . $file_name);
} elseif ($file_name !== null) {
// We are just data
$file_data = $file_path_or_data;
$file_path = null;
$file_size = strlen($file_data);
$etag = md5($file_data);
if ($file_time === null)
$file_time = time();
else
$file_time = ensure_timestamp($file_time);
} else {
// We couldn't find the file
header('HTTP/1.1 404 Not Found');
return false;
}
// Prepare timestamps
$expires = ensure_timestamp($expires);
// Set some variables
$date = gmdate('D, d M Y H:i:s') . ' GMT';
$expires = gmdate('D, d M Y H:i:s', $expires) . ' GMT';
$last_modified = gmdate('D, d M Y H:i:s', $file_time) . ' GMT';
// Say we can go on forever
set_time_limit(0);
// Check relevance
$etag_relevant = !empty($_SERVER['HTTP_IF_NONE_MATCH']) && trim(stripslashes($_SERVER['HTTP_IF_NONE_MATCH']), '\'"') === $etag;
$date_relevant = !empty($_SERVER['HTTP_IF_MODIFIED_SINCE']) && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) >= $file_time;
// Handle download
if ($etag_relevant || $date_relevant) {
// Not modified
header('HTTP/1.0 304 Not Modified');
header('Status: 304 Not Modified');
header('Pragma: public');
header('Cache-Control: private');
header('ETag: "' . $etag . '"');
header('Date: ' . $date);
header('Expires: ' . $expires);
header('Last-modified: ' . $last_modified);
return true;
} elseif (!empty($_SERVER['HTTP_RANGE'])) {
// Partial download
/*
* bytes=0-99,500-1499,4000-
*/
// Explode RANGE
list($size_unit,$ranges) = explode($_SERVER['HTTP_RANGE'], '=', 2);
// Explode RANGES
$ranges = explode(',', $ranges);
// Cycle through ranges
foreach ($ranges as $range) {
// We have a range
/*
* All bytes until the end of document, except for the first 500 bytes:
* Content-Range: bytes 500-1233/1234
*/
// Set range start
$range_start = null;
if (!empty($range[0]) && is_numeric($range[0])) {
// The range has a start
$range_start = intval($range[0]);
} else {
$range_start = 0;
}
// Set range end
if (!empty($range[1]) && is_numeric($range[1])) {
// The range has an end
$range_end = intval($range[1]);
} else {
$range_end = $file_size - 1;
}
// Set the range size
$range_size = $range_end - $range_start + 1;
// Set the headers
header('HTTP/1.1 206 Partial Content');
header('Pragma: public');
header('Cache-Control: private');
header('ETag: "' . $etag . '"');
header('Date: ' . $date);
header('Expires: ' . $expires);
header('Last-modified: ' . $last_modified);
header('Content-Transfer-Encoding: binary');
header('Accept-Ranges: bytes');
header('Content-Range: bytes ' . $range_start . '-' . $range_end . '/' . $file_size);
header('Content-Length: ' . $range_size);
header('Content-Type: ' . $content_type);
if ($content_type === 'application/force-download')
header('Content-Disposition: attachment; filename=' . urlencode($file_name));
// Handle our data transfer
if (!$file_path) {
// We are using file_data
echo substr($file_data, $range_start, $range_end - $range_start);
} else {
// Seek to our location
fseek($file_descriptor, $range_start);
// Read the file
$remaining = $range_size;
while ($remaining > 0) {
// 0-6 | buffer = 3 | remaining = 7
// 0,1,2 | buffer = 3 | remaining = 4
// 3,4,5 | buffer = 3 | remaining = 1
// 6 | buffer = 1 | remaining = 0
// Set buffer size
$buffer_size = min($buffer_size, $remaining);
// Output file contents
echo fread($file_descriptor, $buffer_size);
flush();
ob_flush();
// Update remaining
$remaining -= $buffer_size;
}
}
}
} else {
// Usual download
// header('Pragma: public');
// header('Cache-control: must-revalidate, post-check=0, pre-check=0');
// header('Expires: '. gmdate('D, d M Y H:i:s').' GMT');
// Set headers
header('HTTP/1.1 200 OK');
header('Pragma: public');
header('Cache-Control: private');
header('ETag: "' . $etag . '"');
header('Date: ' . $date);
header('Expires: ' . $expires);
header('Last-modified: ' . $last_modified);
header('Content-Transfer-Encoding: binary');
header('Accept-Ranges: bytes');
header('Content-Length: ' . $file_size);
header('Content-Type: ' . $content_type);
if ($content_type === 'application/force-download')
header('Content-Disposition: attachment; filename=' . urlencode($file_name));
// Handle our data transfer
if (!$file_path) {
// We are using file_data
echo $file_data;
} else {
// Seek to our location
// Read the file
$file_descriptor = fopen($file_path, 'r');
while (!feof($file_descriptor)) {
// Output file contents
echo fread($file_descriptor, $buffer_size);
flush();
ob_flush();
}
}
}
// Close the file
if ($file_descriptor)
fclose($file_descriptor);
// Done
return true;
}
Il dépend également d'une autre fonction plug and play appelée ensure_timestamp que vous pouvez trouver ici: http://github.com/balupton/balphp/blob/master/trunk/lib/core/functions/_datetime.funcs.php#L31
/**
* Gets the days between two timestamps
* @version 1, January 28, 2010
* @param mixed $value
* @return timestamp
*/
function ensure_timestamp ($value = null) {
$result = null;
if ($value === null) $result = time();
elseif (is_numeric($value)) $result = $value;
elseif (is_string($value)) $result = strtotime($value);
else throw new Exception('Unknown timestamp type.');
return $result;
}
- 1. Pause Télécharger & Resume (Fusionner le fichier existant)
- 2. Comment créer un fichier CSV en utilisant PHP (et télécharger)
- 3. Comment forcer un fichier à télécharger en PHP
- 4. Télécharger le fichier PHP
- 5. Télécharger un fichier et l'enregistrer dans un répertoire en PHP
- 6. PHP multiples fichier télécharger
- 7. Comment copier un fichier en PHP sans écraser un fichier existant?
- 8. Comment modifier le fichier Excel existant en utilisant PHP?
- 9. comment écrire dans le fichier XML existant en utilisant php
- 10. Comment renommer un fichier existant
- 11. PHP télécharger le fichier
- 12. Télécharger un fichier en Python
- 13. C# Comment télécharger un fichier sur un serveur PHP?
- 14. Comment télécharger un fichier en utilisant NSURLConnection?
- 15. Comment télécharger un fichier CSV en flex?
- 16. Télécharger par programme un fichier en mémoire php
- 17. Télécharger un fichier Fichiers volumineux PHP/AJAX
- 18. Télécharger un fichier avec php sur un autre serveur php
- 19. Télécharger avec FTP un fichier formulaire en PHP
- 20. Télécharger un fichier lié au php en JavaScript
- 21. Télécharger le fichier php mail
- 22. Comment créer un fichier XML avec php et le télécharger?
- 23. Comment puis-je ajouter un filigrane à un fichier PDF existant en utilisant PHP?
- 24. SVN - Comment télécharger un seul fichier?
- 25. Comment puis-je télécharger un fichier inexistant dans php
- 26. Comment télécharger un fichier sur le serveur PHP?
- 27. ExtJS & PHP Télécharger le fichier
- 28. comment ouvrir un fichier .xlsx existant en utilisant apache poi
- 29. php n'inclura pas un fichier existant: permission refusée
- 30. Comment télécharger un fichier zip en python en utilisant urllib2?
Le titre de la question est superflu. Comment vais-je télécharger un fichier qui n'existe pas? – NullUserException
@NullUserException: Vous souhaiterez peut-être générer un fichier à l'exécution du script, en le maintenant uniquement en mémoire; Un * pourrait * argumenter qu'il ne télécharge pas un 'fichier existant'. Cela n'existerait certainement pas sur le système de fichiers. :) – pinkgothic