Home arrow PHP arrow Page 2 - Building Object-Oriented Database Interfaces in PHP: Updating the Application to PHP 5

Porting Database Interfaces to PHP 5: member visibility, exceptions and more - PHP

In this fourth and final article in the tutorial series, Alejandro Gervasio updates the "DBIGenerator" class developed in the previous articles. The new version incorporates features in PHP 5, such as member visibility, exceptions, and other useful items.

TABLE OF CONTENTS:
  1. Building Object-Oriented Database Interfaces in PHP: Updating the Application to PHP 5
  2. Porting Database Interfaces to PHP 5: member visibility, exceptions and more
  3. Using the class in a object-oriented scenario: the "try" and "catch" blocks
  4. Completing the round: updating and deleting rows
By: Alejandro Gervasio
Rating: starstarstarstarstar / 15
August 31, 2005

print this article
SEARCH DEV SHED

TOOLS YOU CAN USE

advertisement

Porting code developed in PHP 4 to PHP 5 is not really a difficult task. Since the new Zend 2 PHP engine maintains a good level of backward compatibility, the updating process shouldn't present major problems. However, when an object-oriented approach is implemented, things are a little bit different.

As you probably know, PHP 5 presents a highly improved Object Model, allowing you to declare the visibility of class members and methods as private, public or protected, nearly similar to the Java model, among other useful things. Besides, it incorporates Exceptions as a proven method for implementing error handling in object-oriented environments, which resembles the models present in other popular programming languages.

But here, I'm not going to take the long road by explaining these features in detail. If you want to learn more about them, the official PHP site is just one click away. Instead, I'll offer a brief explanation, which you will find useful for better understanding the ported code of the "DBIGenerator" class.

Well, having provided extensive examples of the use of this class in previous articles, let's take a look at its updated code, and then, in turn, spot the differences as compared to the prior version. Here's the ported class' code:

class DBIGenerator{
    private $table;
    private $name;
    private $path;
    public function __construct($table,$name='default_file.php',
            $path='DEFAULTPATH/'){
        $this->table=$table;
        $this->name=$name;
        $this->path=$path;
    }
    public function generate(){
        // build class header
        $str='<?php class '.$this->name.'{';
        if(!$result=mysql_query('SHOW COLUMNS FROM '.$this->table)){
            throw new Exception('Failed to run query');
        }
        // build data member declaration
        if(mysql_num_rows($result)<1){
            throw new Exception('Not available columns in table');
        }
        $methods='';
        while($row=mysql_fetch_array($result,MYSQL_ASSOC)){
            $str.='private $'.$row['Field'].'=\'\';';
            $methods.='public function set'.$row['Field'].'($'.$row
                 ['Field'].'){$this->'.$row['Field'].'=$'.$row
                 ['Field'].';}';
            $methods.='public function get'.$row['Field'].'(){return 
                 $this->'.$row['Field'].';}';
            // store field names in array
            $fields[]=$row['Field'];
        }
         // build empty constructor
        $str.='public function __construct(){}';
         // build modifiers and accessors
        $str.=$methods;
         // build load() method
        $str.='public function load(){$r=mysql_query("SELECT * FROM
                 '.$this->table.' WHERE id=\'$this->id\'");';
        $str.='return mysql_fetch_array($r,MYSQL_ASSOC);}';
        // build submit() method
        $str.='public function submit(){mysql_query("INSERT INTO '.$this-
                 >table.' SET ';
        foreach($fields as $field){
            $str.=($field!='id')?$field.'=\'$this->'.$field.'\',':'';
        }
        $str.='");$this->id=mysql_insert_id();';
        $str=preg_replace("/,\"/","\"",$str).'}';
        // build update() method
        $str.='public function update(){mysql_query("UPDATE '.$this-
                 >table.' SET ';
        foreach($fields as $field){
            $str.=($field!='id')?$field.'=\'$this->'.$field.'\',':'';
        }
        $str=preg_replace("/,$/","",$str);
        $str.=' WHERE id=\'$this->id\'");}';
        // build delete() method
        $str.='public function delete(){mysql_query("DELETE FROM '.
                 $this->table.' WHERE id=\'$this->id\'");}';
        $str.='}?>';
        // open or create class file
        if(!$fp=fopen($this->path.$this->name.'.php','w')){
            throw new Exception('Failed to create class file');
        }
        // lock class file
        if(!flock($fp,LOCK_EX)){
            throw new Exception('Unable to lock class file');
        }
        // write class code to file
        if(!fwrite($fp,$str)){
            throw new Exception('Error writing to class file');
        }
        flock($fp,LOCK_UN);
        fclose($fp);
        // delete temporary variables
        unset($fp,$str,$row,$fields,$field,$methods);
    }
    public function getObject(){
        // check if class file exists
        if(!file_exists($this->path.$this->name.'.php')){
            throw new Exception('Failed to include class file');
        }
        require_once($this->path.$this->name.'.php');
        // create data access object
        return new $this->name;
    }
}

