Download
<?php
/*
Autor: Ulrich Floer (combie) uli@combie.de
Ausgangspunkt für diesen Wrapper ist die Doku und das Beispiel
zu stream_wrapper_register() zu finden auf:
z.B. http://de3.php.net/manual/de/function.stream-wrapper-register.php

Diese Software befindet sich noch im experimentellen Stadium.
Die Benuztzung erfolgt auf eigene Gefahr.

*/



class MysqlWrapper 
{
/**/ 
// PHP 4
   
var $position 0;
   var 
$params = array();
   var 
$locator = array();
   var 
$db_hdl FALSE;
   var 
$content ='';
   var 
$dirty FALSE;
   var 
$cachefile FALSE;
   var 
$dirptr 0;
   var 
$dir = array();
   
 
 
/*     
// PHP 5
   private $position = 0;
   private $params = array();
   private $locator = array();
   private $db_hdl = FALSE;
   private $content ='';
   private $dirty = FALSE;
   private $cachefile = FALSE;
   private $dirptr = 0;
   private $dir = array();
*/

   

/* ------------------------------------------------------- 

 Stream Funktionen


*/
   
  
function stream_open($path$mode$options,&$opened_path// public
  
{
    
$this->params['path'] = $path;  
    
$this->params['mode'] = strtolower($mode);  
    
$this->params['options'] = $options;  
    
$this->params['opened_path'] = $opened_path;  
    
$this->zerlege_path($this->params['path']);
    
// var_dump($this->locator);
    
if (count($this->locator)!== 9) return FALSE;
    if (
FALSE  === $this->locator) return FALSE;
    if(
defined('MYSQLWRAPPER_CACHE_DIR'))
       
$this->cachefile MYSQLWRAPPER_CACHE_DIR.'/'.md5($this->params['path']);
    if (
$this->has_flag('r'))
    {
      if(
$this->read_from_cache()) return TRUE
      if(
$this->read_from_db()) 
      {
        
$this->write_to_cache();
      }else
      {
        return 
FALSE;
      }  

    }elseif (
$this->has_flag('a')) 
    {
      if(! 
$this->read_from_cache())
      {
        if(
$this->read_from_db()) 
        {
          
$this->write_to_cache();
        }
      }
      
$this->position strlen($this->content);
    } 
    if (
$this->has_flag('w')) $this->dirty TRUE
    return 
TRUE;

 }
  
   function 
stream_read($count)  // public
   
{
       if (
              (
$this->has_flag('r'))||
              (
$this->has_flag('w') && $this->has_flag('+'))||
              (
$this->has_flag('a') && $this->has_flag('+'))
          )
       {   
         
$ret substr($this->content$this->position$count);
         
$this->position += strlen($ret);
         return 
$ret;
       } else return 
0;
   }

   function 
stream_write($data)  // public
   
{
       if (
              (
$this->has_flag('a'))||
              (
$this->has_flag('w'))||
              (
$this->has_flag('r') && $this->has_flag('+'))
          )
       { 
         
$left substr($this->content0$this->position);
         
$right substr($this->content$this->position strlen($data));
         
$this->content $left $data $right;
         
$this->position += strlen($data);
         
$this->dirty TRUE;
         return 
strlen($data);
       }else return 
0;
   }

   function 
stream_tell()  // public
   
{
       return 
$this->position;
   }

   function 
stream_eof()  // public
   
{
       return 
$this->position >= strlen($this->content);
   }
   
  function 
stream_flush()  // public
  
{
    if(
$this->dirty)
    {
      if (
FALSE === $this->dbconnect())return FALSE;
      
$temp mysql_real_escape_string($this->content);
      
$sql  "INSERT INTO `{$this->locator['tabelle']}` ";
      
$sql .= " (`{$this->locator['idspalte']}`,`{$this->locator['codespalte']}`) ";
      
$sql .= "values ('{$this->locator['id']}','$temp') ";
      
$res mysql_query($sql,$this->db_hdl); 
      if (
FALSE === $res
      {
        
$sql  "UPDATE `{$this->locator['tabelle']}` SET ";
        
$sql .= " `{$this->locator['codespalte']}`='$temp' ";
        
$sql .= " WHERE `{$this->locator['idspalte']}`='{$this->locator['id']}' ";
        
$res mysql_query($sql,$this->db_hdl);
        if (
FALSE === $res)return FALSE;
      }
      
$this->dirty FALSE;
      
$this->write_to_cache();
    }
    return 
TRUE
  }

  function 
stream_close()  // public
   
{
      
$this->stream_flush(); 
      
//if(FALSE !== $this->db_hdl) mysql_close($this->db_hdl);
      // es besteht keine Notwendigkeit, die Verbindung zu schließen
   
}
   
  function 
stream_stat()  // public  
   
{
   
     if(
version_compare(PHP_VERSION"5.0.0""<")) return FALSE;
     
$result =  $this->get_dummy_stat('file',strlen($this->content));
     return 
$result //  FALSE;
   
}

   function 
stream_seek($offset$whence)  // public
   
{
       switch (
$whence) {
           case 
SEEK_SET:
               if (
$offset strlen($this->content) && $offset >= 0
               {
                     
$this->position $offset;
                     return 
true;
               } else return 
FALSE;
               break;
           case 
SEEK_CUR:
               if (
$offset >= 0
               {
                     
$this->position += $offset;
                     return 
true;
               } else  return 
FALSE;
               break;
           case 
SEEK_END:
               if (
strlen($this->content) + $offset >= 0
               {
                     
$this->position strlen($this->content) + $offset;
                     return 
true;
               } else  return 
FALSE;
               break;
           default:
               return 
FALSE;
       }
   }

/*  ------------------------------------------------------- 

 Dateisystem Funktionen


*/

  
function unlink($pfad)  // public
  
{
    if (!isset(
$this))
    { 
// statischen Aufruf ermoeglichen
      
$selbst __CLASS__ ;
      
$child = @ new $selbst  ;
      return 
$child->unlink($pfad);
    }
    
$this->zerlege_path($pfad);
    if (
count($this->locator)!== 9) return FALSE;
    if (
FALSE  === $this->locator) return FALSE;
    if (
FALSE  === $this->dbconnect()) return FALSE;
    if(
defined('MYSQLWRAPPER_CACHE_DIR'))
    {
        
$cachefile MYSQLWRAPPER_CACHE_DIR.'/'.md5($pfad);
        if (
file_exists($cachefile)) unlink($cachefile);
    }
    
$sql  "DELETE FROM `{$this->locator['tabelle']}` ";
    
$sql .= " WHERE `{$this->locator['idspalte']}`='{$this->locator['id']}'";
    
$res mysql_query($sql,$this->db_hdl);
    if (
FALSE === $res) return FALSE;
    if (
mysql_affected_rows ($this->db_hdl) > 0) return TRUE;
    return 
FALSE;
  }
  
  function 
is_dir($pfad)  // public auch static
  
{
    if (!isset(
$this))
    { 
// statischen Aufruf ermoeglichen
      
$selbst __CLASS__ ;
      
$child = @ new $selbst  ;
      return 
$child->is_dir($pfad);
    }
    
$fh $this->stream_open($pfad,'r',0,$openpath);
    if (
FALSE === $fh)
    {
      
$dh $this->dir_opendir($pfad,0);
      if  (
FALSE === $dh) return FALSE;
      
$this->dir_closedir($dh);
      return 
TRUE;
    }else
    {
      
$this->stream_close($fh);
      return 
FALSE;
    }
  }
  
  function 
is_file($pfad)  // public auch static
  
{
    if (!isset(
$this))
    { 
// statischen Aufruf ermoeglichen
      
$selbst __CLASS__ ;
      
$child = @ new $selbst  ;
      return 
$child->is_file($pfad);
    }
    
$fh $this->stream_open($pfad,'r',0,$openpath);
    if (
FALSE === $fh)
    {
      return 
FALSE;
    }else
    {
      
$this->stream_close($fh);
      return 
TRUE;
    }
  }
  
  function 
file_exists($pfad)  // public auch static
  
{
    if (!isset(
$this))
    { 
// statischen Aufruf ermoeglichen
      
$selbst __CLASS__ ;
      
$child = @ new $selbst  ;
      return 
$child->file_exists($pfad);
    }
    return(
$this->is_dir($pfad) || $this->is_file($pfad));
  }
  
  function 
filesize($pfad)  // public auch static
  
{
    if (!isset(
$this))
    { 
// statischen Aufruf ermoeglichen
      
$selbst __CLASS__ ;
      
$child = @ new $selbst  ;
      return 
$child->filesize($pfad);
    }
    
$fh $this->stream_open($pfad,'r',0,$openpath);
    if (
FALSE === $fh)
    {
      return 
FALSE;
    }else
    {
      
$size strlen($this->content);
      
$this->stream_close($fh);
      return 
$size;
    }
  }
  
  function 
mkdir($pfad,$mode=0,$options=)  // public
  
{
    if (!isset(
$this))
    { 
// statischen Aufruf ermoeglichen
      
$selbst __CLASS__ ;
      
$child = @ new $selbst  ;
      return 
$child->mkdir($pfad);
    }
    
$this->zerlege_path($pfad);
    if (
count($this->locator)!== 8) return FALSE;
    if (
FALSE  === $this->locator) return FALSE;
    if (
FALSE  === $this->dbconnect()) return FALSE;
    
$sql  "CREATE TABLE `{$this->locator['tabelle']}` (";
    
$sql .= "`{$this->locator['idspalte']}` VARCHAR( 255 ) NOT NULL ,";
    
$sql .= "`{$this->locator['codespalte']}` TEXT NOT NULL ,";
    
$sql .= "PRIMARY KEY ( `{$this->locator['idspalte']}` ) )";
    
$res mysql_query($sql,$this->db_hdl);
    if (
FALSE === $res) return FALSE;
    return 
TRUE;
  }
  
  function 
rmdir($pfad,$options=0)  // public
  
{
    if (!isset(
$this))
    { 
// statischen Aufruf ermoeglichen
      
$selbst __CLASS__ ;
      
$child = @ new $selbst  ;
      return 
$child->rmdir($pfad);
    }
    
$this->clear_cache();
    
$this->zerlege_path($pfad);
    if (
count($this->locator)!== 6) return FALSE;
    if (
FALSE  === $this->locator) return FALSE;
    if (
FALSE  === $this->dbconnect()) return FALSE;
    
$sql  "DROP TABLE `{$this->locator['tabelle']}` ";
    
$res mysql_query($sql,$this->db_hdl);
    if (
FALSE === $res) return FALSE;
    return 
TRUE;
  }
  
  function 
rename($quellpfad,$zielpfad)  // public auch static
  
{
    if (!isset(
$this))
    { 
// statischen Aufruf ermoeglichen
      
$selbst __CLASS__ ;
      
$child = @ new $selbst  ;
      return 
$child->rename($quellpfad,$zielpfad);
    }
     
    
$this->zerlege_path($quellpfad);
    
$quelle $this->locator;
    if (
count($quelle)!== 9) return FALSE;
    
    
$this->zerlege_path($zielpfad);
    
$ziel $this->locator;
    if (
count($ziel)!== 9) return FALSE;
    
    foreach(
$ziel as $key => $value)
    {  
// darf sich nur im letzten Eintrag unterscheiden
      
if('id' === $key) continue;
      if (
$value !== $quelle[$key]) return FALSE;
    }

    if (
FALSE  === $this->dbconnect()) return FALSE;
 
    if(
defined('MYSQLWRAPPER_CACHE_DIR'))
    {
        
$cachefile MYSQLWRAPPER_CACHE_DIR.'/'.md5($quellpfad);
        if (
file_exists($cachefile)) unlink($cachefile);
    }
    
$sql  "UPDATE `{$this->locator['tabelle']}` SET ";
    
$sql .= " `{$this->locator['idspalte']}`='{$ziel['id']}' ";
    
$sql .= " WHERE `{$this->locator['idspalte']}`='{$quelle['id']}' ";
    
$res mysql_query($sql,$this->db_hdl);
    if (
FALSE === $res) return FALSE;
    if (
mysql_affected_rows ($this->db_hdl) > 0) return TRUE;
    return 
FALSE;
  }
  
  function 
url_stat($pfad)  // public  
   
{
    
$flag  $this->dir_opendir($pfad,0);
    
$dummy ''// never used
    
$flag  $this->stream_open($pfad,'r',0,$dummy);
    if (
FALSE !== $flag)  
    {
      
$size strlen($this->content);
      
$this->stream_close();
      return 
$this->get_dummy_stat('file',$size);
    }  
    
    if (
FALSE !== $flag)  
    {
      
$this->dir_closedir();
      return 
$this->get_dummy_stat('dir');
    }  
    return 
FALSE
   }


/* ------------------------------------------------------- 

 OpenDir Funktionen

*/   
  
function  dir_opendir($pfad,$options )
  {
    
$this->zerlege_path($pfad);
    if (
count($this->locator) < 7) return FALSE;
    if (
FALSE  === $this->locator) return FALSE;
    if (
FALSE  === $this->dbconnect()) return FALSE;
    
$sql "SELECT `{$this->locator['idspalte']}` as `id` ";
    
$sql .= "FROM `{$this->locator['tabelle']}`";
    
$res mysql_query($sql,$this->db_hdl);
    if (
FALSE === $res) return FALSE;
    while(
$row mysql_fetch_array($res)) $this->dir[] = $row['id'];
    return 
TRUE;
  }


  function  
dir_readdir()
  {
    if (
$this->dirptr >= count($this->dir)) return FALSE;
    return  
$this->dir[$this->dirptr++];
  }

  function 
dir_rewinddir()
  {
    
$this->dirptr 0;
    return 
TRUE;
  }
  
  function 
dir_closedir()
  {
    return 
TRUE;
  }


/* ------------------------------------------------------- 

 User & Kontroll Funktionen

*/   
   
function register() // public static
   
{
    
$ok stream_wrapper_register("mysql"__CLASS__);
    if(!
$ok)  trigger_error('Failed to register "mysql://" protocol',E_USER_ERROR);
   }
   
   function 
file_put_contents($filename,$mixed// public static
   
{
      
$fh fopen($filename,"wb");
      if(
FALSE === $fh) return FALSE;
      if (
is_array($mixed))
      {
        
$bytes fwrite($fh,join(''$mixed));
      }else
      {
        
$bytes fwrite($fh,$mixed);
      }
      
fclose($fh);
      return 
$bytes;
   }

  function 
clear_cache() // public static
  
{
    if(
defined('MYSQLWRAPPER_CACHE_DIR'))
    {
      
$files glob(MYSQLWRAPPER_CACHE_DIR.'/*');
      foreach(
$files as $fileunlink($file);
    }
 
  }
  
  
/* ------------------------------------------------------- 

 Helper Funktionen

*/   
  
function zerlege_path($path// private
  
{
       
$felder = array('datenbank','tabelle','idspalte','codespalte','id'); 
       
$this->locator parse_url($path);
       
// if (count($this->locator)!== 5) return FALSE;
       
$dbpath trim($this->locator['path'],'/');
       unset(
$this->locator['path']);
       
$zerlegtes explode('/',$dbpath);
       for (
$i=0;$i<count($zerlegtes);$i++) 
       {
          
$this->locator[$felder[$i]] = $zerlegtes[$i];
       }   
       
// if (count($zerlegtes)!== 5) return FALSE;
       
return ; 
  }  
  

  function 
read_from_cache() // private
  
{
    if(
FALSE !== $this->cachefile)
    {
      if(
file_exists($this->cachefile))
      {
          
$this->content file_get_contents($this->cachefile);
          return 
TRUE;
      }
    }  
    return 
FALSE;
  }
  
  function 
get_dummy_stat($art,$size=0)
  {
  
      
$result = Array (,,  0,  0,  ,
                  
time(),  time() , time(),  -, -1   );
    switch(
$art)
    {
      case 
'dir'  
                    
$result[2] = 16895;
                    break;
      case 
'file' 
                    
$result[2] = 33206;
                    
$result[7] = $size;
                    break;
      default : return 
FALSE;
    }
    
$result['dev'] = $result[0];                 
    
$result['ino'] = $result[1];                 
    
$result['mode'] = $result[2];                 
    
$result['nlink'] = $result[3];                 
    
$result['uid'] = $result[4];                 
    
$result['gid'] = $result[5];                 
    
$result['rdev'] = $result[6];                 
    
$result['size'] = $result[7];                 
    
$result['atime'] = $result[8];                 
    
$result['mtime'] = $result[9];                 
    
$result['ctime'] = $result[10];                 
    
$result['blksize'] = $result[11];                 
    
$result['blocks'] = $result[12];                 
    return  
$result
  }
  
  
  function 
write_to_cache() // private
  
{
    if(
FALSE !== $this->cachefile)
    {
      
$fh fopen($this->cachefile,'wb');
      
fwrite($fh,$this->content);
      
fclose($fh);
    }
  }


  function 
read_from_db() // private
  
{
    
$this->dbconnect();
    if (
FALSE === $this->db_hdl) return FALSE;
    
$sql  "SELECT `{$this->locator['codespalte']}` ";
    
$sql .= " FROM `{$this->locator['tabelle']}` ";
    
$sql .= " WHERE {$this->locator['idspalte']}='{$this->locator['id']}'";
    
$res mysql_query($sql,$this->db_hdl);
    if (
mysql_num_rows($res) > 0)
    {
      
$row mysql_fetch_array($res);
      
$this->content $row[$this->locator['codespalte']];
      return 
TRUE;
    }
    return 
FALSE;
  }

   
   function 
dbconnect() // private
   
{
    if(
FALSE === $this->db_hdl)
    {
      
$this->db_hdl mysql_connect($this->locator['host'],$this->locator['user'],$this->locator['pass']);
//      if (FALSE === $this->db_hdl) trigger_error(mysql_error($this->db_hdl),E_USER_ERROR);
      
$hdl mysql_select_db($this->locator['datenbank'],$this->db_hdl);
//      if (FALSE === $hdl) trigger_error(mysql_error($this->db_hdl),E_USER_ERROR);
    
}  
    return 
$this->db_hdl;
   }
   
   function 
has_flag($flag// private
   
{
       return (
FALSE === strpos($this->params['mode'],$flag)?FALSE:TRUE);
   }

}


// ............. Schnipp .....................
// dieser Bereich inclusive schipp und schnapp sollte 
// fuer den produktiv Einsatz entfernt werden
// er dient nur zu publizierung dieser Datei

if (basename(__FILE__) === basename($_SERVER['PHP_SELF']))
{
  if(isset(
$_GET['action']) && 'download' === $_GET['action'])
  {
      
header("Content-type: application/x-applikation");
      
readfile(__FILE__);
      exit;
  }else
  { 
    
?> 
    <a href="<?php echo $_SERVER['PHP_SELF']; ?>?action=download">Download</a>
    <hr>
    <?php
    highlight_file
(__FILE__); 
  }    
}
// ............. Schnapp .....................


?>