If you're converting over to ZF1 from ZF2, there's quite a few subtleties to bridge.  Most of the docs are pretty clear, but I found some aspects of Zend_Db's successor to be a bit more obscure.  Zend_Db was a good friend, especially when came time to adopt query abstraction without going through table gateways.  It was so easy (probably sounding little spoiled now) to do then what I wanted to do now, which is wire a connection outside of Doctrine, in order to connect to an AWS Redshift Cluster (which is awesome by the way) to execute straight queries.

What I Used To Do, That I Wanted Anew

$DB = Zend_Db::factory
'host' => 'host',
'password' => $this->getDatabasePass(),
'username' => $this->getDatabaseUser(),
'dbname' => $this->getDatabaseName(),
'options' => array(

$S = $DB->select()->from( 'table', array( 'col1', 'col3' ) )
->where( 'col2=?', "O'Smith" )
->limit( 1 );
$R = $DB->fetchAll( $S );

You'll see below that things have taken a bit of a turn for the more complex. Reading the rationale in all the PRs on GitHub is a bit of a brain-bender, and when you use something like Doctrine for most of the day to day, this is probably a fringe-case thing.


Prepping The New Mistress (ZF2)

I first recommend that you wire your connection the ZF2 way.  I've got Doctrine2 already setup in my autoload configuration file -- just need to add a few lines for configuration's sake.



return array(
'doctrine' => array(
'connection' => array(
'orm_default' => array(
'driverClass' => 'Doctrine\DBAL\Driver\PDOMySql\Driver',
'params' => array(
'host' => 'host',
'port' => '3306',
'user' => 'user',
'password' => 'pass',
'dbname' => 'doctrine_mysql_db',
'redshift' => array(
'connection' => array(
'stats_default' => array(
'driver' => 'Pdo_Pgsql',
'host' => 'host',
'dbname' => 'analytics',
'username' => 'redshift_user',
'password' => 'redshift_pass',
'port' => 5439,
'charset' => 'UTF8'
You'll notice that I'm using Pgsql above, you may want to change if you're going to use MySQL for example - just need to change the driver string

This done, edit your Module config at the getServiceConfig() level to include a factory to dispatch the connection:


public function getServiceConfig() 
return array(
'factories' => array(
// it's this part that matters
'redshift_stats' => function ($sm) {
$config = $sm->get('config');

$dbc = $config['redshift']['connection']['stats_default'];
$adapter = new \Zend\Db\Adapter\Adapter( $dbc );
return new \Zend\Db\Sql\Sql( $adapter );
// end, part that matters

(your mileage may vary) 

Thusly is born the part that lets you do what's below, which is the equivalent to the first (I thought succinct!) ZF1 block we started with: 

$SQL  = $this->getServiceLocator()->get('redshift_stats');
$DBA = $SQL->getAdapter();
$S = $SQL->select()
->from( 'table' )
->columns( array( 'col1', 'col3' ) )
->where( array( "col2" => "O'Smith" ) )
->limit( 1 );

$sel_string = $SQL->getSqlStringForSqlObject($S);
$R = $DBA->query( $sel_string, $DBA::QUERY_MODE_EXECUTE );

Oh yea, fetchAll, fetchOne, and fetchPairs are all gone...  (I ran across a bridge on GitHub someone wrote to try to bridge this extricated functionality).


Insertion Queries

Inserts and updates work a bit differently with ZF2 as well.  The ZF1 insert and update would execute right away, you have to extract the string and execute it now.  This can be a gotcha as you get started

With Zend Framework 1

$DB = /* get your connection */;
$DB->insert( 'table', array( 'col1' => 123 ) );

With Zend Framework 2

$DB       = $this->getServiceLocator()->get('redshift_stats'); 
$ADAPTER = $SQL->getAdapter();
$I = $SQL->insert( 'table' );

$I->values( array( 'col1' => 123 ) );

$ins_string = $SQL->getSqlStringForSqlObject($I);
$results = $ADAPTER->query( $ins_string, $ADAPTER::QUERY_MODE_EXECUTE );

Concluding, I hope this helps you bridge the gap between the two.  By no means thorough, I just wanted to highlight the close-but-not-quite elements that would helped me get kickstarted.

The verbosity of it all, and Zend\Db's lack of support for batch inserts (yes I prefer MySQL) really makes adopting the likes of Doctrine2 worthwhile (I find the Mappers turn out cleaner overall).  I think this may have been the MO with ZF2, less ORM, more query abstraction -- please use something else like Doctrine2 for heavy -- scratch that -- usual lifting.