At first glance, the above listed code presents some minor modifications. Of course, its functionality is the same, but there are several differences that need to be explained, at least for those developers making their first incursions in PHP 5.

The first thing to note is that each class member has been declared as private. This means that they cannot be accessed from outside the class. Any attempt to do so will result in a fatal error. Also, in a similar way, the "generate()" and "getObject()" methods are declared as public, so they can be accessed from outside.

While all of the methods that don't have a explicit visibility declaration are considered by default as public by the PHP interpreter, specifying its visibility helps to have a clearer idea about how they can be accessed in the context of an application.

Certainly, there are other differences that we'll explain briefly. As you can see, the constructor has been replaced with the "__construct()" function, which essentially performs the same task. Whenever an object is instantiated, this method will be executed automatically. However, PHP 5 still supports the traditional way of defining a class constructor, that is declaring a method that has the same name as that of the class.

In addition, the class uses Exceptions to handle basically any error condition, by throwing a new exception each time a potential error might occur. This mechanism has a significant advantage over the common "die()" or "trigger_error()" PHP functions, since it provides an efficient way to handle different runtime errors through a centralized mechanism, by delegating this responsibility to a specific method within the application. As a general rule, errors shouldn't be handled by the code that generated them. Once an exception has been thrown within the class, it may be caught by a "catch" statement, as we'll see shortly.

The last thing to highlight regarding the class is that the same features are applied to the dynamically generated database interface class. Notice that every respective method, "load()", "submit()", "update()" and "delete()", is created specifying their visibility, declared as public. Similarly, the constructor is defined as "__construct()" as well.

At this point, we've reviewed the most relevant changes made to the class, in order to work with the nice object features of PHP 5. Still interested in knowing more? All right. Keep reading to find out how the class can be set up to work in a PHP 5 controlled environment.



 
 
>>> More PHP Articles          >>> More By Alejandro Gervasio
 

blog comments powered by Disqus
escort Bursa Bursa escort Antalya eskort
   

PHP ARTICLES

- Hackers Compromise PHP Sites to Launch Attac...
- Red Hat, Zend Form OpenShift PaaS Alliance
- PHP IDE News
- BCD, Zend Extend PHP Partnership
- PHP FAQ Highlight
- PHP Creator Didn't Set Out to Create a Langu...
- PHP Trends Revealed in Zend Study
- PHP: Best Methods for Running Scheduled Jobs
- PHP Array Functions: array_change_key_case
- PHP array_combine Function
- PHP array_chunk Function
- PHP Closures as View Helpers: Lazy-Loading F...
- Using PHP Closures as View Helpers
- PHP File and Operating System Program Execut...
- PHP: Effects of Wrapping Code in Class Const...

Developer Shed Affiliates

 


Dev Shed Tutorial Topics: