php无法获取字段,PHP读取dbf数据库时dbase无法读取字段类型为memo的数据的解决办法...

自定义的php dbf读取类:

class Prodigy_DBF {

private $Filename, $DB_Type, $DB_Update, $DB_Records, $DB_FirstData, $DB_RecordLength, $DB_Flags, $DB_CodePageMark, $DB_Fields, $FileHandle, $FileOpened;

private $Memo_Handle, $Memo_Opened, $Memo_BlockSize;

private function Initialize() {

if($this->FileOpened) {

fclose($this->FileHandle);

}

if($this->Memo_Opened) {

fclose($this->Memo_Handle);

}

$this->FileOpened = false;

$this->FileHandle = NULL;

$this->Filename = NULL;

$this->DB_Type = NULL;

$this->DB_Update = NULL;

$this->DB_Records = NULL;

$this->DB_FirstData = NULL;

$this->DB_RecordLength = NULL;

$this->DB_CodePageMark = NULL;

$this->DB_Flags = NULL;

$this->DB_Fields = array();

$this->Memo_Handle = NULL;

$this->Memo_Opened = false;

$this->Memo_BlockSize = NULL;

}

public function __construct($Filename, $MemoFilename = NULL) {

$this->Prodigy_DBF($Filename, $MemoFilename);

}

public function Prodigy_DBF($Filename, $MemoFilename = NULL) {

$this->Initialize();

$this->OpenDatabase($Filename, $MemoFilename);

}

public function OpenDatabase($Filename, $MemoFilename = NULL) {

$Return = false;

$this->Initialize();

$this->FileHandle = fopen($Filename, "r");

if($this->FileHandle) {

// DB Open, reading headers

$this->DB_Type = dechex(ord(fread($this->FileHandle, 1)));

$LUPD = fread($this->FileHandle, 3);

$this->DB_Update = ord($LUPD[0])."/".ord($LUPD[1])."/".ord($LUPD[2]);

$Rec = unpack("V", fread($this->FileHandle, 4));

$this->DB_Records = $Rec[1];

$Pos = fread($this->FileHandle, 2);

$this->DB_FirstData = (ord($Pos[0]) + ord($Pos[1]) * 256);

$Len = fread($this->FileHandle, 2);

$this->DB_RecordLength = (ord($Len[0]) + ord($Len[1]) * 256);

fseek($this->FileHandle, 28); // Ignoring "reserved" bytes, jumping to table flags

$this->DB_Flags = dechex(ord(fread($this->FileHandle, 1)));

$this->DB_CodePageMark = ord(fread($this->FileHandle, 1));

fseek($this->FileHandle, 2, SEEK_CUR); // Ignoring next 2 "reserved" bytes

// Now reading field captions and attributes

while(!feof($this->FileHandle)) {

// Checking for end of header

if(ord(fread($this->FileHandle, 1)) == 13) {

break; // End of header!

} else {

// Go back

fseek($this->FileHandle, -1, SEEK_CUR);

}

$Field["Name"] = trim(fread($this->FileHandle, 11));

$Field["Type"] = fread($this->FileHandle, 1);

fseek($this->FileHandle, 4, SEEK_CUR); // Skipping attribute "displacement"

$Field["Size"] = ord(fread($this->FileHandle, 1));

fseek($this->FileHandle, 15, SEEK_CUR); // Skipping any remaining attributes

$this->DB_Fields[] = $Field;

}

// Setting file pointer to the first record

fseek($this->FileHandle, $this->DB_FirstData);

$this->FileOpened = true;

// Open memo file, if exists

if(!empty($MemoFilename) and file_exists($MemoFilename) and preg_match("%^(.+).fpt$%i", $MemoFilename)) {

$this->Memo_Handle = fopen($MemoFilename, "r");

if($this->Memo_Handle) {

$this->Memo_Opened = true;

// Getting block size

fseek($this->Memo_Handle, 6);

$Data = unpack("n", fread($this->Memo_Handle, 2));

$this->Memo_BlockSize = $Data[1];

}

}

}

return $Return;

}

public function GetNextRecord($FieldCaptions = false) {

$Return = NULL;

$Record = array();

if(!$this->FileOpened) {

$Return = false;

} elseif(feof($this->FileHandle)) {

$Return = NULL;

} else {

// File open and not EOF

fseek($this->FileHandle, 1, SEEK_CUR); // Ignoring DELETE flag

foreach($this->DB_Fields as $Field) {

$RawData = fread($this->FileHandle, $Field["Size"]);

// Checking for memo reference

if($Field["Type"] == "M" and $Field["Size"] == 4 and !empty($RawData)) {

// Binary Memo reference

$Memo_BO = unpack("V", $RawData);

if($this->Memo_Opened and $Memo_BO != 0) {

fseek($this->Memo_Handle, $Memo_BO[1] * $this->Memo_BlockSize);

$Type = unpack("N", fread($this->Memo_Handle, 4));

if($Type[1] == "1") {

$Len = unpack("N", fread($this->Memo_Handle, 4));

$Value = trim(fread($this->Memo_Handle, $Len[1]));

} else {

// Pictures will not be shown

$Value = "{BINARY_PICTURE}";

}

} else {

$Value = "{NO_MEMO_FILE_OPEN}";

}

} else {

$Value = trim($RawData);

}

if($FieldCaptions) {

$Record[$Field["Name"]] = $Value;

} else {

$Record[] = $Value;

}

}

$Return = $Record;

}

return $Return;

}

function __destruct() {

// Cleanly close any open files before destruction

$this->Initialize();

}

}

使用方法:

$Test = new Prodigy_DBF("customer.DBF", "customer.FPT");

while(($Record = $Test->GetNextRecord(true)) and !empty($Record)) {

print_r($Record);

}

参数1为dbf文件路径,参数2为fpt文件路径(可省略)。

注意事项:

It might not be an almighty perfect class, but it works for me. Feel free to use this code, but note that the class is VERY tolerant - it doesn't care if fread() and fseek() return true or anything else - so you might want to improve it a bit before using.

Also note that there are many private variables like number of records, recordsize etc. which are not used at the moment.

原贴网址:

http://stackoverflow.com/questions/1947348/how-to-read-foxpro-memo-with-php

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值