Mimesis

File Inclusion

This tutorial will highlight two useful ideas for Mimesis:

REQUIREMENTS

LIMITATIONS

Storing the file would be done exactly as will be displayed on this tutorial. However, no form will be provided. Therefore, if you wanted to use some sort of interface in order to make file storage easier it would be up to you to create it.

The URL obscuring will be done by creating a PHP document which accesses the database and reads the file information from it. Once the information is read the file will then send headers to the browser highlighting that it is in fact a file with its corresponding mimetype. In order to prevent hotlinking a unique identifier will be generated that changes dynamically so as to prevent a static URL which can be addressed.

Error handling has not been taken into account everywhere, as it can occur in various locations.

Keep in mind FILE PERMISSIONS ARE NOT GIVEN.

STRUCTURE

addtodb.php - will add the file into the database

display.php - will display the file (we'll be working with an image file)

imgcycle.php - will access the file and verify the unique identifer

CODE

First and foremost to use Mimesis you will need to have all the mimesis files in one location on your server. We'll assume they're located in a folder called mimesis. In order to use Mimesis you'll need to include the following directive into your code:

require_once('mimesis/Mimesis.php');

Now we need the location of the image you're going to be storing into the database:

$filename = 'somepic.jpg';

We need to create the array/row we're going to add into the database. It will be structured as follows:

$imgData = array( 'filename' => 'filename', 'mimetype' => 'mimetype', 'data' => 'file data' );

In this example the actual values will become:

$imgData = array( 'filename' => basename($filename), 'mimetype' => 'image/jpeg', 'data' => file_get_contents($filename) );

Now we need to create the table that will hold the image file as well as add the image file into the table. We start this by creating the Mimesis object:

$cwd = realpath(dirname(__FILE__)); $tableName = 'images'; $rowLabel = '000'; $columnsFile = 'keys'; $mimesis = new Mimesis($cwd, $tableName, $rowLabel, $columnsFile);

We're finally ready to start generating some actual files, so remember we have to lock the table and then proceed to include into it:

if($mimesis->lockTable()){ // This will fail if another process already has a lock on the object $mimesis->createTable(); // Creates the table/directory 'images' $mimesis->insertRow($imgData); // Creates the row '000' in the newly created 'images' }else{ trigger_error('Could not acquire lock on table', E_USER_ERROR); // Crash the program if a lock isn't acquired }

The completed addtodb.php code will look as follows:

addtodb.php

<?php require_once('mimesis/Mimesis.php'); $filename = 'somepic.jpg'; $imgData = array( 'filename' => basename($filename), 'mimetype' => 'image/jpeg', 'data' => file_get_contents($filename) ); $cwd = realpath(dirname(__FILE__)); $tableName = 'images'; $rowLabel = '000'; $columnsFile = 'keys'; $mimesis = new Mimesis($cwd, $tableName, $rowLabel, $columnsFile); if($mimesis->lockTable()){ $mimesis->createTable(); $mimesis->insertRow($imgData); }else{ trigger_error('Could not acquire lock on table', E_USER_ERROR); } $mimesis->releaseTable(); // Release the lock so other processes can affect the table ?>

Now we'll move on to the PHP file that will act as the image. In other words, the URL of the following page is what you would use for the <img>'s src attribute.

We include the Mimesis package as always:

require_once('mimesis/Mimesis.php');

On this page we'll be using the $_GET superglobal array for two things: to identify which image to load, and a unique identifier that will ensure this image is displayed dynamically rather than statically. Done as follows:

$salt = 'somestring'; // You would change this to a string of your choosing $id = md5(date('YmdHi') . $salt); // This is how we generate the unique ids if(isset($_GET['img']) && isset($_GET['id']) && file_exists('images/' . $_GET['img'] . '.php') && !strcasecmp($_GET['id'], $id)){ // The image is found and there are no problems }else{ header('HTTP/1.1 404 Not Found', true, 404); // Image not found and/or improper id given }

Assuming there are no errors then we read the image from our database and output it to the browser:

if(isset($_GET['img']) && isset($_GET['id']) && file_exists('images/' . $_GET['img'] . '.php') && !strcasecmp($_GET['id'], $id)){ $cwd = realpath(dirname(__FILE__)); $tableName = 'images'; $rowLabel = $_GET['img']; $columnsFile = 'keys'; $mimesis = new Mimesis($cwd, $tableName, $rowLabel, $columnsFile); $imgData = $mimesis->getRow(); // Retrieves the image's array // Output to browser using headers header('Content-Type: ' . $imgData['mimetype']); header('Content-Length: ' . strlen($imgData['data'])); echo $imgData['data']; }

The finalized code:

imgcycle.php

<?php require_once('mimesis/Mimesis.php'); $salt = 'somestring'; $id = md5(date('YmdHi') . $salt); if(isset($_GET['img']) && isset($_GET['id']) && file_exists('images/' . $_GET['img'] . '.php') && !strcasecmp($_GET['id'], $id)){ $cwd = realpath(dirname(__FILE__)); $tableName = 'images'; $rowLabel = $_GET['img']; $columnsFile = 'keys'; $mimesis = new Mimesis($cwd, $tableName, $rowLabel, $columnsFile); $imgData = $mimesis->getRow(); header('Content-Type: ' . $imgData['mimetype']); header('Content-Length: ' . strlen($imgData['data'])); echo $imgData['data']; }else{ header('HTTP/1.1 404 Not Found', true, 404); } ?>

Finally, the last piece of the puzzle will simply act as the page that holds the <img> tag in place and generates the id so that the image can be viewed:

display.php

<?php $salt = 'somestring'; // This must be the same as the one used in 'imgcycle.php' $id = md5(date('YmdHi') . $salt); echo '<img src="imgcycle.php?img=000&id=' . $id . '">'; ?>