Модераторы: skyboy, MoLeX, Aliance, ksnk

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Класс работы с текстовым файлом. Создание функции распреденного управлени 
:(
    Опции темы
Zmiuko
  Дата 23.3.2009, 11:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


http://zmiuko.ru
**


Профиль
Группа: Участник
Сообщений: 297
Регистрация: 8.10.2008

Репутация: 2
Всего: 2



Ребят, пишу php-скрипт работы с текстовым файлом. Бд, зараза такая, не используют, поэтому приходится мучатся.

Написал класс работы с текстовым файлом (своеобразной базы данных основанной на ассоциативных массивах) выборки, сохранения и удаления.
Код

class txtBD
 {

    var $path;
    var $fp;
    var $db;
    var $base64 = false;
    
    function txtBD($path="",$base64=FALSE) {$this->load($path,$base64);}
 
    function reload() {$this->load($this->path,$this->base64);}
 
    function openstream($path)
    {
        $this->closestream();
        if (!is_readable($path))
            {
                $this->lock();
                $a = @fopen($path,"w");
                @fclose($a);
                $this->unlock();
            }
            if (!is_readable($path)) {return false;}
            else
                {
                    if (basename($path) == ".sdb") {return false;}
                    else
                {
                    $this->lock();
                    $this->fp = @fopen($path,"r+");
                    return true;
                }
            }
    }
 
    function countdata()
    {
        if (is_readable($this->path))
            {
            clearstatcache();
            $this->count = filesize($this->path);
            }
    return $this->count;
    }
 
    function lock()
    {
        if (is_resource($this->fp))
            {
            flock($this->fp,LOCK_SH);
            flock($this->fp,LOCK_EX);
            }
    }
 
    function unlock()
    {
        if (is_resource($this->fp)) {flock($this->fp,LOCK_UN);}
    }
 
    function closestream()
    {
        if (is_resource($this->fp)) {fclose($this->fp);}
    return true;
    }
 
    function load($path,$base64=FALSE)
    {
        $this->path = $path;
        if (empty($base64)) {$base64 = $this->base64;}
        else {$this->base64 = $base64;}
        if ($this->openstream($path))
        {
            $data = @fread($this->fp,filesize($path));
            if ($this->base64) {$data = base64_decode($data);}
#        $this->db = unserialize($data);
            if($this->countdata()>0){$this->db = unserialize($data);}
        return true;
        }
        else {return false;}
    }
    
    function loaddata($data)
    {
        if ($this->base64) {$data = base64_decode($data);}
        $this->db = unserialize($data);
    }
 
    function flush($path="")
    {
        if (empty($path)) {$path = $this->path;}
        if (!is_resource($this->fp)) {$this->openstream($path); return true;}
        else
        {
            $data = serialize($this->db);
            if ($this->base64) {$data = base64_encode($data);}
            fseek($this->fp,0);
            fwrite($this->fp,$data);
            ftruncate($this->fp,strlen($data));
            return $this->fp;
        }
    }
 
    function unload()
    {
        unset($this->db);
        $this->closestream();
        return true;
    }
 
    function delete($path="")
    {
        if (empty($path)) {$path = $this->path;}
        unlink($path);
    }
 


Пардон за читабельность..

Реализуется примерно так:

Код

$class = new txtBD('файл');

 if(count($class->db)>0) {
            array_unshift($class->db, $arrbase);
        } else {
            $class->db = array('0' => $arrbase);
        }
        $class->flush();
        
        ну и не сложно само удаление -> $class->delete('тута_если_че_нада');


Файл содержит данные вида:

Код

$arrbase = array(
array("данные #1","данные #1","данные #1","0"),
array("данные #2","данные #2","данные #2","1"),
array("данные #3","данные #3","данные #3","0"),
array("данные #4","данные #4","данные #4","1"),
array("данные #5","данные #5","данные #5","2"),
array("данные #6","данные #6","данные #6","0"),
array("данные #7","данные #7","данные #7","1"),
array("данные #8","данные #8","данные #8","1"),
array("данные #9","данные #9","данные #9","2"),
array("данные #10","данные #10","данные #10","2"),
array("данные #11","данные #11","данные #11","0")
);


ПРОБЛЕМА В СЛЕДУЮЩЕМ:

Допустим мы имеем массив в 1 000 000 строк с копейками. Из опыта следует, что такое количество строк из файла прочесть нереально (допустим он несколько сотен мегабайт)! И тогда в голову приходит идея деления базы по нескольким файлам. Допустим по мере заполнения базы мы склыдываем в файл до 1000 строк (я имею ввыду массив значений Данных Номер X) и если их более тысячи, то создаем файл_номер_(+1) то есть новый и пихаем в него также до 1000 и так далее... то есть создаем... создаем... создаем.
Но тут же возникает вопрос, как при выборке, чтении, редактировании подгружать эту базу.

Пример: у нас 1023 строки... или 3457 строк (массивов вида "array("данные #x","данные #x","данные #x","0")," ) не важно сколько может и 523... Но мы превысили лимит сохранения в файл. И получается что из 1027 массивов, 1000 хранится в файле BASE_0, а 27 из них хранятся уже в файле  BASE_1 и т.д.. Понятно, думаю.
И возникается проблема - допустим мы вымещает данные по 5 на страницу - и получается что мы дерем из первого файла 25 сообщений на первые пять страниц, затем подключаем еще один файл BASE_1 и на 6-ую страницу вымещаем 2-ве оставшихся + 3 из новой базы и далее до конца вымещаем остальные по 5 на страницу соответственно. То же самое и в случае когда 3567 сообщений и 5789... неважно. К примеру говорю.

Так вот как реализовать функцию подключения и распределения такой базы, а также редактирования. Так скажем усовершенствовать мой класс. Да еще чтобы он адекватно и не ресурсоемко работал при запросах вида function ВЫДРАТЬ ИЗ БАЗЫ ДАННЫХ В МАССИВ ДАННЫЕ (с такого-то, по такое-то), если к примеру мы листаем страницы.

Почему сложно? Да потому что я собираюсь перемещать Данные вверх-вних следующей функцией

Код

function move($arr_line, $line, $up = false)
{
    if($line < 0 || $line > count($arr_line)-1)
        return $arr_line;
    $mode = $arr_line[$line][3];
    $move = $up ? -1 : 1;
    if($mode) return $arr_line;
    $c_line = $line;
    do
    {
        $m = $arr_line[$c_line][3];
        $c_line += $move;
        if($c_line < 0 && $up) $c_line = count($arr_line) - 1;
        if($c_line > count($arr_line) - 1 && !$up) $c_line = 0;
        
        //if($m && (($c_line == count($arr_line)-1 && !$up) || ($c_line < 0 && $up))) return $arr_line;
    }while($arr_line[$c_line][3]);
    $tmp = $arr_line[$c_line];
    $arr_line[$c_line] = $arr_line[$line];
    $arr_line[$line] = $tmp;
    return $arr_line;
}


Которая из массива:

Код

$arrbase = array(
array("данные #1","данные #1","данные #1","0"),
array("данные #2","данные #2","данные #2","1"),
array("данные #3","данные #3","данные #3","0"),
array("данные #4","данные #4","данные #4","1"),
array("данные #5","данные #5","данные #5","1"),
array("данные #6","данные #6","данные #6","0")
);


Создает массив данных при поднятии 1-ого сообщения:

Код

$arrbase = array(
array("данные #6","данные #6","данные #6","0"),
array("данные #2","данные #2","данные #2","1"),
array("данные #3","данные #3","данные #3","0"),
array("данные #4","данные #4","данные #4","1"),
array("данные #5","данные #5","данные #5","1"),
array("данные #1","данные #1","данные #1","0")
);




Помогите реализовать данную идею.
PM MAIL WWW ICQ Skype Jabber   Вверх
awers
Дата 23.3.2009, 11:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1465
Регистрация: 22.3.2006
Где: Россия, Таганрог

Репутация: 21
Всего: 31



sqlite не пробовал?
PM MAIL WWW ICQ Skype   Вверх
Zmiuko
  Дата 23.3.2009, 11:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


http://zmiuko.ru
**


Профиль
Группа: Участник
Сообщений: 297
Регистрация: 8.10.2008

Репутация: 2
Всего: 2



Цитата

awers, sqlite не пробовал?


Дело в том,что мне даны ограниченные возможности, надо именно использовать текстовые файлы. У начальства свои тараканы. :(

Забыл сказать, что необходима реализация под php4 и php5? что создает ряд проблем и крайних неудобств.
PM MAIL WWW ICQ Skype Jabber   Вверх
awers
Дата 23.3.2009, 11:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1465
Регистрация: 22.3.2006
Где: Россия, Таганрог

Репутация: 21
Всего: 31



Zmiuko, глядел на phpclasses.org? Такие вещи не стоит делать в рамках "горячего" проекта. Максимум когда скучно
PM MAIL WWW ICQ Skype   Вверх
Zmiuko
Дата 23.3.2009, 11:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


http://zmiuko.ru
**


Профиль
Группа: Участник
Сообщений: 297
Регистрация: 8.10.2008

Репутация: 2
Всего: 2



Да уж прекрасно понимаю, только уж очень важно...

Что касается phpclasses.org, смотрел уже... Только буржуйский не очень понимаю :( (не нашел ничего решающего подобное)
PM MAIL WWW ICQ Skype Jabber   Вверх
awers
Дата 23.3.2009, 11:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1465
Регистрация: 22.3.2006
Где: Россия, Таганрог

Репутация: 21
Всего: 31



Zmiuko, решений валом. translate.google.com в помощь
PM MAIL WWW ICQ Skype   Вверх
Zmiuko
  Дата 23.3.2009, 12:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


http://zmiuko.ru
**


Профиль
Группа: Участник
Сообщений: 297
Регистрация: 8.10.2008

Репутация: 2
Всего: 2



Там нет подобной реализации, увы.

Я так понимаю сначала необходимо подключить класс dir пыхыпышный и пройтись по папке с файлами в поисках на соответствие паттерну (проблема включить паттерн в класс обработки).

Если не находим, то создаем. В принципе само обращение $class->textBD($file) уже создает файл..

Так а вот если файлов уже пять - 1000*4, 4000 массивов и последний обновленный - 213 массивов, к примеру, а нам надо выборку произвести с 3978 по 4018 массив, естественно в $class->db, который формирует массив выбранных данных, то как хотябы это будет выглядеть?...

Или к примеру мы перемещаем по массиву выборки 4001 данные на место 3999 то есть идет перезапись массива из одного файла в другой, то тут уже еще сложнее.. как здесь?

Или удаляем строку 2999, и тогда последующие два файла, один в 1000 и другой как к примеру указано в 213, должны перезаписаться - таким образом - из 3 файла удалили строку (т.е. массив), перезаписали ключи, переходим к третьему в 1000 там удалили последний и дописали на место первого последний массив из пятого файла в 213 массивов, также перезаписали ключи, прошлись по ним... а если файлов не 5, а десять... тут конечно берется во внимание уже складирования в архив, допустим не превышать базу по 1000 сообщений в 5-ти файлах.. а то если база в 100*1000 - то забьем оперативку и повешаем апач, тут уже ни один сервер не справится...

Или есть какое предложения, просто я все думаю насчет складирования большого количества информации...
PM MAIL WWW ICQ Skype Jabber   Вверх
ksnk
Дата 23.3.2009, 12:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прохожий
****


Профиль
Группа: Комодератор
Сообщений: 6855
Регистрация: 13.4.2007
Где: СПб

Репутация: 96
Всего: 386



Вот обсуждение проекта. SQL там, конечно, не вписался, но большие объемы данных этот двигл, вроде, умеет ворочать достаточно быстро.


--------------------
Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! user posted image
PM MAIL WWW Skype   Вверх
Zmiuko
  Дата 23.3.2009, 12:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


http://zmiuko.ru
**


Профиль
Группа: Участник
Сообщений: 297
Регистрация: 8.10.2008

Репутация: 2
Всего: 2



Не знаю, только если решить проблему таким образом, что для каждого массива данных создавать отдельный файл? Хотя идея!... но вот класс не могу продумать..

Получается что создается в папке файл с указанием ссылок на файлы с сохраненными данными... Или просто также по паттерну ищем файлы соответствующие.

Получается что массив данных $arrbase соответствуем базе типа:

Код

файл arrbase_0:

ассоциативный массив: array("данные #0","данные #0","данные #0","0"),


Код

файл arrbase_1:

ассоциативный массив: array("данные #1","данные #1","данные #1","1"),


Код

файл arrbase_2:

ассоциативный массив: array("данные #2","данные #2","данные #2","0"),


Код

файл arrbase_3:

ассоциативный массив: array("данные #3","данные #3","данные #0","0"),


Код

файл arrbase_4:

ассоциативный массив: array("данные #4","данные #4","данные #4","0"),


...и т.д. до "победного"...

Задача конечно упрощается - не надо придумывать сложностей излишних... 

Помогите собрать класс работы с такими "какашками".

Добавлено через 4 минуты и 55 секунд
ksnk, благодарю конечно, только тоже незадача, что плохо понимаю синтаксис Бд.. уж простите за молодое невежество, мне бы попроще как-нибудь реализовать, поскольку проект не слишком наворочен.

Добавлено через 8 минут и 36 секунд
Достал я вас, наверное, со своими ненормальными идеями smile
PM MAIL WWW ICQ Skype Jabber   Вверх
MoLeX
Дата 23.3.2009, 12:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Местный пингвин
****


Профиль
Группа: Модератор
Сообщений: 4076
Регистрация: 17.5.2007

Репутация: 46
Всего: 140



 smile 

Цитата(Zmiuko @  23.3.2009,  11:38 Найти цитируемый пост)
У начальства свои тараканы. :(

если есть техническая возможность работы с СУБД то стоит объяснить начальству что это такое и почему именно на них это надо делать.



--------------------
Amazing  smile 
PM MAIL WWW ICQ   Вверх
ksnk
Дата 23.3.2009, 12:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прохожий
****


Профиль
Группа: Комодератор
Сообщений: 6855
Регистрация: 13.4.2007
Где: СПб

Репутация: 96
Всего: 386



Zmiuko, По моей ссылке есть 2 проекта ff - с поддержкой усеченного SQL, но с большими файлами работать не умеет, и YNDb - работает со своим языком запросов, может быстро есть большие файлы - выложено в последних постах темы.

Если в проекте речь идет о 1 000 000 строк базы, то никакие отговорки о "не слишком навороченном проекте" и "невежестве" не прокатят smile Без приличной базы работать оно не будет...


--------------------
Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! user posted image
PM MAIL WWW Skype   Вверх
IZ@TOP
Дата 23.3.2009, 12:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Панда-бир!
****


Профиль
Группа: Участник
Сообщений: 4795
Регистрация: 3.2.2003
Где: Бамбуковый лес

Репутация: 44
Всего: 73



Добавлю еще к тому, что сказал MoLeX: практически в любой комплект виртуального хостинга входит модуль sqlite. Не вижу смысла разрабатывать свое двигло базы данных на PHP, в то время, когда доступны простейшие решения, за которые не нужно платить огромных денег. Впрочем, интересно было бы узнать, какие именно аргументы у Вашего руководства за файлы и в противовес СУБД.


--------------------
Один из розовых плюшевых-всадников апокалипсиса... очень злой...

Семь кругов ада для новых элементов языка
Мои разрозненные мысли
PM MAIL WWW ICQ Skype GTalk   Вверх
Zmiuko
Дата 23.3.2009, 12:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


http://zmiuko.ru
**


Профиль
Группа: Участник
Сообщений: 297
Регистрация: 8.10.2008

Репутация: 2
Всего: 2



Да много не надо, просто необходима функция, как уже разрешил проблему, которая бы доставала в массив содержимое файлов допустим от указанного числа записи, до указанного... и соответственно также и сохраняла, и удаляла полностью базу... )

К примеру: у нас 8 записей вида array("данные #номер","данные #номер","данные #номер","0"),, которые лежат в 8-ми файлах...

мы дергаем в массив $array от 1 к примеру до 6 и получаем:

Код

$array = array(
array("данные #6","данные #6","данные #6","0"),
array("данные #2","данные #2","данные #2","1"),
array("данные #3","данные #3","данные #3","0"),
array("данные #4","данные #4","данные #4","1"),
array("данные #5","данные #5","данные #5","1"),
array("данные #1","данные #1","данные #1","0")
);


Удаляем допустим 5-ую запись, или редактируем 4-ую, или меняем местами с 3-й по 2-ю... и получаем:

Код

$array = array(
array("данные #6","данные #6","данные #6","0"),
array("данные #2","данные #2","данные #2","1"),
array("данные #3","данные #3","данные #3","0"),
array("данные #4","данные #4","данные #4","1"), // допустим удалили пятую
array("данные #1","данные #1","данные #1","0")
);


и нам надо сохранить этот массив опять же в файлы, с пробегом по именам BASE_номер, для изменения ключа, то есть номера соответствующего ключу массива.

ух, господи... выходит зазря расписываю.

Добавлено через 1 минуту и 16 секунд
Цитата

Добавлю еще к тому, что сказал MoLeX: практически в любой комплект виртуального хостинга входит модуль sqlite. Не вижу смысла разрабатывать свое двигло базы данных на PHP, в то время, когда доступны простейшие решения, за которые не нужно платить огромных денег. Впрочем, интересно было бы узнать, какие именно аргументы у Вашего руководства за файлы и в противовес СУБД. 


Пожимаю в ответ плечами.

Добавлено через 2 минуты и 55 секунд
Просто сам проект ориентирован на мало количество пользователей, СУБД подключать не имеет смысла, наверно. Тем не менее мне поставлена задача, которую необходимо решить.

Добавлено через 12 минут и 29 секунд
Так думаю, что необходимо все же использовать дополнительный файл ссылок к используемым файлам, дабы не перебирать лишний раз имена самих файлов и не тратить ресурсы на их переименование согласно ключам.

Получается что такой файл будет вида:

Код

//содержимое файла ссылок
$array = array(
array("допустим время создания сообщение, оно же имя файла содержащего соответствующий массив"),
array("1782647800"),
array("1782647758"),
array("1782647743"),
array("1782647621"),
array("1782647177")
);

далее файлы:

файл 1782647800.bd с содержимым array("данные #4","данные #4","данные #4","0") ;
файл 1782647758.bd с содержимым array("данные #3","данные #3","данные #3","1") ;
и т.д.


Поможите реализовать функция которая дерет массив данных от указанного ключа массива к указанному на основе моего класса?
PM MAIL WWW ICQ Skype Jabber   Вверх
Zmiuko
  Дата 23.3.2009, 13:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


http://zmiuko.ru
**


Профиль
Группа: Участник
Сообщений: 297
Регистрация: 8.10.2008

Репутация: 2
Всего: 2



Правильна ли будет функция выборки:

Код

function base($data, $arg1, $arg2) {
      $class1 = new textDB($data);
      if($arg>0 and $arg1<$arg2 and $arg2=<count($class1->db)) {
           for($i=$arg1; $i<$arg2; $i) {
                    $class2[$i] = new textBD($data.$class1->db['0'].'.bd);
                    $result[$i] = $class2[$i]->db;
                 }
           return $result;
           }
}


Добавлено через 53 секунды
Согласно тому что я описал выше верна ли, а то сомневаюсь, в данный момент не могу проверить...
PM MAIL WWW ICQ Skype Jabber   Вверх
awers
Дата 23.3.2009, 14:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1465
Регистрация: 22.3.2006
Где: Россия, Таганрог

Репутация: 21
Всего: 31



Цитата(Zmiuko @  23.3.2009,  14:54 Найти цитируемый пост)
Согласно тому что я описал выше верна ли, а то сомневаюсь, в данный момент не могу проверить...

замечательный вопрос. smile 

Дебагером на пол ставки вместо Zend debuger берёшь?
PM MAIL WWW ICQ Skype   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "PHP"
Aliance
IZ@TOP
skyboy
SamDark
MoLeX

Новичкам:

  • PHP редакторы собираются и обсуждаются здесь
  • Электронные книги по PHP, документацию можно найти здесь
  • Интерпретатор PHP, полную документацию можно скачать на PHP.NET

Важно:

  • Не брезгуйте пользоваться тегами [code=php]КОД[/code] для повышения читабельности текста/кода.
  • Перед созданием новой темы воспользуйтесь поиском и загляните в FAQ
  • Действия модераторов можно обсудить здесь

Внимание:

  • Темы "ищу скрипт", "подскажите скрипт" и т.п. будут переноситься в форум "Web-технологии"
  • Темы с именами: "Срочно", "помогите", "не знаю как делать" будут УДАЛЯТЬСЯ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, IZ@TOP, skyboy, SamDark, MoLeX, awers.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0670 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.