note 104956 deleted from book.dbase by danbrown
| From: | danbrown@php.net | Date: | Tue, 19 Jul 2011 15:52:45 +0000 |
| Subject: | note 104956 deleted from book.dbase by danbrown | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-181708@lists.php.net to get a copy of this message | ||
Note Submitter: dave at davidhbrown dot us
----
Thank you, Erich; that code was very helpful. I also needed to know whether a record had been marked
for deletion. This is indicated with an asterisk ("*") in the first byte of the record;
the data actually starts with the second byte of each record. See http://www.dbase.com/KnowledgeBase/int/db7_file_fmt.htm
(I suspect that your code may accidentally include the 0x1A that marks the end-of-file in the last
field of the last record.)
My database had some binary data in it, so I went with serialize() instead of json, but here's
an updated version that considers that marker:
<?php
function echo_dbf($dbfname) {
$fdbf = fopen($dbfname,'r');
$fields = array();
$buf = fread($fdbf,32);
$header=unpack( "VRecordCount/vFirstRecord/vRecordLength", substr($buf,4,8));
echo 'Header: '.serialize($header).PHP_EOL;
$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));
echo 'Field: '.serialize($field).PHP_EOL;
$unpackString.="A$field[fieldlen]$field[fieldname]/";
array_push($fields, $field);}}
fseek($fdbf, $header['FirstRecord']); // move back to the start of the first record
(after the field definitions)
for ($i=1; $i<=$header['RecordCount']; $i++) {
$deleted=fread($fdbf, 1);
$buf = fread($fdbf,$header['RecordLength']-1);
switch($deleted) {
case ' '://valid record
$record=unpack($unpackString,$buf);
echo "record $i: ".serialize($record).PHP_EOL;
break;
case '*'://deleted record
echo "Skipping deleted record $i".PHP_EOL;
continue;
break;
default:
printf("Unrecognized record marker %s, dec %d".PHP_EOL, $deleted, ord($deleted));
}
//echo $i.$buf.PHP_EOL;//raw record
}
fclose($fdbf);
}
?>