Location: PHPKode > scripts > MySQL File System > mysql-file-system/mysql_filesystem_class_inc.php
<?php

/**
 * Class mysql_filesystem
 * Class to manipulate BLOB data types in MySQL
 * The aim of this class is to provide a solid method to store binary data in MySQL tables
 * Class will create a virtual filesystem with Inodes and trees for accurate storage
 * Binary Data is split up into 64K chunks for easy manipulation
 * 64K chunks are manageable by PHP's string functions, and provide easy access to the data
 * Inodes are used to create relationships without the use of MySQL relationships (FK) or Joins
 * @author Paul Scott
 * @copyright Paul Scott
 * @package phpclasses
 */

class mysql_filesystem
{
	/**
	 * Set up some vars
	 */
	var $server;
	var $dbport;
	var $username;
	var $password;
	var $dbname;
	
	/**
	 * Class instantiator
	 */
	function mysql_filesystem($server, $dbport, $username, $password, $dbname)
	{
		$this->server = $server;
		$this->dbport = $dbport;
		$this->username = $username;
		$this->password = $password;
		$this->dbname = $dbname;
	}
	
	/**
	 * function to create the tables neccessary for the functioning of this system
	 * @author Paul Scott
	 * @copyright Paul Scott
	 */
	function createTables()
	{
		$sq1 = "CREATE TABLE file (
			id mediumint(8) unsigned NOT NULL auto_increment,
			datatype varchar(60) NOT NULL default 'application/octet-stream',
			name varchar(120) NOT NULL default '',
			size bigint(20) unsigned NOT NULL default '1024',
			filedate datetime NOT NULL default '0000-00-00 00:00:00',
			PRIMARY KEY (id) ) TYPE=MyISAM";

		$sql .= "CREATE TABLE filedata (
			id mediumint(8) unsigned NOT NULL auto_increment,
			masterid mediumint(8) unsigned NOT NULL default '0',
			filedata blob NOT NULL,
			PRIMARY KEY (id),
			KEY master_idx (masterid) ) TYPE=MyISAM";
		//do the creation
		$linkid = $this->storage_connect();
		if (!$RES = mysql_query($sql, $linkid)) 
		{
    		die("Could not create tables");
    	}

	}
	
	/**
	 * Function to connect to the storage database
	 * @author Paul Scott
	 * @copyright Paul Scott
	 * @param mysql connection params
	 * @return $linkid on success
	 */
	function storage_connect()
	{
		$server = $this->server;
		$port = $this->dbport;
		$username = $this->username;
		$password = $this->password;
		$dbname = $this->dbname;
		
		$connectto = $server . ":" . $port;
		
		if (!$linkid = @mysql_connect($connectto, $username, $password)) 
		{
			"&nbsp;&nbsp;" . die("Unable to connect to storage server!");
		}

		if (!mysql_select_db($dbname, $linkid)) 
		{
  			die("Unable to connect to storage database!");
		}
		
		return $linkid;
	}
		
	
	/**
	 * Method to insert the data into the tables 
	 * creating an entry in the Inodes table 
	 * and the corresponding "chunk" entries in the data table
	 * @author Paul Scott
	 * @copyright Paul Scott
	 */
	 function uploadProcess($srcPathFile, $srcFileType)
	 {
			//set up the connection	
	 		$linkid = $this->storage_connect();	
  			
	 		$DstFileName = basename($srcPathFile); 

  			clearstatcache();
  			$time = filemtime($srcPathFile);
  			$storedate = date("Y-m-d H:i:s", $time);

  			// File Processing
  			if (file_exists($srcPathFile) && is_file($srcPathFile)) 
  			{

    			// Insert into file table
    			$SQL  = "insert into file (datatype, name, size, filedate) values ('";
    			$SQL .= $srcFileType . "', '" . $DstFileName . "', " . filesize($srcPathFile);
    			$SQL .= ", '" . $storedate . "')";

    			if (!$RES = mysql_query($SQL, $linkid)) 
    			{
      				die("Failure on insert to file table!");
    			}

    			$fileid = mysql_insert_id($linkid);
    			

    			// Insert into the filedata table
    			$fp = fopen($srcPathFile, "rb");
    			while (!feof($fp)) 
    			{

      				// Make the data mysql insert safe
      				$binarydata = addslashes(fread($fp, 65535));

      				$SQL = "insert into filedata (masterid, filedata) values (";
      				$SQL .= $fileid . ", '" . $binarydata . "')";

      				if (!mysql_query($SQL, $linkid)) 
      				{
        				die("Failure to insert binary inode data row!");
      				}
    			}

    			fclose($fp);
  			}//if file exists srcfile

		return $fileid;

	 }//function
	 
	 /**
	  * Method to extract the data according to an Inode entry
	  * This method will fetch all the chunks of a file and rebuild it
      * @param fileid
      * @return file
	  * @author Paul Scott
	  * @copyright Paul Scott
	  */
	 function getFile($fileId)
	 {
	 	//set up the connection	
	 	$linkid = $this->storage_connect();	
  			
	 	$nodelist = array();

  		// Pull file meta-data
  		$SQL = "select * from file where id = " . $fileId;
  		if (!$RES = mysql_query($SQL, $linkid)) 
  		{
    		die("Failure to retrive file metadata");
  		}

  		if (mysql_num_rows($RES) != 1) 
  		{
    		die("Not a valid file id!");
  		}

  		$FileObj = mysql_fetch_object($RES);

  		// Pull the list of file inodes
  		$SQL = "SELECT id FROM filedata WHERE masterid = " . $fileId . " order by id";

  		if (!$RES = mysql_query($SQL, $linkid)) 
  		{
    		die("Failure to retrive list of file inodes");
  		}

  		while ($CUR = mysql_fetch_object($RES)) 
  		{
    		$nodelist[] = $CUR->id;
  		}

  		// Send down the header to the client
  		Header ( "Content-Type: $FileObj->datatype" );
  		Header ( "Content-Length: " . $FileObj->size );
  		Header ( "Content-Disposition: attachment; filename=$FileObj->name" );

  		// Loop through and stream the nodes 1 by 1

  		for ($Z = 0 ; $Z < count($nodelist) ; $Z++) 
  		{
    		$SQL = "select filedata from filedata where id = " . $nodelist[$Z];

    		if (!$RESX = mysql_query($SQL, $linkid)) 
    		{
      			die("Failure to retrive file node data");
    		}

    		$DataObj = mysql_fetch_object($RESX);
    		return $DataObj->filedata;
  		}
	}//end function 
	 	
	 
	 
	 /**
	  * Upload file form
	  * Simple html form to upload a file
	  * @deprecated 
	  * @author Paul Scott
	  * @copyright Paul Scott
	  * @deprecated form no longer used, rather populate the db programatically, for security
	  */
	 function uploadForm()
	 {
	 	$form =  "<form method='post' action='" . $this->uploadProcess() . "' enctype='multipart/form-data'>";
		$form .= "<input type='file' name='file1' size='20'>";
		$form .= "<input type='submit' name='submit' value='submit'>";
		$form .= "</form>";
		return $form;
	 }
	 
}//end class
?>
Return current item: MySQL File System