Tutorial : Using Zend Framework Without PDO
This is a very quick tutorial on how to allow developers to develop using the Zend Framework without having to or being able to install PDO on their servers.
I have to warn you though, this is not an official extension of the Zend Framework just yet.
Anyway, let's get rolling as a lot of you are very anxious and happy about that.
About:
This is a merge of PEAR (http://pear.php.net) and the Zend Framework (http://framework.zend.com) in order to give the ability to everyone to be able to connect to as many databases as possible with the Zend_Db database layer.
Quickly, that is a way to connect to may different databases having the same api than the normal Zend_Db without PDO (Pecl) but only PHP.
But..but .. How?!:
Well first of all you need to go to http://dev.agoraproduction.com/zend/ and get the latest Php-x.y.z.tar (At the time of this tutorial (Php-0.1.0.tar)) and get the Db.php file.
Once you are done with this, you will untar the Php-x.y.z.tar and place the Php/ directory into
Zend/Db/Adapter/
(So it looks like Zend/Db/Adapter/Php/ )
After this, you have to replace the current Zend/Db.php with the one I have provided. If you are scared of doing so, it is very understandable and you can refuse to do it, but the drivers won't work. The only thing I added in the Zend_Db class is an elseif to handle the new driver calling (I will show later).
Are you done ? So now you directory structure should look like this:
Zend/p. Done ? Good! :-)
-> Db/
-> Adapter/
-> ...
-> Php/
-> Sqlite.php, Mysql.php, Mssql.php, Oci8.php, Pgsql.php
-> Db.php
-> ...
Supported Databases:
There are currently 5 different RDBMS supported
- MySQL (Zend/Db/Adapter/Php/Mysql.php)
- MsSQL (Zend/Db/Adapter/Php/Mssql.php)
- PostgreSQL (Zend/Db/Adapter/Php/Pgsql.php)
- Oracle (Oci8) (Zend/Db/Adapter/Php/Oci8.php)
- Sqlite (Zend/Db/Adapter/Php/Sqlite.php)
How to call them:
I have tried to make this as easy as possible.. do you remember how to do it usually with PDO ?
<?php
/**
* This is the PDO way. Please notice the PDO_MYSQL
*/
require_once 'Zend.php';
require_once 'Zend/Db.php';
$config = array(
'host' => 'localhost',
'username' => 'sqluser',
'password' => 'sqlpass',
'dbname' => 'databasename',
);
$db = Zend_Db::factory('PDO_MYSQL', $config);
print_r($db->fetchAll("SELECT * FROM tablename"));
print_r($db->fetchRow("SELECT rowname FROM tablename"));
// .. etc.
?>
You noticed the PDO_MYSQL right ? Well the only thing one has to do in order to use the php only drivers is use PHP_MYSQL, PHP_OCI8, PHP_PGSQL, PHP_SQLITE.
Example:
<?php
/**
* This is the PHP (No pdo) way. Please notice the PHP_MYSQL
*/
require_once 'Zend.php';
require_once 'Zend/Db.php';
$config = array(
'host' => 'localhost',
'username' => 'sqluser',
'password' => 'sqlpass',
'dbname' => 'databasename',
);
$db = Zend_Db::factory('PHP_MYSQL', $config); // Here!!!! it happened here!
print_r($db->fetchAll("SELECT * FROM tablename"));
print_r($db->fetchRow("SELECT rowname FROM tablename"));
// .. etc.
?>
So yes, basically it's the same thing you have to do.
Current working functions:
- fetchAll
- fetchOne
- fetchRow
- fetchCol
- query
- update
- insert
- describeTable
- listTables
- setFetchMode (Has to be adjusted to ZF)
- quote (MDB2::escape())
- And other functions are to come later as I am implementing them.
About me:
No one really wants to read that right? Here's my blog: http://blog.agoraproduction.com
David Coallier (davidc@agoraproduction.com)
Enjoy! :)

Comments
Thanks for understanding :)
-D
PDO_ODBC will not work on the i5/os and I'm stumped as to how I would use the Zend Framework here to access DB2. I can't be the only one.
Jeff
Do you plan to make a new version for the new zend frmk ?
Do you plan to make a new version for the new zend frmk ?
Thanks for your interest.
Thanks for the tutorial first. It's very useful. However, I didn't get your code work with my ZF1.0.1 application. Does it support version 1.0.1? I went to your blog and tried to get the latest code from http://dev.agoraproduction.com/zend/. But the svn directory cannot be accessed. It says "Technical difficulties, runnnig on zend framework has its downside...".
Looking forward to your reply.
Dix Mars
How to: create a class file from the below and include it in your table model class file, then instead of extending your table class with Zend_Db_Table_Abstract extend it with ZPDataJoiner, this will override the fetchAll() of Zend_Db_Table_Abstract.
require_once 'Zend/Db/Table/Abstract.php';
class ZPDataJoiner extends Zend_Db_Table_Abstract{
public function fetchAll($where = null, $order = null, $count = null, $offset = null) {
$select = $this->_db->select();
$select ->from(array('thistable' => $this->_name))
->order($order)
->limit($offset, $count);
if (!is_null($where)) {
$select->where($where);
}
if (!empty($this->_referenceMap)) {
foreach($this->_referenceMap as $ruleName => $specs) {
if (isset($specs['columns']) && isset($specs['refColumns']) && isset($specs['refTableClass'])) {
if(isset($this->parentTables[$specs['refTableClass']])){
// echo $specs['columns'].'<hr>';
$parTable = $this->parentTables[$specs['refTableClass']];
$parAlias = $ruleName;
$select->joinLeft(array($parAlias => $parTable),
'thistable.'.$specs['columns'].' = '.$parAlias.'.'.$specs['refColumns'],array('*'));
}
}
}
}
//$select->toString(); return false;
$stmt = $select->query();
$data = array(
'table' => $this,
'data' => $stmt->fetchAll(Zend_Db::FETCH_ASSOC),
'rowClass' => $this->_rowClass,
'stored' => true
);
//print_r($data['data']);
Zend_Loader::loadClass($this->_rowsetClass);
return new $this->_rowsetClass($data);
}
}
//example model class
class Cities extends ZPDataJoiner{
protected $_primary = array('city_id');
protected $_name = 'cities';
protected $_dependentTables = array('departments','staff');
/*the $parentTables is important array(tableclass=>actual_table_name)
it is used by ZPDataJoiner to resolve relationships
and I was to lazy to write a lookup that could use only the
$_referenceMap
*/
protected $parentTables = array('Countries'=>'countries');
protected $_referenceMap = array(
'CitiesToCountries' => array(
'columns' => 'country_id',
'refTableClass' => 'Countries',
'refColumns' => 'country_id',
'onDelete' => '',
'onUpdate ' => ''
));
}
I also have put the webSVN back up (http://dev.agoraproduction.com/zend/svn)
Let me know if it's ok, in theory it should be.
Thanks,
public function getQuoteIdentifierSymbol()
{
return '`';
}
to php/Mysql.php file.
By default I we got a ".
Anyway thank you, with this fix all works super!! cool!
But it seems the current release dosn't work with the ZF 1.5. Can you please fix this, so new ZF users can use this great piece of code :o)