Написание функций чтения/записи в DBF-файл (как в модуле php_dbase.dll)

Miha-ingener

Новичок
Написание функций чтения/записи в DBF-файл (как в модуле php_dbase.dll)

Вот такой занимаюсь задачей - необходимо написать функции для чтения/записи/удаления/замены данных в DBF-файлах.

Есть в php стандартный модуль - php_dbase.dll он может следующее:

dbase_numrecords -- Find out how many records are in a dBase database
dbase_get_record_with_names -- Gets a record from a dBase database as an associative array
dbase_get_record -- Gets a record from a dBase database

dbase_add_record -- Add a record to a dBase database
dbase_replace_record -- Replace a record in a dBase database
dbase_delete_record -- Deletes a record from a dBase database
dbase_create -- Creates a dBase database
dbase_pack -- Packs a dBase database
dbase_open -- Opens a dBase database
dbase_close -- Close a dBase database
dbase_get_header_info -- Get the header info of a dBase database
dbase_numfields -- Find out how many fields are in a dBase database

Считать количество записей, считывать, записывать, заменять записи и т.д.

Проблема вот в чём - поддержка этого модуля невозможна на серверах с ОС FREEBSD. Поэтому мне хочется написать такие же функции, выполняющие тоже самое и подключать их на тех хостингах, где нет поддержки этого модуля.

Вот что уже получилось написать:

PHP:
// Функция, считывающая КОЛИЧЕСТВО записей в DBF-файле

function dbase_numrecords($dbfname) {
$fdbf=fopen($dbfname,'r');
$fields = array();
$buf = fread($fdbf,32);
$header=unpack("VRecordCount/vFirstRecord/vRecordLength", substr($buf,4,8));
print $header['RecordCount'];
fclose($fdbf); }

// Функция, считывающая СТРОКУ в виде массива из DBF-файла

function dbase_get_record($dbfname,$number) {
$fdbf=fopen($dbfname,'r');
$fields = array();
$buf = fread($fdbf,32);
$header=unpack( "VRecordCount/vFirstRecord/vRecordLength", substr($buf,4,8));
$goon = true;
$unpackString='';
while ($goon && !feof($fdbf)) { // read fields:
$buf = fread($fdbf,32);
if (substr($buf,0,1)==chr(13)) {$goon=false;} // end of field list
else {
$field=unpack( "a11fieldname/A1fieldtype/Voffset/Cfieldlen/Cfielddec", substr($buf,0,18));
$unpackString.="A$field[fieldlen]$field[fieldname]/";
array_push($fields, $field);}}
fseek($fdbf, $header['FirstRecord']+1); // move back to the start of the first record (after the field definitions)
for ($i=1; $i<=$header['RecordCount']; $i++) {
$buf = fread($fdbf,$header['RecordLength']);
$record=unpack($unpackString,$buf);
if ($i==$number) {$record=array_values($record); print"<pre>"; print_r($record);}
} //raw record
fclose($fdbf); }
Первые 3 из списка выше удалось реализовать - показываю две. Помогите, пожалуйста, написать и другие функции...
 

флоппик

promotor fidei
Команда форума
Партнер клуба
Первые 3 из списка выше удалось реализовать
Скажем прямо, первые три сперты из комментариев на пхп.нет буква в букву.
Врать то зачем? Вроде взрослые люди...
 

mity

Новичок
Уж не понятно зачем вам потребовался DBASE.
Открывайте исходники php-5.2.13/ext/dbase/, в ветки 5.3 он почему-то отсутствует.

И реализуйте все необходимые вам функции, ну или ищите в интернете, может кто то это уже реализовал на php.

Если вы будите одновременно работать с базой только одним скриптом или в режиме только чтение( или с редкими операциями записи), то производительность будет хорошая. Однако если вы будите работать в "многопользовательском" режиме с операциями записи, то производительность будет, как минимум, на порядок ниже нормальной СУБД.
 

dimagolov

Новичок
Miha-ingener, DBF файлы читаются тем же MS Access-ом или старыми версиями PHP ОДИН раз для импорта в нормальный формат. Потому писать что-то для работы сними просто глупо.
 

fixxxer

К.О.
Партнер клуба
>>поддержка этого модуля невозможна на серверах с ОС FREEBSD

админу засунуть кол в жопу за наглое вранье
 

Miha-ingener

Новичок
Автор оригинала: флоппик
Скажем прямо, первые три сперты из комментариев на пхп.нет буква в букву.
Врать то зачем? Вроде взрослые люди...
Взял готовый код, немного исправил. Сейчас идею понял, переделываю по-другому.


Как всё таки осуществить запись данных в dbf-файл чтобы не повредить структуру.
 

fixxxer

К.О.
Партнер клуба
Не страдать ерундой и установить ext/dbase.

-~{}~ 08.05.10 06:42:

все прекрасно собирается на freebsd/php 5.3 с минимальным патчем

http://pastie.org/951057

PHP:
~$ php -v
PHP 5.3.1 (cli) (built: Apr  2 2010 02:54:22)

~$ cd php-5.2.13/ext/dbase/
~/php-5.2.13/ext/dbase$ phpize && ./configure && make
.. ошибки про static
~/php-5.2.13/ext/dbase$ patch < dbase.c.diff
~/php-5.2.13/ext/dbase$ phpize && ./configure && make
   собралось
~/php-5.2.13/ext/dbase$ make test
Running selected tests.
PASS dbase_create() tests [tests/001.phpt] 
PASS dbase_open() tests [tests/002.phpt] 
PASS Bug #31754 (dbase_open() fails for mode = 1) [tests/bug31754.phpt] 
PASS Bug #46282 (Corrupt DBF When Using DATE) [tests/bug46282.phpt] 
PASS dbase_get_header_info() - Basic test [tests/dbase_get_header_info_001.phpt] 
PASS dbase_get_record_with_names() - Basic test [tests/dbase_get_record_with_names_001.phpt] 
PASS dbase_pack() - Basic test [tests/dbase_pack_001.phpt] 
=====================================================================
Number of tests :    7                 7
Tests skipped   :    0 (  0.0%) --------
Tests warned    :    0 (  0.0%) (  0.0%)
Tests failed    :    0 (  0.0%) (  0.0%)
Expected fail   :    0 (  0.0%) (  0.0%)
Tests passed    :    7 (100.0%) (100.0%)
---------------------------------------------------------------------
Time taken      :    1 seconds
 

01ssv

Новичок
Тема опять актуально в связи с выходом php7. Что делать?
 

флоппик

promotor fidei
Команда форума
Партнер клуба
Не обновлятся. Если уж нужно говно мамонта, то пусть оно будет консистентным.
 

01ssv

Новичок
Разрабочики расширения ответили, что у них нет времени на разработку, но вот патч они могут закоммитить. Сишный код смотрел - но там произошло существенное обновление zend_api и разобраться как правильно нужно поправить не смог. Остается найти доброго человека - который сделает патч.
 

fixxxer

К.О.
Партнер клуба
Добрые люди могут найтись в форуме "Работа". Сомневаюсь, что кто-то будет просто так тратить свое время на почти никому не нужный extension.
 

01ssv

Новичок
Extension нужен, т.к. происходит взаимодействие с внешними системами в этом формате, на своей стороне мы еще можем что то менять - но на другой стороне - не можем.
В итоге спасла связка dbfsak (внешним вызовом) и либа на самом php XBase.
 
Сверху