Finding out information about the database you are working is often as important as the actual data contained within it. For example, it is quite common to need to know something about the table in order to decide what action to perform next. Luckily, retrieving database table information from PHP is just as easy as retrieving data from the tables themselves.
There are several functions you can use to look at the structure of a database table:
- mysql_list_fields(): Call this function first to get information on table fields. It takes three arguments (a database name, a table name, and an optional link identifier) and returns a result pointer that refers to a list of all the fields in the specified table of the specified database. For example, if you want a pointer to list of all the fields in the user table in the sample_db database, you could use:
$result = mysql_list_fields("sample_db", "user");The $result variable now holds a pointer to a list of fields in the user table. You'll see an example of this shortly.
- mysql_num_fields(): This takes a result pointer (as returned by the preceding function) and returns the total number of fields from the result set to which it points. If you want to get the number of fields in the user table, just pop the pointer $result that you obtained from mysql_list_fields() into the mysql_num_fields() function:
$number_of_fields = mysql_num_fields($result);The variable $number_of_fields contains (surprise!) the number of fields in the user table. - msyql_field_name(), mysql_field_len(), and mysql_field_type(): These functions return the field's field name, field length, and field type properties, respectively. Each of them takes both a result pointer and a field index as arguments, which specify the table and field (counting fields from zero) in that order. For example, to get the length of the username field in the user table, first note that username is the fourth field in the table and therefore has a field index of 3 (indexes start at zero), and then you could use:
$username_length = mysql_field_len($result, 3);Because you defined username as having a length of 30 characters, $username_length should contain 30. The other two functions work much the same way. - mysql_field_flags(): This function takes a result set pointer and a field index, and returns a string containing the attribute for the given field. Attributes of a field include NULL or NOT NULL, PRIMARY KEY, UNIQUE, and so on. You can place the attributes of the username field (from the user table) into the variable $attributes using the following code:
$attributes = mysql_field_flags($result, 3);The only attribute of the username field is NOT NULL, so that is the value of $attributes.
Try it Out: Get Information on Fields
Let's take a look at these functions in action. The following script, metadata.php, returns the name, length, and type of each field defined in the user table:
<?php
include_once "./common_db.inc";
$link_id = db_connect();
$result = mysql_list_fields("sample_db", "user", $link_id);
for($i=0; $i < mysql_num_fields($result); $i++) {
echo mysql_fieldname($result, $i);
echo "(".mysql_field_len($result, $i) . ")";
echo " - " . mysql_field_type($result, $i) . "<BR>";
}
?>
How it Works
As usual, start by including the database functions in common_db.inc, and then connect to the server using db_connect():
include_once "./common_db.inc";
$link_id = db_connect();
Then call the mysql_list_fields() function, specifying the database, table, and connection that you want to use (sample_db, user, and $link_id, respectively for this example):
$result = mysql_list_fields("sample_db", "user", $link_id);
The function returns a pointer to a result set that lists all fields in the user table. Store it in the variable $result, and use it with mysql_num_fields() to find out how many fields the table contains. This sets the upper limit of a for...next loop:
for($i=0; $i < mysql_num_fields($result); $i++) {
Using the loop index to specify which field to work with, call the functions mysql_field_name(), mysql_field_len(), and mysql_field_type(), which return the name, length, and type of the fields available:
echo mysql_field_name($result,$i);
echo "(" . mysql_field_len($result, $i) . ")";
echo" - " . mysql_field_type($result, $i) "<BR>";
Some of the field types returned are ambiguous—for example, CHAR and VARCHAR are both returned as string, whereas TEXT is returned as BLOB. To get exact field types (as they are defined in a MySQL table) involves a bit more work. That's where the mysql_field_flags() function comes in, and you can easily modify the code to show the field attributes. Here's the revised code:
$link_id = db_connect(); $result = mysql_list_fields("sample_db", "user", $link_id); for($i=0; $i < mysql_num_fields($result); $1 ++) { echo mysql_field_name($result,$i); echo "(" . mysql_field_len($result, $i) . ")"; echo " - " . mysql_field_type($result, $i); echo " " , mysql_field_flags($result, $i) . "<BR>"; }
Finally, there's a single function that can be used to get all the information on a table's fields in one go: mysql_fetch_field(). If you pass this function a result set pointer and a field index (again, counting fields from zero), it returns an object whose properties include the name of the field and the name of the table to which it belongs, along with its length, attributes, and other details. The following table describes the properties of the returned object.
| Property | Description |
|---|---|
| blob | True if the field is a BLOB |
| max_length | The maximum length of the field |
| multiple_key | True if the field is a key but not unique |
| name | The field name |
| not_null | True if the field cannot be NULL |
| numeric | True if the field is numeric |
| primary_key | True if the field is a primary key |
| table | The name of the table to which the field belongs |
| type | The field type |
| unique_key | True if the field is a unique key |
| unsigned | True if the field is unsigned |
| def | Gives the default value if specified |
| zerofill | True if the field is zero-filled. A zerofill attribute is used to force a number to be a certain width by padding it with leading zeros |
Try it Out: Use mysql_fetch_field()
You can use this function to produce a result similar to the previous example. Place the following code in a file called fetch_field.php:
<?php include_once "./common_db.inc"; $link_id = db_connect(); $result = mysql_list_fields ("sample_db", "user", $link__id); for($i=0; $i < mysql_num_fields($result); $i++) { $field_info_object = mysql_fetch_field($result, $i); echo $field_info_object->name . "(". $field_info_object->max_length . ")"; echo " - " . $field_info_object->type; if($field_info_object->not_null) { echo " not_null "; }else{ " null "; } if($field_info_object:->primary_key) { echo " primary_key "; }else if($field_info_object:-->multiple_key) { echo " key "; }else if($field_info_object->unique_key) { echo " unique "; } if($field_info_object->unsigned){ echo " unsigned "; } if($field_info_object->zerofill) { echo " zero-filled "; } echo "<BR>"; } ?>
How it Works
This works much the same as the last script, but something looks amiss—the length of each field is reported as 0 bytes. Unfortunately, although it's very versatile, the mysql_fetch_field() function contains a small bug that causes its max_length property to always contain 0—no matter what size the specified field is defined with. At time of writing, the latest version of PHP is the RC1 version of PHP5—we can but hope this bug is crushed in the next release. Until then, just revert to using mysql_field_len() for this particular information:
$field_info_object = mysql_fetch_field($result, $i); echo $field_info_object->name . "(" . mysql_field_len{$result, $i) . ")"; echo " - " . $field_info_object->type;
Now the script reports the correct size of each field.
The capability to access metadata on database tables is essential to any general-purpose database management application, which won't know anything beforehand about the table structures with which it has to work. To handle tables correctly every time, it has to rely heavily on functions such as those you've just seen.
