Zend - The PHP Company




Files and Directories

Add Code


Filemanager class  

Type: class
Added by: gnarf
Entered: 20/04/2004
Last modified: 03/12/2004
Rating: - (fewer than 3 votes)
Views: 5442
The filemanager class can be used to create a php filemanger, you can define a chrooted kind of basedir, and use the $_GET array to define a subdir. It has some built in protection against "?subdir=../" stuff and it has alot of little extras, like sort functions, MIME type checks and lots more. I have been using it a long time now, and it never failed me :)


<?php

/* Filemanager class
 *
 * What is it?
 *   This class reads a directory and collects all data on files and directories.
 *
 * AUTHOR:
 *   Johan Adriaans <gnarf@izi-games.com>
 *
 * USAGE:
 *   $base_dir    = "/";
 *   $sub_dir     = "etc/";
 *   $dir = new fileman($base_dir, $sub_dir);
 *   foreach($dir->directories as $directory)    print $directory->name    . "<BR>";
 *   foreach($dir->files as $file)        print $file->name     . "<BR>";
 *
 * STRUCTURE VIEW:
 *   $base_dir    = "/";
 *   $sub_dir     = "etc/";
 *   $dir = new fileman($base_dir, $sub_dir);
 *   print "<PRE>";
 *   foreach($dir->directories as $directory)    print_r($directory);
 *   foreach($dir->files as $file)        print_r($file);
 *   print "</PRE>";
 *
 * GET MIME TYPE FROM FILE:
 *   ...[snip]...
 *   $mime = $file->get_mime();
 *
 * THE DIR OBJECT:
 *   dir Object
 *   (
 *       [stat] => Array
 *           (
 *               [0] => 5635
 *               [1] => 245761
 *               [2] => 16877
 *               [3] => 8
 *               [4] => 0
 *               [5] => 0
 *               [6] => 0
 *               [7] => 4096
 *               [8] => 1082426524
 *               [9] => 1079356208
 *               [10] => 1079356208
 *               [11] => 4096
 *               [12] => 8
 *               [dev] => 5635
 *               [ino] => 245761
 *               [mode] => 16877
 *               [nlink] => 8
 *               [uid] => 0
 *               [gid] => 0
 *               [rdev] => 0
 *               [size] => 4096
 *               [atime] => 1082426524
 *               [mtime] => 1079356208
 *               [ctime] => 1079356208
 *               [blksize] => 4096
 *               [blocks] => 8
 *           )
 *
 *       [pathinfo] => Array
 *           (
 *               [dirname] => /etc
 *               [basename] => sysconfig
 *           )
 *
 *       [name] => sysconfig
 *       [path] => /etc
 *       [dirname] => /etc
 *       [basename] => sysconfig
 *       [size] => 4096
 *       [read] =>
 *       [write] =>
 *       [execute] =>
 *       [uid] => 0
 *       [gid] => 0
 *       [date] => 1079356208
 *   )
 *
 * THE FILE OBJECT:
 *   file Object
 *   (
 *       [stat] => Array
 *           (
 *               [0] => 5635
 *               [1] => 229444
 *               [2] => 33188
 *               [3] => 1
 *               [4] => 0
 *               [5] => 0
 *               [6] => 0
 *               [7] => 1756
 *               [8] => 1079356052
 *               [9] => 1019234121
 *               [10] => 1075921583
 *               [11] => 4096
 *               [12] => 8
 *               [dev] => 5635
 *               [ino] => 229444
 *               [mode] => 33188
 *               [nlink] => 1
 *               [uid] => 0
 *               [gid] => 0
 *               [rdev] => 0
 *               [size] => 1756
 *               [atime] => 1079356052
 *               [mtime] => 1019234121
 *               [ctime] => 1075921583
 *               [blksize] => 4096
 *               [blocks] => 8
 *           )
 *
 *       [pathinfo] => Array
 *           (
 *               [dirname] => /etc
 *               [basename] => inittab
 *           )
 *
 *       [name] => inittab
 *       [path] => /etc/
 *       [dirname] => /etc/
 *       [basename] => inittab
 *       [extension] =>
 *       [size] => 1756
 *       [size_h] => 1.71 KB
 *       [read] => 1
 *       [write] =>
 *       [execute] =>
 *       [mime] =>
 *       [uid] => 0
 *       [gid] => 0
 *       [date] => 1019234121
 *   )
 */

