功能非常棒。赶快下载使用吧:
Firefox的Performancing插件下载地址
While we are not going to go as far as developing a database independent version of SQL, the new features of PHP 5 will be us build a consistent database API with support for stored procedures (where it is not already present). This will then make switching from one database system to another as painless as changing one line of code.
The first features new to PHP 5 to be covered in this article are abstract classes and interfaces. These concepts are nothing more than features added to OOP, which help the programmer follow good coding standards.
An abstract class is a class that is only partially implemented by the programmer. It may contain one or more abstract methods. An abstract method is simply a function definition that serves to tell the programmer that the method must be implemented in a child class.
To create an abstract class we use the code shown in Listing 1:
Listing 1: An Abstract PHP class
abstract class Weapon
{
private $SerialNumber;
abstract public function fire();
public function __construct($SerialNumber)
{
$this->SerialNumber = $SerialNumber;
}
public function getSerialNumber()
{
return $this->SerialNumber;
}
}
?>
The abstract class in Listing 1 contains some of the methods required for a weapon. The fire() method however, cannot be implemented because each different weapons use different firing different mechanisms. The method is therefore declared as abstract, meaning it will be implemented in a more specific child class.
Because the class is abstract, an instance of it can never be created (remember, it is only a partial implementation). Instead a child class must be created using inheritance and implement the fire method in itself. Failure to do so will result in a fatal error. Listing 2 shows a child class being created from the Abstract Weapon class.
Listing 2: Extending the Abstract Weapons class
class Gun extends Weapon
{
public function fire()
{
if($this->SafetyOff) {
return $this->CurrentBullet;
}
}
}
class Cannon extends Weapon
{
public function fire()
{
$this->NeedsLoading = true;
return $this->CurrentCanon;
}
?>
An instance of the Cannon and Gun classes can now be created because they now fully implemented subclasses of weapon.
An interface is similar to an abstract class; indeed interfaces occupy the same namespace as classes and abstract classes. For that reason, you cannot define an interface with the same name as a class. An interface is a fully abstract class; none of its methods are implemented and instead of a class sub-classing from it, it is said to implement that interface.
An interface will be used in the database abstraction layer you create. This ensures that every time you create a class for a particular database, the same API is exposed. When using an interface, you can then rely on the methods defined for the interface to be part of the class because, if they are not, PHP will not parse it.
The MySql functions will be used as an example because they are the most commonly used amongst PHP programmers. The most commonly used functions are:
If all the database class APIs you create can expose the same methods with the same return types then you can be sure that changing from one database to another, such as from MySql to Postgre SQL, will be painless. As such, the interface in listing 3 can be determined for your API.
Listing 3: An Abstracted Database Interface
interface DB
{
public function connect();
public function error();
public function errno();
public static function escape_string($string);
public function query($query);
public function fetch_array($result);
public function fetch_row($result);
public function fetch_assoc($result);
public function fetch_object($result);
public function num_rows($result);
public function close();
}
Notice how the escape_string() method is included as a static method. This method does not require an active connection to a database and should not require and instance of any object which implements the DB interface. In my opinion, this is the single most important method of any database implementation; a poorly implemented escape string method could make your applications vulnerable SQL injection.
Listing 4: Implementing the database interface
class MySqlDB implements DB
{
private $link;
public function connect($server='', $username='', $password='', $new_link=true, $client_flags=0)
{
$this->link = mysql_connect($server, $username, $password, $new_link, $client_flags);
}
public function errno()
{
return mysql_errno($this->link);
}
public function error()
{
return mysql_error($this->link);
}
public static function escape_string($string)
{
return mysql_real_escape_string($string);
}
public function query($query)
{
return mysql_query($query, $this->link);
}
public function fetch_array($result, $array_type = MYSQL_BOTH)
{
return mysql_fetch_array($result, $array_type);
}
public function fetch_row($result)
{
return mysql_fetch_row($result);
}
public function fetch_assoc($result)
{
return mysql_fetch_assoc($result);
}
public function fetch_object($result)
{
return mysql_fetch_object($result);
}
public function num_rows($result)
{
return mysql_num_rows($result);
}
public function close()
{
return mysql_close($this->link);
}
}
?>
You'll notice that there are many more mysql functions than methods that are adapted in the interface in listing 3. However, this small subset of functions is sufficient to meet the needs of most applications requiring trivial data storage and retrieval. The additional functions can be implemented and I have done this in the attached example file, you may also choose to add additional functionality to the class and the interface.
Listing 5: Creating a database class
$db = new MySqlDb;
$db->connect('host', 'username', 'password');
$db->query('use users'); // we could also use $db->select_db here but it is not consistent with the interface
$result = $db->query("SELECT username FROM users");
while($row = $db->fetch_assoc($reuslt))
{
echo($row['username']);
}
As shown in listing 5, you can now create a class for each database you want and as long as it implements the DB interface, switching from one to another is as easy as changing one line of code:
$db = new MsSqlDb;
In this first article, you've seen how to create an abstraction layer to access a database. Using this, you saw how creating an interface helps you to isolate your application so that you can easily switch from one database to anther without rewriting your own applications.
Future Features
These are features that should eventually make it into this plugin
* Allow different "include" file on each runner (override the "master" include)
* Handle fatal errors better
(Page 1 of 2, totaling 20 entries)