Use of MySQL persistent connection in ZF2 - php

On ZF2 I need to use a persistent MySQL connection and reconnect and the MySQL is gone away.
But I can not figure out where I should activate the MYSQL_OPT_RECONNECT parameter.
My db adapters are definied as follow:
'db' => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=DB_NAME;host=HOST',
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\'',
),
'username' => 'LOGIN',
'password' => 'PWD',
),
I have tried things like :
'db' => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=DB_NAME;host=HOST',
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\'',
'AUTO_RECONNECT_ON_UNSERIALIZE' => 1,
),
'options' => array(
'AUTO_RECONNECT_ON_UNSERIALIZE' => 1,
),
'username' => 'LOGIN',
'password' => 'PWD',
),
and nothing works.
How to make this mysql_options(&mysql, MYSQL_OPT_RECONNECT, &reconnect);
happen somewhere ?

Ok, the answer is :
'db' => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=DB_NAME;host=HOST',
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\'',
),
'options' => array(
PDO::ATTR_PERSISTENT => true',
),
'username' => 'LOGIN',
'password' => 'PWD',
),
But the use of persistant connection might not be a good fit for every one so you can also catch any "Mysql Server Gone Away Error" and proceed to a reconnect via :
$this->tableGateway->getAdapter()->getDriver()->getConnection()->disconnect();
$this->tableGateway->getAdapter()->getDriver()->registerConnection($this->getAdapter()->getDriver()->getConnection()->connect());
if($this->tableGateway->getAdapter()->getDriver()->getConnection()->isConnected()) {
return true;
}

Related

Zend 2 Framework Multiple Databases

I trying to configure several database connection in my global.php file. I followed this tutorial ( https://samsonasik.wordpress.com/2013/07/27/zend-framework-2-multiple-named-db-adapter-instances-using-adapters-subkey/#comments ) and was able to access the databases over the servicemanager
Now it looks like
//config/autoload/global.php
return array(
'db' => array(
//this is for primary adapter....
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=zf21_learn;host=localhost',
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
),
//other adapter when it needed...
'adapters' => array(
'db1' => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=zf2_staging;host=localhost',
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
),
),
'db2' => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=zf2_test;host=localhost',
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
),
),
),
),
'service_manager' => array(
// for primary db adapter that called
// by $sm->get('Zend\Db\Adapter\Adapter')
'factories' => array(
'Zend\Db\Adapter\Adapter'
=> 'Zend\Db\Adapter\AdapterServiceFactory',
),
// to allow other adapter to be called by
// $sm->get('db1') or $sm->get('db2') based on the adapters config.
'abstract_factories' => array(
'Zend\Db\Adapter\AdapterAbstractServiceFactory',
),
),
);
Now i can access the primary db by $sm->get('Zend\Db\Adapter\Adapter')
and db1 by $sm->get('db1') in the controller.
Now my question : Is it possible to load all adapters in a array so i can loop through them and pic the one i need.

SSL encrypted ZF2 PDO connection to Mysql

Is it possible to make an SSL encrypted connection via ZF2 to my MySql Server?
And if yes, how is it possible?
I can't find anything for ZF2 PDO SSL connection on the web.
return array(
'db' => array(
'adapters' => array(
// The first (default) database connection
'zf2' => array(
'driver' => 'pdo',
'dsn' => 'mysql:dbname=zf2;host=sandbox-db-vm',
'username' => 'root',
'password' => 'password',
),
// Now the second database connection
'zf2ssl' => array(
'driver' => 'pdo',
'dsn' => 'mysql:dbname=zf2;host=sandbox-db-vm',
'username' => 'ssl_user',
'password' => 'ssl_test',
PDO::MYSQL_ATTR_SSL_KEY => '/etc/mysql-ssl/client-key.pem',
PDO::MYSQL_ATTR_SSL_CERT => '/etc/mysql-ssl/client-cert.pem',
PDO::MYSQL_ATTR_SSL_CA => '/etc/mysql-ssl/ca-cert.pem'
),
),
),
'service_manager' => array(
// Let's make sure our adapters get instantiated
'abstract_factories' => array(
'Zend\Db\Adapter\AdapterAbstractServiceFactory',
),
),
);

zend framework 2 and sqlserver driver issues