class file {
  var 
$stat    = array();
  var 
$pathinfo    = array();
  var 
$name;
  var 
$path;
  var 
$dirname;
  var 
$basename;
  var 
$extension;
  var 
$size;
  var 
$size_h;
  var 
$read;
  var 
$write;
  var 
$execute;
  var 
$mime;

  
////
  //  function file
  //  (Constructor) Reads the rights and sets the default value for a file
  ////

  
function file ($file) {
    
$this->stat        stat($file);
    
$this->pathinfo    pathinfo($file);
    
$this->dirname    $this->pathinfo["dirname"];
    
$this->basename    $this->pathinfo["basename"];
    
$this->extension    strtolower($this->pathinfo["extension"]);
    
$this->size        $this->stat[7];
    
$this->uid        $this->stat[4];
    
$this->gid        $this->stat[5];
    
$this->date        $this->stat[9];

    if (!
ereg("/$"$this->dirname )) $this->dirname  .= "/";

    
// Create a human readable file size
    
if ($this->size 1024)        $this->size_h $this->size " bytes";
    if (
$this->size 1024)        $this->size_h round($this->size 10242) . " KB";
    if (
$this->size 1048576)        $this->size_h round($this->size 10485762) . " MB";
    if (
$this->size 1073741824)    $this->size_h round($this->size 10737418242) . " GB";

    
$this->read false;
    
$this->write false;
    
$this->execute false;
    if (
is_readable($file))    $this->read true;
    if (
is_writable($file))    $this->write true;
    if (
is_executable($file))    $this->execute true;
    
clearstatcache();

    
// aliasses
    
$this->name $this->basename;
    
$this->path $this->dirname;
  }

  function 
get_mime() {
    
$verify TRUE;
    
$fn $this->dirname $this->name;

    if (empty(
$fn)) {
      return 
"";
    }

    if (
$verify) {
      if (
$fp = @fopen($fn"rb")) {
        
$fcont fread($fp32);
        
fclose($fp);
      } else {
        return 
"";
      }
    }

    
$ext $this->extension;

    switch (
$ext) {
      case 
"aif":
      case 
"aifc":
      case 
"aiff":
        return 
"audio/aiff";

      case 
"asp":
        return 
"text/asp";

      case 
"avi":
        return 
"video/avi" .
          (!
$verify || (substr($fcont04) == "RIFF") ? "" "*");

      case 
"mpg":
      case 
"mpeg":
        return 
"video/mpeg";

      case 
"wmv":
        return 
"video/windows-media";

      case 
"bmp":
        return 
"image/bmp" .
          (!
$verify || (substr($fcont02) == "BM") ? "" "*");

      case 
"css":
        return 
"text/css";

      case 
"doc":
        return 
"application/msword" .
          (!
$verify ||
          (
substr($fcont08) == "xD0xCFx11xE0xA1xB1x1AxE1") ?
                 
"" "*");

      case 
"exe":
      case 
"dll":
      case 
"scr":
        return 
"application/x-msdownload" .
          (!
$verify || (substr($fcont02) == "MZ") ? "" "*");

      case 
"hlp":
        return 
"application/windows-help" .
          (!
$verify ||
          (
substr($fcont04) == "x3Fx5Fx03x00") ? "" "*");

      case 
"htm":
      case 
"html":
        return 
"text/html" .
          (!
$verify ||
          (
substr($fcont06) == "<html>") ||
          (
substr($fcont014) == "<!DOCTYPE HTML") ?
          
"" "*");

      case 
"gif":
        return 
"image/gif" .
          (!
$verify || (substr($fcont03) == "GIF") ? "" "*");

      case 
"gz":
      case 
"tgz":
        return 
"application/x-gzip" .
          (!
$verify || (substr($fcont03) == "x1Fx8Bx08") ? "" "*");

      case 
"jfif":
      case 
"jpe":
      case 
"jpeg":
      case 
"jpg":
        return 
"image/jpeg" .
         (!
$verify ||
         (
substr($fcont010) == "xFFxD8xFFxE0x00x10JFIF") ?
          
"" "*");

      case 
"mov":
        return 
"video/quicktime";

      case 
"pdf":
        return 
"application/pdf" .
          (!
$verify || (substr($fcont04) == "%PDF") ? "" "*");

      case 
"php":
      case 
"php3":
      case 
"php4":
      case 
"phtml":
        return 
"application/x-httpd-php" .
          (!
$verify || (substr($fcont05) == "<?") ? "" "*");

      case 
"pl":
        return 
"text/perl" .
          (!
$verify ||
          (
substr($fcont021) == "#!/usr/local/bin/perl") ? "" "*");

      case 
"png":
        return 
"image/x-png" .
          (!
$verify || (substr($fcont04) == "x89PNG") ? "" "*");

      case 
"psd":
        return 
"image/psd" .
          (!
$verify || (substr($fcont04) == "8BPS") ? "" "*");

      case 
"tiff":
      case 
"tif":
        return 
"image/tiff" .
          (!
$verify ||
          (
substr($fcont08) == "x4Dx4Dx00x2Ax00x00x00x08") ||
          (
substr($fcont04) == "x49x49x2Ax00") ?
          
"" "*");

      case 
"ttf":
        return 
"application/x-ttf";

      case 
"txt":
      case 
"ini":
      case 
"log":
      case 
"sql":
      case 
"cfg":
      case 
"conf":
        return 
"text/plain";

      case 
"swf":
        return 
"application/x-shockwave-flash";


      case 
"wav":
        return 
"audio/x-wav" .
          (!
$verify || (substr($fcont04) == "RIFF") ? "" "*");

      case 
"wma":
        return 
"audio/x-ms-wma";

      case 
"mp3":
        return 
"audio/x-mp3";

      case 
"xml":
        return 
"text/xml" .
          (!
$verify || (substr($fcont05) == "<?xml") ? "" "*");

      case 
"zip":
        return 
"application/x-zip-compressed" .
          (!
$verify || (substr($fcont02) == "PK") ? "" "*");
    }
    return 
"";
  }
}

