<?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))
{
" " . 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
?>