Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [PHP]Multifile, biblioteka do obslugi plikowej bazy danych
-młody skryptadept-
post
Post #1





Goście







Witajcie.
Ma poczatku chcialem sie przedstawic, jestem mlodym programista php, moje dosiadczenie nie jest dluzsze niz 1 rok.
Napisalem biblioteke do obslugi plikowej bazy danych,
sam stosuje jej zamiast sqla (IMG:http://forum.php.pl/style_emoticons/default/tongue.gif)
ale moze ona tez posluzyc 'normalnym' jaki jej substytut.
Np. kiedy musimy magazynowac duzo malych obrazkow.


oto przyklad uzycia bazy:
  1. <?php
  2. require_once('multifile.php');
  3. $db->debug = false;
  4. $db = new multifile;
  5. $db->dbpath = './example/';
  6. # Dokumentacja szalenie prosta, bo i prosta jest obsluga tego lib'a
  7. # Mamy do dyspozycji 5 metod:
  8.  
  9. //foreach ( glob('ZDJECIA_Z_REJSU/*') as $file) {
  10. //    $data = array($file, file_get_contents($file));
  11. //    $db->put($data);
  12. //}
  13. //exit;
  14.  
  15. # put()
  16.    $data = array('klucz', 'string'); # stringi
  17.    $data = array('klucz', array('tablica')); # tablice
  18.    $data = array('klucz', file_get_contents('zdjecie.jpg')); # dane binarne
  19.    $db->put($data);
  20.  
  21. # get()
  22.    $data = $db->get('klucz');
  23.  
  24. # delete()
  25.    $wynik = $db->delete('klucz');
  26.  
  27. # exists()
  28.    if ( true === $db->exists('klucz'));
  29.        echo 'Klucz istnieje';
  30.  
  31. # search()
  32.    $wynik = $db->search("^klucz$"); // wyrazena regularne
  33.    
  34. # get_list()
  35.    $pelna_lista_recordow = $db->get_list();
  36.  
  37. # count
  38.    $ilosc_recordow = $db->count();
  39.  
  40. ?>


A to właściwa biblioteka:

[/php]
<?php
/*
CHANGELOG
# v.1.0



*/
/*

ToDo:
# Co szybsze, array_key_exists czy issset (IMG:http://forum.php.pl/style_emoticons/default/questionmark.gif) ?

Functionlist:
get()
delete()
exists() // exists powinno uzywac searcha (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)
search()
count()
get_list()
update()
*/
class multifile {
/* # TODO
dzielenie duuuzych plikow na porcje
szukanie od najstarszego, od najmlodszego, losowo
*/
var $dbpath = '';
var $debug = false;

var $_update = '';


function update($key, $data) {
$this->_update = $data;
if ( true === $this->_seek($key, 'update'))
return true;
return false;
}

function put($enter) {
$time_start = $this->gmt();
$key = @current($enter) or die('Zapisywac mozna tylko tablice');
$enter = array_slice($enter, 1);
if ( true !== $this->exists($key))
return false;
$path = $this->_get_writable_file();
$data = @file_get_contents($path) or die('Can\'t read from file file.');
$data = unserialize($data);
$data[$key] = $enter;
file_put_contents($path, serialize($data));
if ( $this->debug !== false ) echo 'Czas wstawiania: '.($this->gmt() - $time_start).'<br />';
return true;
}

function _is_dir($path='') {
$path = empty($path) ? $this->dbpath : $path;
if ( ! is_dir($path))
@mkdir($path, '0777') or die('Blad odczytu/zapisu bazy danych.<br />');
return true;
}

function get($key, $how='') {
/* Zrobic random
$how =
'random'
'back'
*/
$time_start = $this->gmt();
$this->_is_dir();
$key = is_array($key) ? current($key) : $key;
if ( false !== $data = $this->_seek($key, 'get')) {
//$data = unserialize($data); ###
if ( $this->debug !== false ) echo 'Czas wyciagania: '.($this->gmt() - $time_start).'<br />';
return ( count($data) < 2 ) ? $data[0] : $data; // jesli tablica ma 1 element, to zwraca tylko string (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)
}
if ( $this->debug !== false ) echo 'Czas wyciagania - nieudany-: '.($this->gmt() - $time_start).'<br />';
return false;
}

function exists($key) {
$time_start = $this->gmt();
$this->_is_dir();
if ( true === $this->_seek($key, 'exists'))
return false;
return true;
}

function delete($key='') {
$time_start = $this->gmt();
$this->_is_dir();
if ( true === $this->_seek($key, 'delete'))
return true;
return false;
}

function count() {
$time_start = $this->gmt();
$this->_is_dir();
return; $this->_seek('', 'count');
}

function get_list($pattent='') {
$time_start = $this->gmt();
$this->_is_dir();
$list = $this->_seek('', 'list');
if ( $this->debug !== false ) echo 'Czas generowania listy: '.($this->gmt() - $time_start).'<br />';
return $list;
}

function search($pat='') {
$time_start = $this->gmt();
$finded = array();
foreach ( $this->_seek('', 'list') as $key ) {
if ( preg_match("#$pat#", $key))
array_push($finded, $key);
}
if ( $this->debug !== false ) echo 'Czas szukania: '.($this->gmt() - $time_start).'<br />';
return $finded;
}

function _seek($key='', $do) {
switch($do) {
case('count'):
$count = 0;
break;
case('list'):
$list = array();
break;
default:
if ( strlen($key) < 1)
return false;
}
foreach ( $this->_get_files_list() as $file ) {
$db_data = @file_get_contents($file) or die('Cam\'t read db file.');
$db_data = unserialize($db_data);
if ( $do == 'count') {
$coun += count($db_data);
continue;
}
if ( $do == 'list' ) {
$list = array_merge( $list, array_keys($db_data) );
continue;
}
if ( ! array_key_exists($key, $db_data))
continue;
switch($do) {
case('get'):
return $db_data[$key];
case('update'):
$db_data[$key] = $this->_update;
file_put_contents($file, serialize($db_data));
return true;
case('delete'):
unset($db_data[$key]);
file_put_contents($file, serialize($db_data));
return true;
case('exists'):
return true;
default:
die('Blad uzycia _seek()');
}
}
switch($do) {
case('count'):
return $count;
case('list'):
return $list;
default:
return false;
}
}

function _get_files_list() {
$time_start = $this->gmt();
$this->_is_dir();
return glob($this->dbpath.'*');
}

function _get_writable_file() {
$time_start = $this->gmt();
$this->_is_dir();
$filelist = glob($this->dbpath . '*');
foreach ( $filelist as $file ) {
if ( filesize($file) < $this->_get_memory_limit())
return $file;
}
sort($filelist);
$new_file_path = is_file(end($filelist)) ? preg_replace_callback( '#^(.*?/)([0-9]+)$#', create_function('$vars', 'return $vars[1].($vars[2] + 1);'), end($filelist)) : $this->dbpath.'0';
file_put_contents($new_file_path, serialize(array())) or die('Nie moge utworzyc pliku bazy danych');
//file_put_contents(is_file(end($filelist)) ? preg_replace_callback( '#^(.*?/)([0-9]+)$#', create_function('$v', 'return $v[1].($v[2] + 1);'), end($filelist)) : $this->dbpath.'0', serialize(array())) or die('Nie moge utworzyc pliku bazy danych');
return $new_file_path;
}

function _get_memory_limit() {
$time_start = $this->gmt();
return abs(intval(ini_get('memory_limit'))) * 1024 * 1024 * 0.3;
}

function gmt(){list($usec,$sec)=explode(' ',microtime());return ((float)$usec + (float)$sec);}
}?>
[/php]

Serdecznie prosze o gro uwag.
Co Wy na to, czy z takim stylem nadaje sie na etat? (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)
Go to the top of the page
+Quote Post
-Gość-
post
Post #2





Goście







Zle wkleila sie biboteka, oto ona jeszcze raz, tym razem z tabulatorami i bbcode:p

  1. <?php
  2.    /*
  3.         CHANGELOG
  4.         # v.1.0
  5.         
  6.     
  7.     
  8.     */
  9. /*
  10.  
  11. ToDo:
  12.     # Co szybsze, array_key_exists czy issset (IMG:http://forum.php.pl/style_emoticons/default/questionmark.gif) ?
  13.  
  14. Functionlist:
  15.     get()
  16.     delete()
  17.     exists() // exists powinno uzywac searcha :)
  18.     search()
  19.     count()
  20.     get_list()
  21.     update()
  22. */
  23. class multifile {
  24.    /* # TODO
  25.         dzielenie duuuzych plikow na porcje
  26.         szukanie od najstarszego, od najmlodszego, losowo
  27.     */
  28.    var $dbpath = '';
  29.    var $debug = false;
  30.    
  31.    var $_update = '';
  32.    
  33.    
  34.    function update($key, $data) {
  35.        $this->_update = $data;
  36.        if ( true === $this->_seek($key, 'update'))
  37.            return true;
  38.        return false;
  39.    }
  40.    
  41.    function put($enter) {
  42.        $time_start = $this->gmt();
  43.        $key = @current($enter) or die('Zapisywac mozna tylko tablice');
  44.        $enter = array_slice($enter, 1);
  45.        if ( true !== $this->exists($key))
  46.            return false;
  47.        $path = $this->_get_writable_file();
  48.        $data = @file_get_contents($path) or die('Can't read from file file.');
  49.        $data = unserialize($data);
  50.        $data[$key] = $enter;
  51.        file_put_contents($path, serialize($data));
  52.        if ( $this->debug !== false ) echo 'Czas wstawiania: '.($this->gmt() - $time_start).'<br />';
  53.        return true;
  54.    }
  55.    
  56.    function _is_dir($path='') {
  57.        $path = empty($path) ? $this->dbpath : $path;
  58.        if ( ! is_dir($path))
  59.            @mkdir($path, '0777') or die('Blad odczytu/zapisu bazy danych.<br />');
  60.        return true;
  61.    }
  62.    
  63.    function get($key, $how='') {
  64.        /* Zrobic random
  65.             $how =
  66.             'random'
  67.             'back'
  68.         */
  69.        $time_start = $this->gmt();
  70.        $this->_is_dir();
  71.        $key = is_array($key) ? current($key) : $key;
  72.        if ( false !== $data = $this->_seek($key, 'get')) {
  73.            //$data = unserialize($data); ###
  74.            if ( $this->debug !== false ) echo 'Czas wyciagania: '.($this->gmt() - $time_start).'<br />';
  75.            return ( count($data) < 2 ) ? $data[0] : $data; // jesli tablica ma 1 element, to zwraca tylko string :)
  76.        }
  77.        if ( $this->debug !== false ) echo 'Czas wyciagania - nieudany-: '.($this->gmt() - $time_start).'<br />';
  78.        return false;
  79.    }
  80.  
  81.    function exists($key) {
  82.        $time_start = $this->gmt();
  83.        $this->_is_dir();
  84.        if ( true === $this->_seek($key, 'exists'))
  85.            return false;
  86.        return true;
  87.    }
  88.    
  89.    function delete($key='') {
  90.        $time_start = $this->gmt();
  91.        $this->_is_dir();
  92.        if ( true === $this->_seek($key, 'delete'))
  93.            return true;
  94.        return false;
  95.    }
  96.    
  97.    function count() {
  98.        $time_start = $this->gmt();
  99.        $this->_is_dir();
  100.        return; $this->_seek('', 'count');
  101.    }
  102.    
  103.    function get_list($pattent='') {
  104.        $time_start = $this->gmt();
  105.        $this->_is_dir();
  106.        $list = $this->_seek('', 'list');
  107.        if ( $this->debug !== false ) echo 'Czas generowania listy: '.($this->gmt() - $time_start).'<br />';
  108.        return $list;
  109.    }
  110.    
  111.    function search($pat='') {
  112.        $time_start = $this->gmt();
  113.        $finded = array();
  114.        foreach ( $this->_seek('', 'list') as $key ) {
  115.            if ( preg_match("#$pat#", $key))
  116.                array_push($finded, $key);
  117.        }
  118.        if ( $this->debug !== false ) echo 'Czas szukania: '.($this->gmt() - $time_start).'<br />';
  119.        return $finded;
  120.    }
  121.    
  122.    function _seek($key='', $do) {
  123.        switch($do) {
  124.            case('count'):
  125.                $count = 0;
  126.                break;
  127.            case('list'):
  128.                $list = array();
  129.                break;
  130.            default:
  131.                if ( strlen($key) < 1)
  132.                    return false;
  133.        }
  134.        foreach ( $this->_get_files_list() as $file ) {
  135.            $db_data = @file_get_contents($file) or die('Cam't read db file.');
  136.            $db_data = unserialize($db_data);
  137.            if ( $do == 'count') {
  138.                $coun += count($db_data);
  139.                continue;
  140.            }
  141.            if ( $do == 'list' ) {
  142.                $list = array_merge( $list, array_keys($db_data) );
  143.                continue;
  144.            }
  145.            if ( ! array_key_exists($key, $db_data))
  146.                continue;
  147.            switch($do) {
  148.                case('get'):
  149.                    return $db_data[$key];
  150.                case('update'):
  151.                    $db_data[$key] = $this->_update;
  152.                    file_put_contents($file, serialize($db_data));
  153.                    return true;
  154.                case('delete'):
  155.                    unset($db_data[$key]);
  156.                    file_put_contents($file, serialize($db_data));
  157.                    return true;
  158.                case('exists'):
  159.                    return true;
  160.                default:
  161.                    die('Blad uzycia _seek()');
  162.            }
  163.        }
  164.        switch($do) {
  165.            case('count'):
  166.                return $count;
  167.            case('list'):
  168.                return $list;
  169.            default:
  170.                return false;
  171.        }
  172.    }
  173.  
  174.    function _get_files_list() {
  175.        $time_start = $this->gmt();
  176.        $this->_is_dir();
  177.        return glob($this->dbpath.'*');
  178.    }
  179.    
  180.    function _get_writable_file() {
  181.        $time_start = $this->gmt();
  182.        $this->_is_dir();
  183.        $filelist = glob($this->dbpath . '*');
  184.        foreach ( $filelist as $file ) {
  185.            if ( filesize($file) < $this->_get_memory_limit())
  186.                return $file;
  187.        }
  188.        sort($filelist);
  189.        $new_file_path = is_file(end($filelist)) ? preg_replace_callback( '#^(.*?/)([0-9]+)$#', create_function('$vars', 'return $vars[1].($vars[2] + 1);'), end($filelist)) : $this->dbpath.'0';
  190.        file_put_contents($new_file_path, serialize(array())) or die('Nie moge utworzyc pliku bazy danych');
  191.        //file_put_contents(is_file(end($filelist)) ? preg_replace_callback( '#^(.*?/)([0-9]+)$#', create_function('$v', 'return $v[1].($v[2] + 1);'), end($filelist)) : $this->dbpath.'0', serialize(array())) or die('Nie moge utworzyc pliku bazy danych');
  192.        return $new_file_path;
  193.    }
  194.    
  195.    function _get_memory_limit() {
  196.        $time_start = $this->gmt();
  197.        return abs(intval(ini_get('memory_limit'))) * 1024 * 1024 * 0.3;
  198.    }
  199.    
  200. function gmt(){list($usec,$sec)=explode(' ',microtime());return ((float)$usec + (float)$sec);}
  201. }?>
Go to the top of the page
+Quote Post
Pilsener
post
Post #3





Grupa: Zarejestrowani
Postów: 1 590
Pomógł: 185
Dołączył: 19.04.2006
Skąd: Gdańsk

Ostrzeżenie: (0%)
-----


Operujesz na tablicach - moim zdaniem powinieneś iść bardziej w stronę while + fgets, żeby parsować pliki linijka po linijce - w ten sposób można szybko "obrabiać" nawet pliki, które mają 10MB. Swojego czasu interesowałem się plikami i napisałem nawet tutka:
http://www.forumweb.pl/viewtopic.php?t=39103
Przetestuj swój kod na jakiejś bazie, powiedzmy z 10 tysięcy rekordów - tak trudno powiedzieć, czy jest wydajny, nie ma błędów itp. Zmierz szybkość, zużycie pamięci - wrzuć demo na jakiś darmowy host.
Go to the top of the page
+Quote Post
--gox--
post
Post #4





Goście







Taki kod jest znacznie wydajniejszy niz fgets.... znacznie, znaczenie wydajniejszy.
Dysk laduje po 100MB/s (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 24.12.2025 - 12:32