when i try connecting to my sql server database from my zf2 application as shown below,
return array(
'db' => array(
'driver' => 'Pdo',
'dsn' => 'sqlsrv:dbname=album;hostname=192.168.0.20',
'username' => 'user',
'password' => 'pass',
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
),
),
'service_manager' => array(
'factories' => array(
'Zend\Db\Adapter\Adapter' => 'Zend\Db\Adapter\AdapterServiceFactory',
),
),
);
I get this error,
File:
/usr/local/zend/apache2/htdocs/zf2-tutorial/vendor/zendframework/zendframework/library/Zend/Db/Adapter/Driver/Pdo/Connection.php:289
Message:
Connect Error: could not find driver
Am i missing something here? Or rather this does not work at all on the linux oriented machines ?
Try taking out this line: "// PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''".
Your connection say you are trying to connect to MSSQL and not MySQL.
return array(
'db' => array(
'driver' => 'Pdo',
'dsn' => 'sqlsrv:dbname=album;hostname=192.168.0.20',
'username' => 'user',
'password' => 'pass',
'driver_options' => array(
// PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
),
),
'service_manager' => array(
'factories' => array(
'Zend\Db\Adapter\Adapter' => 'Zend\Db\Adapter\AdapterServiceFactory',
),
),
);
I always prep it like this without trouble, using dist files to set the right connection params as you work through deployment:
local config file
'database' => array(
'connection' => array(
'mysql_master' => array(
'driver' => 'Pdo_Mysql',
'host' => 'host',
'dbname' => 'analytics',
'username' => 'user',
'password' => 'pass',
'charset' => 'UTF8',
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'UTF8'",
),
),
),
),
Then in my Module.php, I define such a factory (in the getServiceConfig array):
'Zend\Db\Adapter\Adapter' => function ($sm){
$config = $sm->get('config');
$dbParams = $config['database']['config']['mysql_master'];
$adapter = new \Zend\Db\Adapter\Adapter($dbParams);
return $adapter;
},
Hope this helps. If this doesn't work, something else is going on.. let me know, I can help.
Cheers.
Alex
The problem is that you don't have the necessary driver installed. I had the same problem with postgres, and this solved it for me:
apt-get install php5-pgsql
However, I am not 100% sure what driver must be installed to make Sql Server work. I did read that it's no longer supported. See this: PHP PDO to MS SQL Server on Ubuntu Server. In a nutshell, your best bet is to rather use:
sudo apt-get install php5-sybase
and then connection string:
"dblib:host=sever;dbname=dbname"
From what I gather, that should connect you to a Sql Server database, but again, I can't gaurantee this because I don't have a setup to test it with. Hope that helps...
I hope this helps you some... I'm currently following along to the Zend Framework 2 skeleton application guide. My database parameters needed to be passed in the following way:
'db' => array(
'driver' => 'SQLSRV',
'hostname' => 'SqlServerName',
'Database' => 'SqlDatabaseName',
'uid' => 'UsertoConnectwith',
'pwd' => 'Passwordofusertoconnectwith'
),

Zend Framework 2 - Database connection

Trying to wrap my head around the new concepts of Zend Framework 2.0.
I'm trying to connect to a database, and to get that connection in a controller or model.
Nothing fancy, just the pure connection to run queries against.
So this is my current code:
//module.config.php
return array(
'db' => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=DBNAME;host=HOSTNAME,
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
),
'username' => 'USERNAME',
'password' => 'PASSWORD',
),
'service_manager' => array(
'factories' => array(
'translator' => 'Zend\I18n\Translator\TranslatorServiceFactory',
'Zend\Db\Adapter\Adapter' => 'Zend\Db\Adapter\AdapterServiceFactory',
),
),
);
What am I doing wrong?
Create db.local.php in your ./config/autoload folder and add the following content
return array(
'db' => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=zenBlog;host=localhost',
'username' =>'root',
'password' =>'',
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
),
),
'service_manager' => array(
'aliases' => array(
'db' => 'Zend\Db\Adapter\Adapter',
),
),);
in your controller $this->getServiceLocator()->get('db'); to access to database.
This is how my local.php in config\autoload\local.php looks like.
<?php
return array(
'db' => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=<dbname>;host=localhost',
'username' => 'root',
'password' => <your password here>,
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
),
),
'service_manager' => array(
'aliases' => array(
'adapter' => 'Zend\Db\Adapter\Adapter',
),
),);
Now use this to create a database adapter:
$adapter = $this->getServiceLocator()->get('adapter');
Create a sql statetment and put in variable $sql.
Now do this:
$statement = $adapter->createStatement($sql);
$result = $statement->execute();
Hope this helps.

configure multiple databases in zf2

