Functions to Chop up Files in PHP

PHP Help from NicholasSolutions

Contents

  1. Introduction
  2. The functions
  3. Examples

0. Introduction

Sometimes it's useful to be able to chop up a file into chunks of a certain size. For example, maybe you need to put a large file in a MySQL database, and the file size exceeds the maximum MySQL packet size allowed by your hosting company. Another use might be to allow users to download a large file in parts, and then join them together on their computer with a file joiner. Below are two scripts to help with the task of splitting up files.

First, file_chop() will chop the file up for you and return an array with the pieces. If your file is not too large, it works very nicely and gives you all the chunks as an array of strings. You can write these to a database or files, or whatever else you'd like to do. The second function, file_chop_big() is meant to be used on bigger files. This function does not read the whole file in at once in order to avoid exceeding PHP's memory limit (the default is 8MB). Instead, it works one chunk at a time, writing the files to disk, and returns an array of the chunks' file names. You can use this function on smaller files, too, if you'd rather write the chunks to disk than hold them in memory. To use file_chop_big(), the user running PHP (usually your web server) will need write access to the folder where you put the script.

1. The functions

data array file_chop(string file_path, int chunk_size)

function file_chop($file_path$chunk_size){
    
$handle fopen($file_path'rb');         //read the file in binary mode
    
$size filesize($file_path); 
    
$contents fread($handle$size);
    
fclose($handle);
    
    
//find number of full $chunk_size byte portions
    
$num_chunks floor($size/$chunk_size);

    
$chunks = array();

    
$start 0;
    for (
$kk=0$kk $num_chunks$kk++){
      
$chunks[] = substr($contents$start$chunk_size); //get $chunk_size bytes at a time
      
$start += $chunk_size;
    }
    
    if (
$start $size){
       
$chunks[] = substr($contents$start);  //get any leftover
    
}
    return 
$chunks;
}  

filename array file_chop_big(string file_path, int chunk_size)

function file_chop_big($file_path$chunk_size){
  
$size filesize($file_path);

  
//find number of full $chunk_size byte portions
  
$num_chunks floor($size/$chunk_size);

  
$file_handle fopen($file_path'rb');         //read the file in binary mode

  
$chunks = array();

  for (
$kk=0$kk $num_chunks$kk++){
    
$chunks[$kk] = basename($file_path).'.chunk'.($kk+1);
    
$chunk_handle fopen($chunks[$kk], 'w');   //open the chunk file for writing

    //write the data to the chunk file 1k at a time
    
while((ftell($chunk_handle) + 1024) <= $chunk_size){
      
fwrite($chunk_handlefread($file_handle1024));
    }

    if((
$leftover $chunk_size-ftell($chunk_handle)) > ){
      
fwrite($chunk_handlefread($file_handle$leftover));
    }
    
fclose($chunk_handle);
  }

  if ((
$leftover $size ftell($file_handle)) > 0){
    
$chunks[$num_chunks] = basename($file_path).'.chunk'.($num_chunks 1);
    
$chunk_handle fopen($chunks[$num_chunks], 'w');
    while(!
feof($file_handle)){
      
fwrite($chunk_handlefread($file_handle1024));
    }
    
fclose($chunk_handle);
  }

  
fclose($file_handle);
  return 
$chunks;
}
 

2. Examples

Using these functions should be pretty self-explanatory. Both accept a string containing the path of the file to split, and an integer equal to the size of the desired chunks in bytes (1 kb = 1024 bytes, 1 MB = 1048576 bytes). Both functions return arrays. The difference is that file_chop() returns an array of the data chunks themselves, whereas file_chop_big() writes the chunks to disk (each saved as filename.chunk1, filename.chunk2, filename.chunk3, etc.), and returns an array of strings containing the file names of the chunks. In both cases, the last chunk will usually be smaller than the others (which are equal in size to the chunk size argument).

Here's an example of using file_chop() to save a file in a database:

<?php
$path 
'file.mp3';        //the file to chop up
$bytes 512000;           //size of the chunks in bytes (500k in this case)

$pieces file_chop($path$bytes);
echo 
"$path was chopped into " count($pieces) . " $bytes-byte chunks stored in $pieces";
//the last piece may be smaller than $bytes bytes

foreach ($pieces as $bit){
   
//insert $bit into your database
}
?>

post to Dzone Digg this! Add to del.icio.us Googleize this Add to reddit Save to myYahoo Add to furl Add to Netvouz! Spurl this! Add to Linkroll! Save to Simpy Give if thumbs up on StumbleUpon Save to Blinklist Add to Tektag Save to Bibsonomy Submit to Tweako
Search ERT on the Tools Page
Did you know? You can discuss this article with the mentor who wrote it and others interested in the topic? You are invited to join the discussion with Go to the forum

Got a technical article or tutorial you want to publish on the Internet? Join Go to the forum in the Round Table Forum and let the Mentors know what you have. If it meets ERT standards, is factual and can help ERT visitors, then ERT Mentors and Editors can help you (without charge) polish your offering so it can be published and promoted by ERT. An article published on ERT may be read by as many as 10,000 visitors a week; promoting you, your site, and your ideas. Please note ERT does not publish re-prints; promotional handouts, or pieces consisting mainly of links. So original technical content only please. If you prefer you can email the Editor