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 (Login to leave 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)
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.)
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.
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!
please tell me how to implement this qury in zend frame work