How can I configure (and use) multiple databases in Zend Framework 2? Currently I have this in my global.php:
return array(
'db' => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=my_db;host=localhost',
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
),
'username' => 'user',
'password' => '******',
),
'service_manager' => array(
'factories' => array(
'Zend\Db\Adapter\Adapter' => 'Zend\Db\Adapter\AdapterServiceFactory',
),
),
);
But I do not see a way to add a second one.
If you look at the Zend\Db\Adapter\AdapterServiceFactory, you'll see that your adapter configuration points to only one key 'db'. Which means that the Adapter that it builds will always use this (unique) configuration key.
I recommend you to create your own factory that would look like this :
namespace Your\Namespace;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\Db\Adapter\Adapter;
class MyAdapterFactory implements FactoryInterface
{
protected $configKey;
public function __construct($key)
{
$this->configKey = $key;
}
public function createService(ServiceLocatorInterface $serviceLocator)
{
$config = $serviceLocator->get('Config');
return new Adapter($config[$this->configKey]);
}
}
In your main module (or any other one), add the following to the Module.php file to declare the adapters factories to the Zend Service Manager:
use Your\Namespace\MyAdapterFactory;
use Zend\ModuleManager\Feature\ServiceProviderInterface;
class Module implements ServiceProviderInterface{
//Previous code
public function getServiceConfig()
{
return array(
'factories' => array(
'myadapter1' => new MyAdapterFactory('dbconfigkey1'),
'myadapter2' => new MyAdapterFactory('dbconfigkey2'),
),
);
}
//...
The global config should now look like:
return array(
'dbconfigkey1' => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=my_db;host=localhost',
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
),
'username' => 'user',
'password' => '******',
),
'dbconfigkey2' => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=my_db2;host=localhost',
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
),
'username' => 'user',
'password' => '******',
),
);
to use the adapters you need to call them using the Service Manager:
$adapter1=$serviceManager->get('myadapter1');
$adapter2=$serviceManager->get('myadapter2');
As of version 2.2
An Abstract Service Factory is now part of the zf2 Zend\Db module. It is possible to add multiples configuration keys under the 'adapters' sub-key :
'db'=> array(
'adapters'=>array(
'adapter' => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=test;host=localhost',
'username' => 'readCredential',
'password' => '****'
),
'adapter2' => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=test;host=localhost',
'username' => 'rwCredential',
'password' => '****'
),
)
),
However, the AbstractServiceFactory need to be added "manually" as it isn't so by default :
'service_manager' => array(
'abstract_factories' => array(
'Zend\Db\Adapter\AdapterAbstractServiceFactory',
)
),
The adapters are accessible as previously :
$adapter1=$serviceManager->get('adapter');
$adapter2=$serviceManager->get('adapter2');
From a performance perspective this second approach is better : One object will be instantiated (The abstract factory) to (potentially) create the different adapters. Whereas in the previous approach, one object per configuration was created.
I found much better explaination on https://samsonasik.wordpress.com/2013/07/27/zend-framework-2-multiple-named-db-adapter-instances-using-adapters-subkey/
Zend Framework 2.2 comes with abstract_factories Zend\Db\Adapter\AdapterAbstractServiceFactory that allow us to configure multiple named DB adapter instances. This is step by step to do it :
Register Zend\Db\Adapter\AdapterAbstractServiceFactory at ‘abstract_factories’ type under ‘service_manager’ key.
//config/autoload/global.php
//.... part of config/autoload/global.php
'service_manager' => array(
'abstract_factories' => array(
'Zend\Db\Adapter\AdapterAbstractServiceFactory',
),
),
Configure ‘adapters’ subkey under ‘db’ key at config/autoload/global.php
//config/autoload/global.php
//.... part of config/autoload/global.php
'db' => array(
'adapters' => array(
'db1' => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=zf2_staging;host=localhost',
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
),
),
'db2' => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=zf2_test;host=localhost',
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
),
),
),
),
Configure ‘adapters’ subkey under ‘db’ key at config/autoload/local.php
//config/autoload/local.php
return array(
'db' => array(
'adapters' => array(
'db1' => array(
'username' => 'root',
'password' => '',
),
'db2' => array(
'username' => 'other_user',
'password' => 'other_user_passwd',
),
),
),
);
Call adapter using ‘db1’ or ‘db2’ as db adapter from ServiceManager
$sm->get('db1');
$sm->get('db2');
If you need to get $sm->get(‘Zend\Db\Adapter\Adapter’) as primary adapter, ‘db1’ and ‘db2’ as other adapter for specific purpose, then you need to define primary adapter directly under db, so the configuration of config/autoload/global.php will be like the following :
//config/autoload/global.php
return array(
'db' => array(
//this is for primary adapter....
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=zf21_learn;host=localhost',
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
),
//other adapter when it needed...
'adapters' => array(
'db1' => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=zf2_staging;host=localhost',
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
),
),
'db2' => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=zf2_test;host=localhost',
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
),
),
),
),
'service_manager' => array(
// for primary db adapter that called
// by $sm->get('Zend\Db\Adapter\Adapter')
'factories' => array(
'Zend\Db\Adapter\Adapter'
=> 'Zend\Db\Adapter\AdapterServiceFactory',
),
// to allow other adapter to be called by
// $sm->get('db1') or $sm->get('db2') based on the adapters config.
'abstract_factories' => array(
'Zend\Db\Adapter\AdapterAbstractServiceFactory',
),
),
);
The config/autoload/global.local.php should be configured too like the following :
//config/autoload/local.php
return array(
'db' => array(
// for primary db adapter that called
// by $sm->get('Zend\Db\Adapter\Adapter')
'username' => 'root',
'password' => '',
// to allow other adapter to be called by
// $sm->get('db1') or $sm->get('db2') based on the adapters config.
'adapters' => array(
'db1' => array(
'username' => 'root',
'password' => '',
),
'db2' => array(
'username' => 'other_user',
'password' => 'other_user_passwd',
),
),
),
);

Categories