class 
dir {
  var 
$stat    = array();
  var 
$pathinfo    = array();
  var 
$name;
  var 
$path;
  var 
$dirname;
  var 
$dirname;
  var 
$basename;
  var 
$size;
  var 
$read;
  var 
$write;
  var 
$execute;

  
////
  //  function dir
  //  (Constructor) Reads the rights and sets the default value for a directory
  ////

  
function dir ($dir) {
    
$this->stat        stat($dir);
    
$this->pathinfo    pathinfo($dir);
    
$this->size        $this->stat[7];
    
$this->uid        $this->stat[4];
    
$this->gid        $this->stat[5];
    
$this->date        $this->stat[9];
    
$this->dirname    $this->pathinfo["dirname"];
    
$this->basename    $this->pathinfo["basename"];

    
$this->read false;
    
$this->write false;
    
$this->execute false;
    if (
is_readable($file))    $this->read true;
    if (
is_writable($file))    $this->write true;
    if (
is_executable($file))    $this->execute true;
    
clearstatcache();

    
// aliasses
    
$this->name $this->basename;
    
$this->path $this->dirname;
  }
}

class 
fileman {

  var 
$files        = array();
  var 
$directories    = array();
  var 
$base_dir;
  var 
$sub_dir;
  var 
$dir_obj;
  var 
$error_strings    = array();
  var 
$complete_path;
  var 
$readable;
  var 
$sort_order;

  
////
  //  function fileman
  //  (Constructor) Reads the rights, sets the default value for a directory and starts the dir read loop.
  ////

  
function fileman ($base_dir$sub_dir) {
    
// Add final slashes do the dirs in ARGS and create a full string.
    
if (!ereg("/$"$base_dir)) $base_dir .= "/";
    if (!
ereg("/$"$sub_dir )) $sub_dir  .= "/";
    
$this->sub_dir        $sub_dir;
    
$this->base_dir        $base_dir;
    
$this->complete_path    $base_dir $sub_dir;
    
// Checks if given dir is a valid one and is readable.
    
if (!is_dir($this->complete_path))        $this->error("$sub_dir is not a valid directory.");
    if (
ereg("../"$this->sub_dir))        $this->error("$sub_dir contains a '../' string, this is not permited due to security issues.");
    if (!
is_readable($this->complete_path)) {
      
$this->error("$sub_dir is not a readable directory.");
      
$this->readable false;
    } else {
      
$this->readable true;
    }

    
$this->check_errors();
    
$this->read_directory();
    return 
true;
  }

  
////
  //  function read_directory
  //  Reads the current directory and calls the file and dir classes.
  ////

  
function read_directory () {
    
$dir_counter 0;
    
$file_counter 0;
    
$this->dir_obj opendir($this->complete_path);
    while (
FALSE !== ($object readdir($this->dir_obj))) {
      if (
$object == ".")  continue;
      if (
$object == "..") continue;

      if (
is_file($this->complete_path $object)) {
          
$file_counter++;
        
$this->files[$file_counter] = new file ($this->complete_path $object);
      }
      if (
is_dir($this->complete_path $object)) {
          
$dir_counter++;
        
$this->directories[$dir_counter] = new dir ($this->complete_path $object);
      }
    }
    
closedir($this->dir_obj);
  }

  
////
  //  function sort
  //  Sorts the file and directory listing to to the string specified (name, extension, size, date)
  ////

  
function sort ($sort) {
    
$this->sort_order $sort;
    
usort($this->files,     array ($this"compare"));
    
usort($this->directories,     array ($this"compare"));
  }
  
// File sorting part, used by sort function.
  
function compare ($a$b) {
    if (
$this->sort_order == "name")        return strcasecmp($a->name$b->name);
    if (
$this->sort_order == "extension")    return strcasecmp($a->extension$b->extension);
    if (
$this->sort_order == "date")        return strcasecmp($a->date$b->date);
    if (
$this->sort_order == "size")        return ($a->size $b->size) ? : -1;
    return 
strcasecmp($a->name$b->name);
  }

  
////
  //  function error
  //  Adds error to the error string.
  ////

  
function error ($string) {
    
$this->error_strings[] = $string;
  }

  
////
  //  function check_error
  //  Checks if any errors were found. and takes action.
  ////

  
function check_errors () {
    if (
count($this->error_strings) > 0) {
      foreach (
$this->error_strings as $error) { print $error "<BR>"; }
      print 
"Errors found: " count($this->error_strings) . "<P>";
      exit;
    } else {
      return 
true;
    }
  }
}
// END OF MAIN CLASS
?>


Usage Example


See the example


Rate This Script





Search



This Category All Categories