PHP Upload Class
I wrote this class a long time ago, for PHP 4. Then when I switched to PHP 5, I completely rewrote it for PHP 5. It has undergone many changes, bug fixes, and features have been added. It is far from finished, but unfortunately, I don't use it or maintain it as much anymore. However, that's not to say that it isn't stable, or perfectly suited for use when a simple file needs to be uploaded, it can even handle multiple file uploads.
It contains built in functions for resizing and watermarking images upon upload, and included in the download are files in Arial 40pt for ready for watermarking, all you have to do is set the right path when you call the watermark function.
It's really easy to set up and get running, every variable and option is well commented, explaining exactly what each variable does, however, the inner workings of the code are not as well documented, but everything is pretty straight forward and should be easy to figure out should you need to change something.
An example of how to use the class has been included in the download files, however, don't just copy files to your server and expect it to work! You'll need to customize the settings to your specific website.
The Code
- <?php
- /*
- Sculch Upload Class
- This is a PHP class for use with sculch created
- applications, used for uploading files to the
- server.
- version: 5.2.9
- author: Mario Finelli, Jr. <http://www.sculch.com>
- */
- class sculch_upload {
- public $directory = "uploads/"; # The upload directory.
- public $set; # Set a value to apply a manual reaname of file.
- // Set $jumble to true to generate a random string of
- // characters to use as the filename, instead of the name
- // the file was uploaded with.
- public $jumble = false;
- // How many charcters to generate when creating a jumbled
- // filename.
- public $length = 10;
- // $conflict is the variable that is used to determine
- // conflict handling. If $conflict = 1 then the script will
- // generate a new, unique filename. If $conflict = 2 then the
- // script will overwrite the existing file. If $conflict = 3
- // then the script will throw an error and stop the script.
- public $conflict = 1;
- // This is an array of allowable extensions, leave it blank
- // to allow all extensions to be uploaded.
- // $field is set in the __construct function. This is the
- // field value in the HTML form to new check for a file
- // as well as send back the modifed filename if needed.
- private $field;
- private $target; # Target pathname for uploaded file.
- private $filename; # Filename of the uploaded file.
- private $name; # Actual name of file (no extension).
- private $extension; # Extension of the uploaded file.
- private $temp; # Temporary filename of the uploaded file.
- private $jumbled = ""; # Variable used to store jumbled filename.
- "n","o","p","q","r","s","t","u","v","w","x","y","z",
- "1","2","3","4","5","6","7","8","9","0","-");
- private $debug = false; # Used for testing purposes.
- private $ok = false; # Changes to true if the file is uploaded successfully.
- private $im;
- private $ims;
- private $w;
- private $h;
- private $x;
- private $y;
- private $str;
- private $tim;
- private $w_h;
- private $w_w;
- private $place;
- private $wim;
- private $available;
- private $x_pos;
- private $y_pos;
- private $e_upload;
- private $a_upload = true;
- private $e_watermark;
- private $a_watermark = true;
- private $e_resize;
- private $a_resize = true;
- private $fx;
- private $fy;
- private $fp;
- public function upload_errors(){
- return $this->e_upload;
- }
- public function watermark_errors(){
- return $this->e_watermark;
- }
- public function resize_errors(){
- return $this->e_resize;
- }
- public function get_fx(){
- return $this->fx;
- }
- public function get_fy(){
- return $this->fy;
- }
- private function debug($title, $data){
- if($this->debug){
- }
- }
- // fix_path() is a function used to remove the trailing
- // slash from $directory if it exists.
- private function fix_path(){
- $this->debug("Old Directory", $this->directory);
- }
- $this->debug("New Directory", $this->directory);
- }
- private function check_path(){
- $this->debug("Directory Status", "Had to make directory");
- } else {
- $this->debug("Directory Status", "Directory already existed");
- }
- }
- private function clean_filename(){
- //clean name
- //then attach extension with period
- //dont forget to validate extension
- //extension and name get saved to filename
- $this->name = preg_replace("/\s+|;|\"|\:|\*|@|'|}|{|=|\+|&|\^|%|\\$|#|\\\|\\/|\\?|<|>|\\||`|~|!/","_",$this->name);
- $this->filename = $this->name.".".$this->extension;
- }
- private function check_extension(){
- $this->e_upload = "your script was not configured properly. The allowed extensions variable needs to be an array";
- $this->a_upload = false;
- } else {
- // do nothing, all extensions are accepted
- return true;
- } else {
- for($e=0; $e<$n; $e++){
- }
- $this->e_upload = $this->extension." is not an allowable extension";
- $this->a_upload = false;
- } else {
- //extension checks
- return true;
- }
- }
- }
- }
- private function jumble(){
- for($i=0; $i<$this->length; $i++){
- if($i==0||$i==$this->length){
- } else {
- }
- }
- $this->debug("Jumbled Name",$this->jumbled);
- }
- private function unique(){
- // generate a unique filename
- switch($this->conflict){
- case 1:
- $i = 1; // counter
- $this->filename = $this->name."_$i.".$this->extension;
- $i++;
- }
- if($i!=1){
- $this->name = $this->name."_".($i-1);
- }
- break;
- case 2:
- // really there is nothing to do
- // because the file is going to
- // be overwritten
- break;
- case 3:
- // return an error
- $this->e_upload = "a file named ".$this->filename." already exists on the server";
- $this->a_upload = false;
- break;
- default:
- $this->e_upload = "your script was not configured properly. Conflict handling needs to have an integer value between one and three, inclusive";
- $this->a_upload = false;
- break;
- }
- }
- public function __construct($z){
- $this->field = $z;
- $this->fix_path();
- }
- private function file_details(){
- }
- public function upload_it(){
- $this->file_details();
- $this->check_extension();
- $this->target = $this->directory."/";
- $this->check_path();
- if($this->jumble){
- $this->jumble();
- $this->name = $this->jumbled;
- $this->filename = $this->jumbled.".".$this->extension;
- }
- if($this->set){
- $this->name = $this->set;
- $this->filename = $this->set.".".$this->extension;
- }
- $this->clean_filename();
- $this->unique();
- //beginning to move the file
- $this->e_upload = "there was an attempted upload attack";
- } else {
- if($this->a_upload){
- //file uploaded successfully
- $_POST[$this->field] = $this->filename;
- $this->ok = true;
- } else {
- $this->e_upload = "there was an attempted upload attack";
- }
- }
- }
- }
- private function make_source(){
- switch($this->extension){
- case "png":
- $this->ims = imagecreatefrompng($this->target.$this->filename);
- return true;
- break;
- case "jpg":
- case "jpeg":
- $this->ims = imagecreatefromjpeg($this->target.$this->filename);
- return true;
- break;
- case "gif":
- $this->ims = imagecreatefromgif($this->target.$this->filename);
- return true;
- break;
- default:
- return false;
- break;
- }
- }
- private function assign_tim($letter, $f){
- // slow, laborious, inefficient, but only way I could figure out
- switch($letter){
- case '&': $this->tim = imagecreatefrompng($f."/symbols/ampersand.png");return true;break;
- case '@': $this->tim = imagecreatefrompng($f."/symbols/at.png");return true;break;
- case '^': $this->tim = imagecreatefrompng($f."/symbols/caret.png");return true;break;
- case '<': $this->tim = imagecreatefrompng($f."/symbols/caret_left.png");return true;break;
- case '>': $this->tim = imagecreatefrompng($f."/symbols/caret_right.png");return true;break;
- case ':': $this->tim = imagecreatefrompng($f."/symbols/colon.png");return true;break;
- case ',': $this->tim = imagecreatefrompng($f."/symbols/comma.png");return true;break;
- //case '©': $this->tim = imagecreatefrompng($f."/symbols/copy.png");return true;break;
- case '-': $this->tim = imagecreatefrompng($f."/symbols/dash.png");return true;break;
- case '$': $this->tim = imagecreatefrompng($f."/symbols/dollar.png");return true;break;
- case '!': $this->tim = imagecreatefrompng($f."/symbols/exclamation.png");return true;break;
- case '(': $this->tim = imagecreatefrompng($f."/symbols/parentheses_left.png");return true;break;
- case ')': $this->tim = imagecreatefrompng($f."/symbols/parentheses_right.png.png");return true;break;
- case '%': $this->tim = imagecreatefrompng($f."/symbols/percent.png");return true;break;
- case '.': $this->tim = imagecreatefrompng($f."/symbols/period.png");return true;break;
- case '#': $this->tim = imagecreatefrompng($f."/symbols/pound.png");return true;break;
- case '?': $this->tim = imagecreatefrompng($f."/symbols/question.png");return true;break;
- case '\'': $this->tim = imagecreatefrompng($f."/symbols/quote.png");return true;break;
- case '"': $this->tim = imagecreatefrompng($f."/symbols/quotes.png");return true;break;
- case ';': $this->tim = imagecreatefrompng($f."/symbols/semicolon.png");return true;break;
- case '/': $this->tim = imagecreatefrompng($f."/symbols/slash.png");return true;break;
- case ' ': $this->tim = imagecreatefrompng($f."/symbols/space.png");return true;break;
- case '*': $this->tim = imagecreatefrompng($f."/symbols/star.png");return true;break;
- case '_': $this->tim = imagecreatefrompng($f."/symbols/underscore.png");return true;break;
- case 'A': $this->tim = imagecreatefrompng($f."/big/A.png");return true;break;
- case 'B': $this->tim = imagecreatefrompng($f."/big/B.png");return true;break;
- case 'C': $this->tim = imagecreatefrompng($f."/big/C.png");return true;break;
- case 'D': $this->tim = imagecreatefrompng($f."/big/D.png");return true;break;
- case 'E': $this->tim = imagecreatefrompng($f."/big/E.png");return true;break;
- case 'F': $this->tim = imagecreatefrompng($f."/big/F.png");return true;break;
- case 'G': $this->tim = imagecreatefrompng($f."/big/G.png");return true;break;
- case 'H': $this->tim = imagecreatefrompng($f."/big/H.png");return true;break;
- case 'I': $this->tim = imagecreatefrompng($f."/big/I.png");return true;break;
- case 'J': $this->tim = imagecreatefrompng($f."/big/J.png");return true;break;
- case 'K': $this->tim = imagecreatefrompng($f."/big/K.png");return true;break;
- case 'L': $this->tim = imagecreatefrompng($f."/big/L.png");return true;break;
- case 'M': $this->tim = imagecreatefrompng($f."/big/M.png");return true;break;
- case 'N': $this->tim = imagecreatefrompng($f."/big/N.png");return true;break;
- case 'O': $this->tim = imagecreatefrompng($f."/big/O.png");return true;break;
- case 'P': $this->tim = imagecreatefrompng($f."/big/P.png");return true;break;
- case 'Q': $this->tim = imagecreatefrompng($f."/big/Q.png");return true;break;
- case 'R': $this->tim = imagecreatefrompng($f."/big/R.png");return true;break;
- case 'S': $this->tim = imagecreatefrompng($f."/big/S.png");return true;break;
- case 'T': $this->tim = imagecreatefrompng($f."/big/T.png");return true;break;
- case 'U': $this->tim = imagecreatefrompng($f."/big/U.png");return true;break;
- case 'V': $this->tim = imagecreatefrompng($f."/big/V.png");return true;break;
- case 'W': $this->tim = imagecreatefrompng($f."/big/W.png");return true;break;
- case 'X': $this->tim = imagecreatefrompng($f."/big/X.png");return true;break;
- case 'Y': $this->tim = imagecreatefrompng($f."/big/Y.png");return true;break;
- case 'Z': $this->tim = imagecreatefrompng($f."/big/Z.png");return true;break;
- case 'a': $this->tim = imagecreatefrompng($f."/small/a.png");return true;break;
- case 'b': $this->tim = imagecreatefrompng($f."/small/b.png");return true;break;
- case 'c': $this->tim = imagecreatefrompng($f."/small/c.png");return true;break;
- case 'd': $this->tim = imagecreatefrompng($f."/small/d.png");return true;break;
- case 'e': $this->tim = imagecreatefrompng($f."/small/e.png");return true;break;
- case 'f': $this->tim = imagecreatefrompng($f."/small/f.png");return true;break;
- case 'g': $this->tim = imagecreatefrompng($f."/small/g.png");return true;break;
- case 'h': $this->tim = imagecreatefrompng($f."/small/h.png");return true;break;
- case 'i': $this->tim = imagecreatefrompng($f."/small/i.png");return true;break;
- case 'j': $this->tim = imagecreatefrompng($f."/small/j.png");return true;break;
- case 'k': $this->tim = imagecreatefrompng($f."/small/k.png");return true;break;
- case 'l': $this->tim = imagecreatefrompng($f."/small/l.png");return true;break;
- case 'm': $this->tim = imagecreatefrompng($f."/small/m.png");return true;break;
- case 'n': $this->tim = imagecreatefrompng($f."/small/n.png");return true;break;
- case 'o': $this->tim = imagecreatefrompng($f."/small/o.png");return true;break;
- case 'p': $this->tim = imagecreatefrompng($f."/small/p.png");return true;break;
- case 'q': $this->tim = imagecreatefrompng($f."/small/q.png");return true;break;
- case 'r': $this->tim = imagecreatefrompng($f."/small/r.png");return true;break;
- case 's': $this->tim = imagecreatefrompng($f."/small/s.png");return true;break;
- case 't': $this->tim = imagecreatefrompng($f."/small/t.png");return true;break;
- case 'u': $this->tim = imagecreatefrompng($f."/small/u.png");return true;break;
- case 'v': $this->tim = imagecreatefrompng($f."/small/v.png");return true;break;
- case 'w': $this->tim = imagecreatefrompng($f."/small/w.png");return true;break;
- case 'x': $this->tim = imagecreatefrompng($f."/small/x.png");return true;break;
- case 'y': $this->tim = imagecreatefrompng($f."/small/y.png");return true;break;
- case 'z': $this->tim = imagecreatefrompng($f."/small/z.png");return true;break;
- case '1': $this->tim = imagecreatefrompng($f."/numbers/1.png");return true;break;
- case '2': $this->tim = imagecreatefrompng($f."/numbers/2.png");return true;break;
- case '3': $this->tim = imagecreatefrompng($f."/numbers/3.png");return true;break;
- case '4': $this->tim = imagecreatefrompng($f."/numbers/4.png");return true;break;
- case '5': $this->tim = imagecreatefrompng($f."/numbers/5.png");return true;break;
- case '6': $this->tim = imagecreatefrompng($f."/numbers/6.png");return true;break;
- case '7': $this->tim = imagecreatefrompng($f."/numbers/7.png");return true;break;
- case '8': $this->tim = imagecreatefrompng($f."/numbers/8.png");return true;break;
- case '9': $this->tim = imagecreatefrompng($f."/numbers/9.png");return true;break;
- case '0': $this->tim = imagecreatefrompng($f."/numbers/0.png");return true;break;
- default: return false;break;
- }
- }
- private function get_xy($v, $h, $m){
- // do vertical alignment
- switch (strtolower($v)){
- case "top":
- case "t":
- case "upper":
- case "u":
- default:
- $this->y_pos = $m;
- break;
- case "middle":
- case "c":
- case "m":
- case "center":
- $this->y_pos = $m + ($this->available['y']/2) - ($this->w_h/2);
- break;
- case "bottom":
- case "b":
- case "lower":
- case "l":
- $this->y_pos = imagesy($this->ims) - $m - $this->w_h;
- break;
- }
- // do horizontal alignment
- switch (strtolower($h)){
- case "left":
- case "l":
- default:
- $this->x_pos = $m;
- break;
- case "middle":
- case "c":
- case "m":
- case "center":
- $this->x_pos = $m + ($this->available['x']/2) - ($this->w_w/2);
- break;
- case "right":
- case "r":
- $this->x_pos = imagesx($this->ims) - $m - $this->w_w;
- break;
- }
- }
- private function dimensions($aspect, $nw, $nh, $ow, $oh){
- if($aspect){
- if(($ow / $nw) >= ($oh / $nh)){
- $this->x = $nw;
- $this->y = round(($nw * $oh)/$ow);
- } else {
- $this->x = round(($nh * $ow)/$oh);
- $this->y = $nh;
- }
- } else {
- $this->x = $nw;
- $this->y = $nh;
- }
- }
- private function output($resource, $overwrite = true, $addition = "_small"){
- if($overwrite){
- switch($this->extension){
- case "png":
- imagepng($resource, $this->target.$this->filename);
- break;
- case "jpg":
- case "jpeg":
- imagejpeg($resource, $this->target.$this->filename, 100);
- break;
- case "gif":
- imagegif($resource, $this->target.$this->filename);
- break;
- default:
- // Theoretically this is impossible.
- break;
- }
- } else {
- switch($this->extension){
- case "png":
- imagepng($resource, $this->target.$this->name.$addition.".".$this->extension);
- break;
- case "jpg":
- case "jpeg":
- imagejpeg($resource, $this->target.$this->name.$addition.".".$this->extension, 100);
- break;
- case "gif":
- imagegif($resource, $this->target.$this->name.$addition.".".$this->extension);
- break;
- default:
- // Theoretically this is impossible.
- break;
- }
- }
- imagedestroy($this->ims);
- @imagedestroy($this->im);
- @imagedestroy($this->wim);
- @imagedestroy($this->tim);
- }
- public function watermark($s = "copyright string", $f = "location of files", $v = "top", $h = "left", $m = 15){
- if($this->ok){
- $this->str = str_split($s);
- if(substr($f, -1) == '/'){
- $f = substr($f, 0, -1);
- }
- //simple check for correct path
- $this->e_watermark = "the watermark images could not be found";
- return false;
- } else {
- $this->w_h = imagesy($this->tim);
- imagedestroy($this->tim);
- $this->debug("Watermark Height",$this->w_h);
- $this->w_w = 0;
- $this->place = 0;
- if(!$this->make_source()){
- $this->e_watermark = $this->extension." is not currently supported for modification";
- return false;
- }
- $c = count($this->str);
- $this->debug("Str Length",$c);
- for($i=0; $i<$c; $i++){
- if(!$this->assign_tim($this->str[$i], $f)){
- $this->e_watermark = "an unsupported character (".$this->str[$i].") was attempted. Please check your copyright string";
- return false;
- }
- $this->w_w += imagesx($this->tim);
- $this->debug("Letter Width",$this->str[$i]." ".imagesx($this->tim));
- imagedestroy($this->tim);
- }
- $this->debug("Watermark Width", $this->w_w);
- $this->wim = imagecreatetruecolor($this->w_w, $this->w_h);
- $fill = imagecolorallocatealpha($this->wim,0,0,0,127); // apply transparent background
- imagefill($this->wim,0,0,$fill);
- for($i=0; $i<$c; $i++){
- if(!$this->assign_tim($this->str[$i], $f)){
- $this->e_watermark = "an unsupported character was attempted. Please check your copyright string";
- return false;
- }
- $this->debug("Place of", $this->str[$i].": ".$this->place);
- $xx = imagesx($this->tim);
- imagecopy($this->wim,$this->tim,$this->place,0,0,0,$xx,imagesy($this->tim));
- $this->place += $xx;
- imagedestroy($this->tim);
- }
- $this->available['x'] = (imagesx($this->ims) - (2*$m));
- $this->available['y'] = (imagesy($this->ims) - (2*$m));
- $this->debug("Available dimensions", $this->available['x']."x".$this->available['y']);
- if($this->w_w > $this->available['x'] || $this->w_h > $this->available['y']){
- //need to resize watermark so it fits
- $this->dimensions(true, $this->available['x'], $this->available['y'], $this->w_w, $this->w_h);
- $this->tim = $this->wim;
- $this->wim = imagecreatetruecolor($this->x, $this->y);
- $fill = imagecolorallocatealpha($this->wim,0,0,0,127);
- imagefill($this->wim,0,0,$fill);
- imagecopyresampled($this->wim, $this->tim, 0,0,0,0, $this->x, $this->y, $this->w_w, $this->w_h);
- $this->w_w = $this->x;
- $this->w_h = $this->y;
- imagedestroy($this->tim);
- }
- $this->get_xy($v, $h, $m);
- $this->debug("Watermark horizontal",$this->y_pos);
- if($this->extension == "gif"){
- //change gif to true color before watermark paste
- $this->tim = imagecreatetruecolor(imagesx($this->ims), imagesy($this->ims));
- imagecopy($this->tim,$this->ims,0,0,0,0,imagesx($this->ims),imagesy($this->ims));
- $this->ims = imagecreatetruecolor(imagesx($this->tim), imagesy($this->tim));
- imagecopy($this->ims,$this->tim,0,0,0,0,imagesx($this->tim),imagesy($this->tim));
- }
- imagecopy($this->ims, $this->wim, $this->x_pos,$this->y_pos,0,0,$this->w_w, $this->w_h);
- }
- // output image here
- if($this->a_watermark){
- $this->output($this->ims, true);
- }
- } else {
- if($this->a_upload){
- $this->e_watermark = "the file can not be modified before it us uploaded to the server. Chnage the method order in your script";
- $this->a_upload = false;
- }
- }
- }
- public function resize($width, $height, $overwrite = true, $addition = "_small", $aspect = true){
- if($this->ok){
- if(!$this->make_source()){
- $this->e_resize = $this->extension." is not currently supported for modification";
- return false;
- }
- $this->w = imagesx($this->ims);
- $this->h = imagesy($this->ims);
- $this->debug("Old X", $this->w);
- $this->debug("Old Y", $this->h);
- // New Dimesions
- $this->dimensions($aspect, $width, $height, $this->w, $this->h);
- $this->debug("New X", $this->x);
- $this->debug("New Y", $this->y);
- switch($this->extension){
- case "png":
- case "jpg":
- case "jpeg":
- $this->im = imagecreatetruecolor($this->x, $this->y);
- break;
- case "gif":
- $this->im = imagecreate($this->x, $this->y);
- break;
- default:
- // Theoretically this is impossible.
- break;
- }
- if($this->w < $width && $this->h < $height){
- return false;
- } else {
- imagecopyresampled($this->im, $this->ims, 0,0,0,0, $this->x, $this->y, $this->w, $this->h);
- }
- if($this->a_resize){
- $this->output($this->im, $overwrite, $addition);
- }
- //if($overwrite){
- $this->fx = $this->x;
- $this->fy = $this->y;
- //} else {
- //$this->fx = $this->w;
- //$this->fy = $this->h;
- //}
- } else {
- if($this->a_upload){
- $this->e_resize = "the file can not be modified before it us uploaded to the server. Change the method order in your script";
- $this->a_upload = false;
- }
- }
- }
- }
- ?>
The Download
| Filename | sculch-upload.zip |
|---|---|
| Filesize | 222475 bytes |
| Filetype | ZIP Archive |
| MD5 checksum | 31437da6ce4708f541419058db6cbd81 |
| License | © 2006-2009 by Sculch, LLC. under the MIT License |
