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/ -> Db/ -> Adapter/ -> ... -> Php/ -> Sqlite.php, Mysql.php, Mssql.php, Oci8.php, Pgsql.php -> Db.php -> ...
p. Done ? Good! ![]()
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!
Categories: Tutorials, Zend Framework
Tags: Database, MDB2, MySQL, Object Oriented Programming, PDO, PEAR, Zend_Db


16 comments to “Tutorial : Using Zend Framework Without PDO”
February 23rd, 2007 at 3:18 am
we have noticed a problem in the describetable and zend_db_table about primary keys. I’ll try to address the problem as soon as possible.
Thanks for understanding
-D
April 30th, 2007 at 4:19 pm
Any thoughts on expanding what you’ve got here to include the IBM DB2 extension.
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
June 16th, 2007 at 11:06 am
hello David Coallier, i’ve tested your work with the new zend frmk rc2 but it doesn’t work, because zend_loader and other mod…
Do you plan to make a new version for the new zend frmk ?
June 16th, 2007 at 11:07 am
hello David Coallier, i’ve tested your work with the new zend frmk rc2 but it doesn’t work, because zend_loader and other mod…
Do you plan to make a new version for the new zend frmk ?
July 6th, 2007 at 8:02 pm
Everything has been fixed in SVN in order to work with RC2 and we are building tests. As soon as those are done, I’ll release
Thanks for your interest.
August 29th, 2007 at 3:13 pm
Hi, David,
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
October 17th, 2007 at 3:44 am
this is a fix I have come up with that will allow fetchAll to correctly join dependant parent tables, so that fetchAll in fact bring back all related parent tables as it would in a normal LEFT JOIN query – the ZPDataJoiner can obviously be refined a lot more.
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 ‘ => ”
));
}
January 6th, 2008 at 8:50 am
BTW guys I just put up a new release which should make it compatible with 1.0.z.
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,
January 6th, 2008 at 8:52 am
Link to release: http://dev.agoraproduction.com/zend/releases/Php-0.3.0.tar.gz
January 10th, 2008 at 5:41 pm
Seems your Db.php is not compatible with ZF 1.0.x. I did not find a new version within you Php-0.3.0.tar.gz file. Or am I missing something?
March 17th, 2008 at 3:20 pm
As I see you just forgot add function
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!
June 20th, 2008 at 5:56 am
Great stuff!!
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
)
October 17th, 2008 at 12:54 am
OK, that was fun – heh.
I’ve managed to (so far) get simple "fetchAll" working with Zend 1.6.1.
Here’s what I had to do:
All changes within db.php
Replace:
/**
* Zend
*/
require_once ‘Zend.php’;
/**
* Zend_Db_Exception
*/
require_once ‘Zend/Db/Exception.php’;
With:
/**
* @see Zend_Loader
*/
require_once ‘Zend/Loader.php’;
Add:
/**
* Use the INT_TYPE, BIGINT_TYPE, and FLOAT_TYPE with the quote() method.
*/
const INT_TYPE = 0;
const BIGINT_TYPE = 1;
const FLOAT_TYPE = 2;
… to the top of the Zend_Db declaration.
Replace:
Zend::loadClass($adapterName);
With:
@Zend_Loader::loadClass($adapterName);
Now I’ve only been working with this for about 30 minutes, I’m going against MySQL, so I have no idea if there are other gotchas waiting.
But at least I can now have Zend DB in an environment where MySQLi and PDO are not enabled. Thanks! (I hope you confirm/update the code soon.)
January 6th, 2009 at 12:36 am
I have been in a situation where I have had to preserve several straight-sql non mysqli calls to maintain a codebase and used your classes to get by for a while.
I have had to patch many, many incompatibilities — one of the most orerous was the fact that Zend quotes its references, as in "Users"."first_name", which took a ton of regex to patch.
Further the Zend_Db_Adapter interface has many methods — fetchPair, FetchAssoc, etc., which are not supported here. (they require fetch() calls to objects that do not have them.
Its my opinion that while this is a well intended hack that serves you for a while, on a project with a significant lifespan you are more likely to save time by converting to mysqli or pdo_mysql (or any of the other zend-supported drivers) and mutate your code to work with the supported Zend libraries, than you are to use this library.
I appreciate the work you put in to meld these two codebases, but the work is incomplete, and you are really buying into a terminal path by using this library.
June 3rd, 2009 at 10:04 am
Dear David!
Your link http://dev.agoraproduction.com/zend/ isn’t opening, can You or someone who downloaded that PHP adapters put it to mirror?
Thank You!
March 13th, 2010 at 12:05 pm
SELECT * FROM emp WHERE ename=’smith’ AND id=520
please tell me how to implement this qury in zend frame work