Recently, the company encountered a php memory overflow problem when exporting order information. The reason is that the temporary file generated during download is too large to accommodate the PHP memory, when I thought of changing the PHP memory limit, it was just a slow task. so I thought of another way to read and download files in multiple parts. Recently, the company encountered a php memory overflow problem when exporting order information. The reason is that the temporary file generated during download is too large to accommodate the PHP memory, when I thought of changing the PHP memory limit, it was just a slow task. so I thought of another way to read and download files in multiple parts.
The source code is as follows:
- $ SourceFile = "1.tmp"; // temporary file name to be downloaded
- $ OutFile = "..xls"; // download the file name saved to the client
- $ File_extension = strtolower (substr (strrchr ($ sourceFile, "."), 1); // get the file extension
- // Echo $ sourceFile;
- If (! Ereg ("[tmp | txt | rar | pdf | doc]", $ file_extension) exit ("illegal resource download ");
- // Check whether the file exists
- If (! Is_file ($ sourceFile )){
- Die ("404 File not found!");
- }
- $ Len = filesize ($ sourceFile); // get the file size
- $ Filename = basename ($ sourceFile); // get the file name
- $ OutFile_extension = strtolower (substr (strrchr ($ outFile, "."), 1); // get the file extension
- // Specify the output browser format based on the extension
- Switch ($ outFile_extension ){
- Case "exe ":
- $ Ctype = "application/octet-stream ";
- Break;
- Case "zip ":
- $ Ctype = "application/zip ";
- Break;
- Case "mp3 ":
- $ Ctype = "audio/mpeg ";
- Break;
- Case "mpg ":
- $ Ctype = "video/mpeg ";
- Break;
- Case "avi ":
- $ Ctype = "video/x-msvideo ";
- Break;
- Default:
- $ Ctype = "application/force-download ";
- }
- // Begin writing headers
- Header ("Cache-Control :");
- Header ("Cache-Control: public ");
- // Set the output browser format
- Header ("Content-Type: $ ctype ");
- Header ("Content-Disposition: attachment; filename =". $ outFile );
- Header ("Accept-Ranges: bytes ");
- $ Size = filesize ($ sourceFile );
- // If $ _ SERVER ['http _ range'] parameter exists
- If (isset ($ _ SERVER ['http _ range']) {
- /* The Range header can request one or more sub-ranges of an object.
- For example,
- Indicates the first 500 bytes: bytes = 0-499
- Indicates the second 500 bytes: bytes = 500-999
- Indicates the last 500 bytes: bytes =-500
- Indicates the range after 500 bytes: bytes = 500-
- First and Last bytes: bytes = 0-0,-1
- Specify the following ranges: bytes = 500-600,601-999.
- However, the server can ignore this request header. if the unconditional GET contains the Range request header, the response will be returned with the status code 206 (PartialContent) instead of 200 (OK ).
- */
- // The value of connecting to $ _ SERVER ['http _ range'] again after the breakpoint is bytes = 4390912-
- List ($ a, $ range) = explode ("=", $ _ SERVER ['http _ range']);
- // If yes, download missing part
- Str_replace ($ range, "-", $ range); // What is this sentence ....
- $ Size2 = $ size-1; // total file bytes
- $ New_length = $ size2-$ range; // Obtain the length of the next download.
- Header ("HTTP/1.1 206 Partial Content ");
- Header ("Content-Length: $ new_length"); // The total Length of input
- Header ("Content-Range: bytes $ range $ size2/$ size"); // Content-Range: bytes 4908618-4988927/4988928 95%
- } Else {
- // The first connection
- $ Size2 = $ size-1;
- Header ("Content-Range: bytes 0-$ size2/$ size"); // Content-Range: bytes 0-4988927/4988928
- Header ("Content-Length:". $ size); // total output Length
- }
- // Open the file
- $ Fp = fopen ("$ sourceFile", "rb ");
- // Set the pointer position
- Fseek ($ fp, $ range );
- // Unreal output
- While (! Feof ($ fp )){
- // Set the maximum file execution time
- Set_time_limit (0 );
- Print (fread ($ fp, 1024*8); // output file
- Flush (); // OUTPUT BUFFER
- Ob_flush ();
- }
- Fclose ($ fp );
- Exit ();