Chapter 1

Preface

In this chapter, you will be introduced to the simplest use of DBLIB.

Imagine we need to have a list of countries in the database. So we set up a simple table which has only two columns. One is numeric primary key (country ID), the other is a textual field (country name). We need to provide user a way to edit this table. Since the table will have only several entries, we will not make use of filtering.

EXAMPLE: You can find fully working code for this task is contained in the example/cars/admin/country directory, where it is used to edit the country table.

File layout

Now I will introduce you to the file layout my applications (and this guide and DBLIB examples) use.

There are two styles of writing a web (PHP) application. The first one is monolithic. It uses one or several scripts, which handle all the functions. The function to do is passed to the script by a parameter.

I use another approach. (Almost) each function has its own file/script. Moreover, there is a separate directory for each view. As you can see in the example, the language directory contains scripts, used to edit the language table.

The scripts I use in examples/guide are:
NOTE: Some scripts may be ommited in some directories (like detail.php and filter.php in this first simple example).

Creating header file

First, we have to include DBLIB classes we will use. Here we suppose the classes will be in the include path. The example mentioned above uses another technique - DBLIB directory is stored in a global variable.

<?
  require_once("DBLView.php");
  require_once("DBLTextField.php");
  require_once("DBLMYSQLQuery.php");
Please note, that we use require_once() here. Because all DBLIB classes include their superclasses, it is necessary to use require_once() to prevent defining the same class more than once (which yields error).

Now we will instantiate the view:
     $view =& new DBLView("country");
Please note the use of "=&". Simply said, this has better performance than using only "=". For more information, please see php reference manual.

We use only one argument here - a string. This string is a view name. Why name views? Because of filters. If a filter is set on a view, DBLIB stores the filter settings to a session variable. So when you come again to the same view (i.e., view the same table), the filter you have set before will still be used. To distinguish the filters, they are stored under the view's name. So this is why the view has to have set unique name. Beware! The record offset (current page in the record index) is also considered a part of the filter and it is stored under the view name.
     $view->sortByColumnTitles = 0;
The above line disables sorting by clicking on column title, since we won't support sorting in this simple example.

Now we will define fields we use in the view. There is one field - the text to edit. The ID column is a primary key and it is not edited by the user, so we do not need to add it here.
    $name =& new DBLTextField("name","Name","",32,30);
    $name->allowEmpty = false;
    $view->addField($name);
First we create a text field. The first argument is field name. It serves both as a name of the database field (column) and to reference the field in calls to DBLIB (formats, filters, ... - see below). Then we provide a textual title. It is a simple ASCII string. It is used in error messages etc. The third argument is HTML title. It is used as a column/field title in record index/detail/edit form. Usually, those two are the same. So when HTML title is empty, DBLIB sets it to htmlspecialchars(<textual title>). This feature is used in the above code.

Next two parameters are widget width (in characters) and maximum characters that can be input into the field.  I have found, that it is best when the width is two characters more than maximum characters, so there is enough place for the cursor and the field contents are not scrolled.

On the second line we define that empty value is not allowed. Then we add the field to the view. Please note, that the view does not copy the field object, it only creates a reference to it. So even after you add the field, you can make changes to it using the $name variable.

Now we need to establish link from the record index. Since there is only one field, we will not use record detail, but the link will be directly to record edit form. It can be accomplished very simply:
    $view->editField = "name";
This will tell the view, that the field named name in the record index should be link to the edit form. How view knows where is the edit form? The name of the script is contained in the editURL property of the view, which is set to point to the edit.php script by default.

Next thing will be to define formats (format strings). Then need not to be defined at all, they can be directly specified in the function calls. But I found it useful to define formats in header.php - when you need to add another field later, you have to edit only header.php. That is nice.

Here are the formats we will use:
    $indexFormat = "name";
    $editFormat = "name";
Since this is very simple example, I will not describe the formats here. Please, see chapter 2 for more explanation. For now, you can see that there is a field name present.

As the last thing in the header, we will create a query.
     $q =& new DBLMYSQLQuery(new DBLDBDef("localhost","","","dblib_cars"),"country");
The first parameter of the query is database definition. The arguments are:
The second parameter of the query is a source definition. It may be join of tables or whatever, but here it is just a table name. In the real world, I define database parameters (instantiate DBLDBDef class) in the header and store it in a global variable, so the above call is just:
     $q =& new DBLMYSQLQuery($DBDEF,"country");
This allows easy change of the database location. You may even want to create the query itself globally and only change its source. This eases moving to another database engine (MySQL/Postgres). However, there are several cases where you need to create another queries (lookup fields discussed in further examples), so this is not a complete solution.

We are finished with definitions.

Creating record index

In this part, we will create a script that will print out record index.

At the beginning, you have to do three things:
  1. Start session (session_start()), if you want to use filters/paging (this is usually required for authentication too). This should be first, since starting a session may send cookies.
  2. Include header.php
  3. Start HTML page (<HTML>, header, <BODY> ...)
I usually construct header.phpso that it itself includes global definitions.

Since we want the records to appear in some order, we will set it now:
    $q->setOrder("name");
And finally, we will print the record index:
    $view->index($q,$indexFormat);
That's all. Just two calls :-) Of course, now you need to somehow generate page footer. Usually hyperlink somewhere "up in the application" and HTML code end.

Creating edit form

Now we come to editing the form. Here we will create one script, which will print edit form and also processed posted data (creating a new record or modifying an existing one). This is useful in the case that there is an error in the entered data. The error message can be printed above the form and then the form with the entered data can be displayed, so user is able to correct them immediatelly.

This script is also very simple. First we have to include view definition:
<?
  require('header.php');
Then we just call:
  $view->standardEdit($q,$editFormat,$HTML_HEADER);
First two arguments are easy. They are a query and edit format descrption.

The third argument is a path to a file (here it is shown as if it was contained in a global variable). This file may be either HTML, or PHP. Its purpose is to generate HTML page startup (<HTML>, header, <BODY> ...). The edit.php script may not include this directly. It is because after an edit form is posted, two cases make take place:
In the first case, HTML page must not be started for the redirect to proceed. However, in the second case, the page must be started. To accomplish this, the method is given path to a header file. If it is to output something, it includes (by the PHP includefunction) the given header file. That's it.

Finally, we have to somehow finish the page, for example by:

?>
</BODY>
</HTML>

Deleting records

We also need to provide a way to delete a record. Default references will lead to a delete.php script. You can do it like this:
<?
  require('header.php');
Include a header.
  $q->addCondition("id","=",intval($_GET["id"]));
Setup filter/condition on the query so that only the record with the ID passed as a parameter is used. (NOTE: You need not to do intval() here, since the query class will escape the values correctly. But I am used to use it everywhere :-) It's safer. )
  $q->deleteRecord();
Delete the record.
Header("Location: ./");
?>
Redirect to a record index.

NOTE: Actual delete.php in the example directory does also check for existance of the master record. This is discussed in the next chapter.

Finally

Now you may try to point your browser to the example and look, how the code works. Also try to create a record with an empty name. First, try it with javascript turned on in your browser, then turn it off and try again. You will see, how the automatic consistency control in DBLIB works.

Also try creating more records (>30) to see how automatic record index paging works.

<< Previous chapter
Chapter index
Next chapter >>