Overview

Namespaces

  • None
  • PHP
  • Pry
    • Auth
      • Interfaces
    • Config
    • Controller
    • Date
    • Db
    • Feed
      • Abstracts
      • Writers
    • File
      • Decorator
    • Form
      • Element
    • Image
    • Log
      • Writer
    • Net
      • Exception
    • Session
    • Util
    • Validate
      • Validator
    • View

Classes

  • HTTPDownload
  • Request
  • Socket
  • Overview
  • Namespace
  • Class
  • Tree
  1: <?php
  2: 
  3: /**
  4:  * Pry Framework
  5:  *
  6:  * LICENSE
  7:  *
  8:  * This source file is subject to the new BSD license that is bundled
  9:  * with this package in the file LICENSE.txt.
 10:  * 
 11:  */
 12: 
 13: namespace Pry\Net;
 14: 
 15: /**
 16:  * Téléchargement de fichier via protocole HTTP
 17:  * Pour des fichiers de taille importante préférer la solution X-SendFile header
 18:  * @category Pry
 19:  * @package Net
 20:  * @see http://www.php.net/manual/en/function.fread.php#84115
 21:  * @version 1.0.2
 22:  * @author Olivier ROGER <oroger.fr>
 23:  *
 24:  */
 25: class HTTPDownload
 26: {
 27: 
 28:     /**
 29:      * Chemin vers le fichier
 30:      * @var string
 31:      */
 32:     protected $path;
 33: 
 34:     /**
 35:      * Nom du fichier envoyé au navigateur.
 36:      * Permet de renommer un fichier en l'envoyant.
 37:      * @var string
 38:      */
 39:     protected $name;
 40: 
 41:     /**
 42:      * Extension du fichier
 43:      * @var string
 44:      */
 45:     protected $extension;
 46: 
 47:     /**
 48:      * Type Mime du fichier
 49:      * @var string
 50:      */
 51:     protected $mime;
 52: 
 53:     /**
 54:      * Taille du fichier en octet
 55:      * @var int
 56:      */
 57:     protected $size;
 58: 
 59:     /**
 60:      * Active ou non la reprise de téléchargement
 61:      * @var boolean
 62:      */
 63:     protected $resume;
 64: 
 65:     /**
 66:      * Position de début du pointeur
 67:      * @var int
 68:      */
 69:     protected $seekStart;
 70: 
 71:     /**
 72:      * Position de fin du pointeur
 73:      * @var int
 74:      */
 75:     protected $seekEnd;
 76: 
 77:     public function __construct($path, $resume = false)
 78:     {
 79:         if (file_exists($path))
 80:         {
 81:             $this->path      = $path;
 82:             $this->extension = strtolower(substr(strrchr($path, '.'), 1));
 83:             $this->getMime();
 84:             $this->size      = filesize($path);
 85:             $this->seekStart = 0;
 86:             $this->seekEnd   = -1;
 87:             $this->resume    = $resume;
 88:             $this->name      = basename($path);
 89:         }
 90:         else
 91:         {
 92:             throw new \Exception('Fichier innexistant');
 93:         }
 94:     }
 95: 
 96:     /**
 97:      * Lance le téléchargement ou la reprise du téléchargement
 98:      */
 99:     public function download()
100:     {
101:         header("Cache-Control: cache, must-revalidate");
102:         header("Pragma: public");
103:         header('Expires: 0');
104:         if ($this->resume)
105:         {
106:             $this->getRange();
107:             header('HTTP/1.0 206 Partial Content');
108:             header('Status: 206 Partial Content');
109:             header('Accept-Ranges: bytes');
110:             header('Content-Range: bytes ' . $this->seekStart . '-' . $this->seekEnd . '/' . $this->size);
111:             header('Content-Length:' . ($this->seekEnd - $this->seekStart + 1));
112:         }
113:         else
114:         {
115:             header('Content-Length:' . $this->size);
116:         }
117: 
118:         header('Content-Description: File Transfer');
119:         header('Content-Type: ' . $this->mime);
120:         header('Content-Disposition: attachment;filename="' . $this->name . '"');
121:         header('Content-Transfer-Encoding: binary');
122: 
123:         $handle = fopen($this->path, 'rb');
124:         if (!$handle)
125:         {
126:             throw new \Exception('Erreur pendant le téléchargement');
127:         }
128:         else
129:         {
130:             fseek($handle, $this->seekStart);
131:             while (!feof($handle)) {
132:                 set_time_limit(0);
133:                 echo fread($handle, 1024 * 8); //Paquet de 8ko
134:                 flush();
135:                 ob_flush();
136:             }
137:             fclose($handle);
138:         }
139:     }
140: 
141:     /**
142:      * Défini le type mime du fichier
143:      * Par défaut le type octet-stream est utilisé
144:      * @param string $mime
145:      */
146:     public function setMimeType($mime)
147:     {
148:         $this->mime = $mime;
149:     }
150: 
151:     /**
152:      * Renomme le fichier à télécharger
153:      * @param string $name
154:      */
155:     public function setName($name)
156:     {
157:         $this->name = $name;
158:     }
159: 
160:     /**
161:      * Récupère le range
162:      * @see http://tools.ietf.org/id/draft-ietf-http-range-retrieval-00.txt
163:      * @return void
164:      */
165:     private function getRange()
166:     {
167:         //Peut être de la forme Range: bytes=0-99,500-1499,4000-
168:         if (isset($_SERVER['HTTP_RANGE']))
169:         {
170:             list($unit, $ranges) = explode('=', $_SERVER['HTTP_RANGE'], 2);
171:             if ($unit == 'bytes')
172:             {
173:                 list($range, $extraRange) = explode(',', $ranges, 2);
174:                 //Seul le premier range est utilisé pour des raisons de simplicité
175:                 list($seekStart, $seekEnd) = explode('-', $range, 2);
176: 
177:                 if (!empty($seekStart) && $seekStart > 0)
178:                     $this->seekStart = intval($seekStart);
179: 
180:                 if (!empty($seekEnd))
181:                     $this->seekEnd = min(abs(intval($seekEnd)), ($this->size) - 1);
182:             }
183:         }
184:     }
185: 
186:     /**
187:      * Tente de déterminer le type mime du fichier
188:      */
189:     private function getMime()
190:     {
191:         switch ($this->extension)
192:         {
193:             case 'txt': $this->mime = 'text/plain';
194:                 break;
195:             case 'pdf': $this->mime = 'application/pdf';
196:                 break;
197:             case 'rtf': $this->mime = 'application/rtf';
198:                 break;
199:             case 'jpg': $this->mime = 'image/jpeg';
200:                 break;
201:             case 'xls': $this->mime = 'application/vnd.ms-excel';
202:                 break;
203:             case 'pps': $this->mime = 'application/vnd.ms-powerpoint';
204:                 break;
205:             case 'doc': $this->mime = 'application/msword';
206:                 break;
207:             case 'exe': $this->mime = 'application/octet-stream';
208:                 break;
209:             case 'zip': $this->mime = 'application/zip';
210:                 break;
211:             case 'mp3': $this->mime = 'audio/mpeg';
212:                 break;
213:             case 'mpg': $this->mime = 'video/mpeg';
214:                 break;
215:             case 'avi': $this->mime = 'video/x-msvideo';
216:                 break;
217:             default: $this->mime = 'application/force-download';
218:         }
219:     }
220: 
221: }
Pry API documentation generated by ApiGen 2.8.0