dbf.lib.php
上传用户:jiangbw
上传日期:2022-03-16
资源大小:49k
文件大小:15k
源码类别:

MySQL数据库

开发平台:

Unix_Linux

  1. <?
  2. /*======================================================================*
  3. || #################################################################### ||
  4. || # BUILD UNDER PHP SCRIPTNET 3.2.1 FRAMEWORK ||
  5. || # ---------------------------------------------------------------- # ||
  6. || # Code2Art Open Source Software. All Rights Reserved.  ||
  7. || # This file should be redistributed in whole or significant part.  # ||
  8. || # ------------------ SCRIPTNET IS FREE SOFTWARE ------------------ # ||
  9. || # http://www.code2art.com | http://www.code2art.com/scriptnet      # ||
  10. || # Copyleft by Benediktus Ardian Hersanto, SE       # ||
  11. || # Sorry if this framework is still unavailable for public       # ||
  12. || # because I still searching on my own head.       # ||
  13. || #################################################################### ||
  14. *======================================================================*/
  15. /*======================================================================*
  16. || #################################################################### ||
  17. || DBF to MySQL Bulk Converter 2.0 ||
  18. ||______________________________________________________________________||
  19. || This utility was developed on 2006, since this were used to be on    ||
  20. || my own library. But I think I should share it to you, because I      ||
  21. || need to save my work on Internet (I don't believe on my own HD drive)||
  22. || it always crash and had a terrible bad sectors.  ||
  23. || Thanks to all person who download this utility, I hope you enjoy it. ||
  24. || ||
  25. || Regards, ||
  26. || Benediktus Ardian Hersanto,SE (ardie_b@yahoo.com) ||
  27. /*======================================================================*/
  28. // ---------------------------------------------------------------------//
  29. // Free to use for everyone who understand PHP
  30. // ---------------------------------------------------------------------//
  31. /************************************************************
  32. author : B. Ardian Hersanto,SE on May 2006
  33. email  : ardie_b@yahoo.com
  34. *************************************************************
  35. Thanks to http://www.wotsit.org for file type documentation.
  36. This script only works to PC only, 
  37. on macintosh you have to change unpack format to big-endian (its your own problem, not me)
  38. *************************************************************/
  39. if(!function_exists('str_split')) {
  40. function str_split($string,$split_len=1) {
  41. $chars = array();
  42. for($i=0;$i<ceil(strlen($string)/$split_len);$i++)
  43. $chars[] = substr($string,$i*$split_len,$split_len);
  44. return $chars;
  45. }
  46. }
  47. class dbf {
  48.     var $dbf_num_rec;           //Number of records in the file
  49.     var $dbf_num_field;         //Number of columns in each row
  50.     var $dbf_names = array();   //Information on each column ['name'],['len'],['type']
  51. var $check_validity = false;
  52. var $lowercase_fields = true;
  53.     //These are private....
  54.     var $_raw;               //The raw input file
  55.     var $_rowsize;           //Length of each row
  56.     var $_hdrsize;           //Length of the header information (offset to 1st record)
  57.     var $_memos;             //The raw memo file (if there is one).
  58. var $date_format = array("Year","Month","Day"); //Standard date format
  59. var $dbase_iii   = array(0x02,0x03,0x83);  // Version types that match DBASE III structure has Different size on the length of Db Container Reserved area
  60.     function dbf($filename) {
  61. echo "<CENTER>PROCESSING FILE : ",$filename,"<BR></CENTER>";
  62.         if ( !file_exists($filename)) {
  63.             echo 'DBF file not found!!!'; exit;
  64.         } else $this->file = $filename;
  65. }
  66. function parseFile($read_contents=false) {
  67.         //Read the File
  68. $filename = $this->file;
  69.         $handle = fopen($filename, "r");
  70.         if (!$handle) { echo "Cannot read DBF file"; exit; }
  71.         $this->bin_data = fread($handle, filesize($filename));
  72.         fclose ($handle);
  73. $this->version = hexdec(bin2hex($this->bin_data[0]));
  74. $this->table_type = $this->getTableType();
  75. if($this->table_type=='') die("Not a valid DBF file !!!");
  76. // Is a valid dbf file EOF signature
  77. $eof_signature = bin2hex(substr($this->bin_data,strlen($this->bin_data)-1,1));
  78. if($this->check_validity){if($eof_signature!='1a') die("Not a valid DBF file !!!");}
  79. $this->_struct = array();
  80. // Extract Date
  81.         for($i=1; $i<4; $i++)
  82. $this->_struct['modified_date'][$this->date_format[-1+$i]] = bin2hex($this->bin_data[$i]);
  83. // Extract Number of records // V1 = little endian 32 bit read order
  84. $this->_struct['number_of_records'] = implode("",unpack("V1",substr($this->bin_data,4,4)));
  85. // Extract Length of header Structure // v1 = little endian 16 bit read order
  86. $this->_struct['header_length'] = implode("",unpack("v1",substr($this->bin_data,8,2)));
  87. // Extract Length of each record
  88. $this->_struct['each_rec_length'] = implode("",unpack("v1",substr($this->bin_data,10,2)));
  89. // Check if this file is not corrupted
  90. if($this->check_validity) {
  91. if($this->_struct['header_length']+($this->_struct['number_of_records']*$this->_struct['each_rec_length'])==filesize($filename)) die("File DBF Corrupt !!!");
  92. }
  93. // Extract Reserved
  94. $this->_struct['Reserved#1'] = implode("",unpack("v1",substr($this->bin_data,12,2)));
  95. // Extract Incomplete Transaction
  96. $this->_struct['Incomplete_Transaction'] = implode("",unpack("C1",substr($this->bin_data,14,1)));
  97. // Extract Encryption Flag
  98. $this->_struct['encryption_state'] = implode("",unpack("C1",substr($this->bin_data,15,1)));
  99. // Extract Reserved For LAN
  100. $this->_struct['LAN_reserved'] = implode("",unpack("V1",substr($this->bin_data,16,4)));
  101. // Extract Multi User DBASE
  102. $this->_struct['multi_user'] = implode("",unpack("V2",substr($this->bin_data,20,8)));
  103. // Extract MDX Flag
  104. $this->_struct['MDX_state'] = implode("",unpack("C1",substr($this->bin_data,28,1)));
  105. // Extract Language Driver
  106. $this->_struct['encode_language'] = bin2hex(substr($this->bin_data,29,1));
  107. // Extract Reserved 2nd
  108. $this->_struct['Reserved#2'] = bin2hex(substr($this->bin_data,30,2));
  109. // Extract Field Structures
  110. $end = '';$i=1; $this->data_offset = 0;
  111. if($this->_struct['number_of_records']>0) {
  112. while ($end=='') {
  113. $this->data_offset = $i*32;
  114. $tmp = bin2hex(substr($this->bin_data,$this->data_offset,32));
  115. if(eregi('0D',substr($tmp,0,2))) $end = '1';
  116. if($end=='')$this->_struct['Fields Raw'][] = $tmp;
  117. $i++;
  118. }
  119. $this->readStructure();
  120. if($read_contents) {
  121. if(eregi('Visual FoxPro',$this->table_type)) {
  122. // Extract Data
  123. $offset_start = $this->data_offset+264; // Database Container + 263 + 1 deleted record
  124. for($i=0;$i<$this->_struct['number_of_records'];$i++) {
  125. if($i>0) $offset_start = $this->_struct['each_rec_length']+$offset_start;
  126. $this->readData($offset_start,$i);
  127. }
  128. } else if(in_array($this->version,$this->dbase_iii)) {
  129. // Extract Data
  130. // There are some of software vendor add an empty char before data
  131. $header_bug_flag = bin2hex(substr($this->bin_data,$this->data_offset+1,1));
  132. if($header_bug_flag==0x00) $offset_start = $this->data_offset+2;
  133. else $offset_start = $this->data_offset+1; // Database Container + 1 deleted record
  134. for($i=0;$i<$this->_struct['number_of_records'];$i++) {
  135. if($i>0) $offset_start = $this->_struct['each_rec_length']+$offset_start;
  136. $this->readData($offset_start,$i);
  137. }
  138. }
  139. }
  140. }
  141. return $this->_struct;
  142. }
  143. function parseData() {
  144. if(eregi('Visual FoxPro',$this->table_type)) {
  145. // Extract Data
  146. $offset_start = $this->data_offset+264; // Database Container + 263 + 1 deleted record
  147. if($this->_struct['number_of_records']>0) {
  148. for($i=0;$i<$this->_struct['number_of_records'];$i++) {
  149. if($i>0) $offset_start = $this->_struct['each_rec_length']+$offset_start;
  150. $this->readData($offset_start,$i);
  151. }
  152. }
  153. } else if(in_array($this->version,$this->dbase_iii)) {
  154. // Extract Data
  155. // There are some of software vendor add an empty char before data
  156. $header_bug_flag = bin2hex(substr($this->bin_data,$this->data_offset+1,1));
  157. if($header_bug_flag==0x00) $offset_start = $this->data_offset+2;
  158. else $offset_start = $this->data_offset+1; // Database Container + 1 deleted record
  159. if($this->_struct['number_of_records']>0) {
  160. for($i=0;$i<$this->_struct['number_of_records'];$i++) {
  161. if($i>0) $offset_start = $this->_struct['each_rec_length']+$offset_start;
  162. $this->readData($offset_start,$i);
  163. }
  164. }
  165. }
  166. if(isset($this->_struct['Records'])&&is_array($this->_struct['Records'])) 
  167. return $this->_struct['Records']; else return NULL;
  168. }
  169. function readStructure() {
  170. if(isset($this->_struct['Fields Raw'])) {
  171. for($i=0;$i<count($this->_struct['Fields Raw']);$i++) {
  172. $row = $this->_struct['Fields Raw'][$i];
  173. // Extract Field Name
  174. $this->_struct['Fields'][$i]['Field Name'] = '';
  175. $string = substr($row,0,10*2);
  176. $chars = str_split($string,2);
  177. for($n=0;$n<count($chars);$n++) 
  178. $this->_struct['Fields'][$i]['Field Name'] .= chr(hexdec($chars[$n]));
  179. if($this->lowercase_fields) $this->_struct['Fields'][$i]['Field Name'] = strtolower(trim($this->_struct['Fields'][$i]['Field Name']));
  180. // Extract Field Type
  181. $this->_struct['Fields'][$i]['Field Type'] = chr(hexdec(substr($row,11*2,1*2)));
  182. // Extract Field Data Address
  183. $this->_struct['Fields'][$i]['Field Data Address'] = substr($row,12*2,4*2);
  184. // Extract Field Length
  185. $this->_struct['Fields'][$i]['Field Length'] = hexdec(substr($row,16*2,1*2));
  186. // Extract Field Decimal Count
  187. $this->_struct['Fields'][$i]['Decimal Count'] = hexdec(substr($row,17*2,1*2));
  188. // Extract Multi User
  189. $this->_struct['Fields'][$i]['Multi User DBASE#1'] = substr($row,18*2,2*2);
  190. // Extract Work Area ID
  191. $this->_struct['Fields'][$i]['Work Area ID'] = substr($row,20*2,1*2);
  192. // Extract Reserved for Multi User
  193. $this->_struct['Fields'][$i]['Multi User DBASE#2'] = substr($row,21*2,2*2);
  194. // Extract Flag for SET FIELDS
  195. $this->_struct['Fields'][$i]['SET FIELDS FLAG'] = substr($row,23*2,1*2);
  196. // Extract Reserved
  197. $this->_struct['Fields'][$i]['Reserved'] = substr($row,24*2,7*2);
  198. // Extract Index Flag
  199. $this->_struct['Fields'][$i]['Index Field'] = substr($row,31*2,1*2);
  200. }
  201. unset($this->_struct['Fields Raw']);
  202. }
  203. }
  204. function readData($data_start,$index) {
  205. if(isset($this->_struct['Fields'])&&count($this->_struct['Fields'])>0) {
  206. $raw_hex = substr($this->bin_data,$data_start,$this->_struct['each_rec_length']);
  207. $prev_offset = 1;
  208. for($i=0;$i<count($this->_struct['Fields']);$i++) {
  209. $data_type = trim($this->_struct['Fields'][$i]['Field Type']);
  210. $column = trim($this->_struct['Fields'][$i]['Field Name']);
  211. $data_len = $this->_struct['Fields'][$i]['Field Length'];
  212. if(!isset($this->_struct['Records'][$index]['delete_mark']))$this->_struct['Records'][$index]['delete_mark'] = substr($raw_hex,0,1);
  213. $this->_struct['Records'][$index][$column] = $this->_ConvertDataType(substr($raw_hex,$prev_offset,$data_len),$this->_struct['Fields'][$i]);
  214. $prev_offset += $data_len;
  215. }
  216. } else die('Cannot read DBF data !!!');
  217. }
  218. function _ConvertDataType($content,$_def) {
  219. $type = $_def['Field Type'];
  220. switch ($type) {
  221. case 'C' : return $content; break;
  222. case 'L' : if(eregi('T',$content)||eregi('Y',$content)) return TRUE;
  223.    else if(eregi('F',$content)||eregi('N',$content)) return FALSE;
  224.    else return NULL;
  225.    break;
  226. case 'D' : $date['Year'] = trim(substr($content,0,4));
  227.    $date['Month'] = trim(substr($content,4,2));
  228.    $date['Day'] = trim(substr($content,6,2));
  229.    return $date;
  230.    break;
  231. case 'N' : if($_def['Decimal Count']==0) settype($content,"integer");
  232.    return $content;
  233.    break;
  234. case 'M' : return $this->readMemo($_def); break;
  235. }
  236. }
  237. function createMySQLTable() {
  238. $file = basename($this->file);
  239. $table_name = eregi_replace(".dbf",'',$file);
  240. $sql = "CREATE TABLE IF NOT EXISTS {$table_name}(";
  241. if(isset($this->_struct['Fields'])&&is_array($this->_struct['Fields'])) {
  242. for($i=0;$i<count($this->_struct['Fields']);$i++) {
  243. if($this->lowercase_fields) $field_name = strtolower($this->_struct['Fields'][$i]['Field Name']);
  244. else $field_name = $this->_struct['Fields'][$i]['Field Name'];
  245. $fields[] = trim($field_name).$this->getMySQLDataType($this->_struct['Fields'][$i]);
  246. }
  247. $sql .= implode(',',$fields).")";
  248. return $sql;
  249. } else {
  250. return '';
  251. }
  252. }
  253. function getMySQLDataType($_def) {
  254. $type = $_def['Field Type'];
  255. switch ($type) {
  256. case 'C' : if($_def['Field Length']>5) return " varchar(".$_def['Field Length'].")"; else return " char(".$_def['Field Length'].")";break;
  257. case 'L' : return " int(1) default 0";
  258.    break;
  259. case 'D' : return " date";
  260.    break;
  261. case 'N' : if($_def['Decimal Count']==0) return " int(".$_def['Field Length'].")";
  262.    else if($_def['Decimal Count']>0) return " float(".$_def['Field Length'].",".$_def['Decimal Count'].")";
  263.    break;
  264. case 'M' : return " text"; break;
  265. }
  266. }
  267. function readMemo($_def) {
  268. if(eregi('Fox',$this->table_type)) $memo = basename(basename($this->file,".dbf"),".DBF").".fpt";
  269. else $memo = basename(basename($this->file,".dbf"),".DBF").".dbt";
  270. if(file_exists($memo)) {
  271. $fp = fopen($memo,"r");
  272. if($fp) {
  273. $mem_file = fread($fp,filesize($memo));
  274. // Read Header
  275. $index = (isset($this->_struct['Memo']))?count($this->_struct['Memo']):0;
  276. if(eregi('Fox',$this->table_type)) {
  277. $memo_header = substr($mem_file,0,512);
  278. $memo_text = substr($mem_file,512,filesize($memo));
  279. //Number of next available Block skipped
  280. //bin2hex(implode("",unpack("N1",substr($memo_header,0,4))));
  281. $size_of_block = hexdec(bin2hex(substr($memo_header,6,2)));
  282. $start_offset = isset($this->_struct['Memo'][$index-1])?$size_of_block*$index:0;
  283. $this->_struct['Memo'][$index]['Record Type'] = bin2hex(substr($memo_text,$start_offset+3,1));
  284. $this->_struct['Memo'][$index]['Length of Memo'] = hexdec(bin2hex(substr($memo_text,$start_offset+4,4)));
  285. $this->_struct['Memo'][$index]['Content'] = substr($memo_text,$start_offset+8,$this->_struct['Memo'][$index]['Length of Memo']);
  286. fclose($fp);
  287. return $this->_struct['Memo'][$index]['Content'];
  288. }
  289. } else {
  290. echo "<b>Warning :</b> File permission denied on file ".$memo."<BR>";
  291. fclose($fp);
  292. }
  293. } else {
  294. echo "<b>Warning :</b> Memo file not found!!!<br>";
  295. }
  296. }
  297. function getTableType() {
  298. settype($this->version,"integer");
  299. switch ($this->version) {
  300. case 2 : return "FoxBase"; break;
  301. case 3 : return "File without DBT"; break;
  302. case 4 : return "dBASE IV w/o memo file"; break;
  303. case 5 : return "dBASE V w/o memo file"; break;
  304. case 48 : return "Visual FoxPro w. DBC"; break;
  305. case 49 : return "Visual FoxPro w. AutoIncrement field"; break;
  306. case 67 : return ".dbv memo var size (Flagship)"; break;
  307. case 123 : return "dBASE IV with memo"; break;
  308. case 131 : return "File with DBT or dBASE III+ with memo file"; break;
  309. case 139 : return "dBASE IV w. memo"; break;
  310. case 142 : return "dBASE IV w. SQL table"; break;
  311. case 179 : return ".dbv and .dbt memo (Flagship)"; break;
  312. case 229 : return "Clipper SIX driver w. SMT memo file."; break;
  313. case 245 : return "FoxPro w. memo file"; break;
  314. case 251 : return "Unknown Foxpro"; break;
  315. }
  316. }
  317. }
  318. ?>