You are here

GIS Developing Follow Me with PHP--Load GeoAttribute from DBF dBase format

Blog Terms: 

1. What is DBF dBase Format?

dBASE was the first widely used database management system or DBMS for microcomputers, published by Ashton-Tate for CP/M, and later on the Apple II, Apple Macintosh, UNIX [1], VMS [2], and IBM PC under DOS where it became one of the best-selling software titles for a number of years. dBASE was never able to transition successfully to Microsoft Windows and was eventually displaced by newer products like Paradox, Clipper, FoxPro, and Microsoft Access. dBASE was sold to Borland in 1991, which sold the rights to the product line in 1999 to the newly-formed dBASE Inc.

Starting in the mid 1980s many other companies produced their own dialects or variations on the product and language. These included FoxPro (now Visual FoxPro), Arago, Force, Recital, dbFast, dbXL, Quicksilver, Clipper, Xbase++, FlagShip, and Harbour. Together these are informally referred to as xBase or XBase.

-------http://en.wikipedia.org/wiki/DBASE

Why shoud you learn to read dbf file? Because Esri shapefile stores the attribute information of geodata not in shapefile itself, but in other dbf file. Oh, I hate Esri, why need I to read so many different data formats??? I hope you can be the boss of the esri and change everything to make things easy.

But don't worry, there is always one hero will occor to save the earth. Who? dBase Functions in PHP!  Wow~~~~~~

2. dBase Functions

These functions in PHP allow you to access records stored in dBase-format (dbf) databases. But firstly, please remove the magic semicolon before dbase.dll in your php.ini file in order to use this function in PHP5. The oftenly used functions are these, you can find in PHP handbook.

dbase_add_record -- Adds a record to a database
dbase_close -- Closes a database
dbase_create -- Creates a database
dbase_delete_record -- Deletes a record from a database
dbase_get_header_info -- Gets the header info of a database
dbase_get_record_with_names --  Gets a record from a database as an associative array
dbase_get_record --  Gets a record from a database as an indexed array
dbase_numfields -- Gets the number of fields of a database
dbase_numrecords -- Gets the number of records in a database
dbase_open -- Opens a database
dbase_pack -- Packs a database
dbase_replace_record -- Replaces a record in a database

3. dBase Format Description

The Data File is a mix of binary and ASCII data. Header contains binary data. The records are all in ASCII, that means you can open it with texteditot, but the data displaying on your screen has an unreadable structure.

 

3.1 Opens and Close a database

// open in read-only mode
$db = dbase_open('capitals.dbf', 0);

if (
$db) {
  
// read some data ..
  
  
dbase_close($db);
}

3.2 Get dbf Header

Use dbase_get_header_info to get the header info of a database and an indexed array with an entry for each column in the database. Each array element contains an associative array of column information, as described here:

name

The name of the column

type

The human-readable name for the dbase type of the column (i.e. date, boolean, etc.)

length

The number of bytes this column can hold

precision

The number of digits of decimal precision for the column

format

A suggested printf() format specifier for the column

offset

The byte offset of the column from the start of the row

Use the php code to display the information in the header, the column name, type, format and so on.
// Path to dbase file
$db_path = "capitals.dbf";

// Open dbase file
$dbh = dbase_open($db_path, 0)
  or die(
"Error! Could not open dbase database file '$db_path'.");

// Get column information
$column_info = dbase_get_header_info($dbh);

// Display information
print_r($column_info);

The outputted array will be like this:
Array
(
    [0] => Array
        (
            [name] => IMS_ID
            [type] => number
            [length] => 9
            [precision] => 0
            [format] => %9s
            [offset] => 1
        )

    [1] => Array
        (
            [name] => GEO_CODE
            [type] => number
            [length] => 14
            [precision] => 0
            [format] => %14s
            [offset] => 10
        )
........................................
    [9] => Array
        (
            [name] => Y_2003
            [type] => number
            [length] => 9
            [precision] => 0
            [format] => %9s
            [offset] => 221
        )

)


Maybe your server host hasn't open the dbase function or your server is using PHP4, how to
retrieve the data? You can try these code below:

function loadDBFHeader($DBFFileName)
{
    $DBFFile = fopen($DBFFileName, 'r');

    $result = array();
    $buff32 = array();
    $i = 1;
    $inHeader = true;

    while ($inHeader) {
        if (!feof($DBFFile)) {
            $buff32 = fread($DBFFile, 32);
            if ($i > 1) {
                if (substr($buff32, 0, 1) == chr(13)) {
                    $inHeader = false;
                } else {
                    $pos = strpos(substr($buff32, 0, 10), chr(0));
                    $pos = ($pos == 0 ? 10 : $pos);

                    $fieldName = substr($buff32, 0, $pos);
                    $fieldType = substr($buff32, 11, 1);
                    $fieldLen = ord(substr($buff32, 16, 1));
                    $fieldDec = ord(substr($buff32, 17, 1));

                    array_push($result, array($fieldName, $fieldType, $fieldLen, $fieldDec));
                }
            }
            $i++;
        } else {
            $inHeader = false;
        }
    }

    fclose($DBFFile);
    return($result);
}

$dbfheader = loadDBFHeader("capitals.dbf");
 print_r($dbfheader);


The outputed array will be this:
Array
(
    [0] => Array
        (
            [0] => IMS_ID
            [1] => N
            [2] => 9
            [3] => 0
        )
.............................

3.3 Get dbf Record

dbase_get_record_with_names is using to get a record from a database as an associative array, this structure is clearer than using the other function dbase_get_record --  Gets a record from a database as an indexed array .
// open in read-only mode
$db = dbase_open('capitals.dbf', 0);

if ($db) {
  $record_numbers = dbase_numrecords($db);

  for ($i = 1; $i <= $record_numbers; $i++) {
      $row = dbase_get_record_with_names($db, $i);

      print_r($row);
      //echo "Member #$i: " . trim($row['name']) . "\n";
  }
}

The data record array will be listed:
Array
(
    [IMS_ID] => 1
    [GEO_CODE] => 1000
    [WUP_AGGL] => Kabul                                 
    [CNTRY_NAME] => Afghanistan                              
    [UN_CODE] => 4
    [GEO_SUBREG] => South Asia                
    [GEO_REGION] => Asia and the Pacific              
    [WUP_CAPIT] => Kabul                       
    [CAPIT_1_0] => 1
    [Y_2003] => 2956
    [deleted] => 0
)
....................


After getting those attribute information you could use it to discribe the geodata, for example, display the capital name in its' location(refer to GIS Developing Follow Me with PHP--Visualize Geodata and create map in raster image).

 

For those users they could not use dbase function in their remote server host, sorry I have not found any solutions to read the dbase record. Maybe someone could help me for that, because I am the pathetic one among them    T_T

Anyway, the stupid source code is available here: loadDbf.rar

Ref:

http://www.clicketyclick.dk/databases/xbase/format/dbf.html#DBF_STRUCT

http://en.wikipedia.org/wiki/DBASE

PHP5 handbook