Initially, I started to develop a web application using Zend Framework 2 and Doctrine2 with MySQL but the customer wants that the database would be Oracle. So, I have to change the database from MySQL to Oracle.
To do that, I have modified my doctrine.local.php file from this version
return array(
'doctrine' => array(
'connection' => array(
'orm_default' => array(
'driverClass' =>'Doctrine\DBAL\Driver\PDOMySql\Driver',
'params' => array(
'host' => 'localhost',
'port' => '3306',
'user' => 'user_gnsys',
'password' => '******',
'dbname' => 'gnsys',
),
'doctrine_type_mappings' => array(
'enum'=>'string'
)
),
)
)
);
To this other version ...
return array(
'doctrine' => array(
'connection' => array(
'orm_default' => array(
'driverClass' => 'Doctrine\DBAL\Driver\OCI8\Driver',
'params' => array(
'host' => 'localhost',
'port' => '1521',
'dbname' => 'GNSYS',
'driver' => 'oci8',
'user' => 'c##gnsys',
'password' => '********',
'servicename' => 'demo31',
),
'doctrine_type_mappings' => array(
'enum'=>'string'
)
),
)
)
);
Next, I try to validate my schema using the next command:
josecarlos#R2D2:~/Workspace/Web/gnsys$ php public/index.php orm:validate-schema
And I've got the next exit ...
How can I remove all these "Notice" that I've got on the exit? Have I forget to update another file?
I fixed the problem installing oci8 library.
Related
I want to built Doctrine 2 into an Apigility Zend Framework 2 application.
Following Marco Pivetta's Doctrine ORM ZF2 Tutorial, I installed not only Doctrine, but also the Zend Developer Tools, like in the tutorial shown:
$ composer require doctrine/doctrine-orm-module
$ composer require zendframework/zend-developer-tools:dev-master
$ cp vendor/zendframework/zend-developer-tools/config/zenddevelopertools.local.php.dist config/autoload/zdt.local.php
// config/application.config.php
return array(
'modules' => array(
'Application',
...
'ZendDeveloperTools', // <-- added
'DoctrineModule', // <-- added
'DoctrineORMModule', // <-- added
),
// [...]
);
Now when I open the Apigility admin page, I get errors:
Fatal error: Uncaught exception 'Zend\Db\Adapter\Exception\InvalidArgumentException' with message 'createDriver expects a "driver" key to be present inside the parameters' in /var/www/myproject/vendor/zendframework/zendframework/library/Zend/ServiceManager/ServiceManager.php on line 909
Zend\Db\Adapter\Exception\InvalidArgumentException: createDriver expects a "driver" key to be present inside the parameters in /var/www/myproject/vendor/zendframework/zendframework/library/Zend/Db/Adapter/Adapter.php on line 262
Zend\ServiceManager\Exception\ServiceNotCreatedException: An exception was raised while creating "Zend\Db\Adapter\Adapter"; no instance returned in /var/www/myproject/vendor/zendframework/zendframework/library/Zend/ServiceManager/ServiceManager.php on line 909
Zend\ServiceManager\Exception\ServiceNotCreatedException: An exception was raised while creating "ZendDeveloperTools\DbCollector"; no instance returned in /var/www/myproject/vendor/zendframework/zendframework/library/Zend/ServiceManager/ServiceManager.php on line 909
The errors occur, when the zenddevelopertools.toolbar.enabled is set to true.
Here is the configuration in the /config/autoload/global.php:
return array(
'db' => array(
'adapters' => array(
'DB\\Customers' => array(),
'DB\\myproject_v1' => array(),
'DB\\myproject_v2' => array(),
),
),
'service_manager' => array(
'factories' => array(
'Zend\\Db\\Adapter\\Adapter' => 'Zend\\Db\\Adapter\\AdapterServiceFactory',
),
),
'zf-mvc-auth' => array(
...
),
);
and the /config/autoload/local.php looks like follows:
return array(
'db' => array(
'adapters' => array(
'DB\\Customers' => array(
'driver' => 'Pdo_Sqlite',
'database' => 'data/sqlite.db',
),
'DB\\myproject_v1' => array(
'driver' => 'Pdo_Mysql',
'database' => 'myproject_v1',
'username' => 'root',
'password' => 'pwd',
'hostname' => 'localhost',
'driver_options' => array(
1002 => 'SET NAMES \'UTF8\'',
),
),
'DB\\myproject_v2' => array(
'driver' => 'Pdo_Mysql',
'database' => 'myproject_v2',
'username' => 'root',
'password' => 'pwd',
'hostname' => 'localhost',
'driver_options' => array(
1002 => 'SET NAMES \'UTF8\'',
),
),
),
),
'zf-mvc-auth' => array(
...
),
);
I guess, the Zend Developer Tools cannot find an appropriate DB adapter.
Why are these errors occuring and how to ix them?
Additional info:
The db.service_manager.factories.Zend\\Db\\Adapter\\Adapter configuration in my global.php is actually needless, since I use custom DB adapters instead of the default one created by Zend\Db\Adapter\AdapterServiceFactory. Anyway the Zend Developer Tools seem to try to use it. So, when I copy the DB settings directly to db
return array(
'db' => array(
'adapters' => array(
...
'driver' => 'Pdo_Mysql',
'username' => 'root',
'password' => 'pwd',
'hostname' => 'localhost',
'database' => 'myproject_v1',
),
),
...
);
I get different errors:
Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[28000] [1045] Access denied for user 'username'#'localhost' (using password: YES)' in /var/www/myproject/vendor/zendframework/zendframework/library/Zend/ServiceManager/ServiceManager.php on line 1070
PDOException: SQLSTATE[28000] [1045] Access denied for user 'username'#'localhost' (using password: YES) in /var/www/myproject/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php on line 43
You are only showing Db configs. You need a Doctrine config something like this:
<?php
return array(
'doctrine' => array(
'connection' => array(
// default connection name
'orm_default' => array(
'driverClass' => 'Doctrine\DBAL\Driver\PDOMySql\Driver',
'params' => array(
'host' => 'localhost',
'port' => '3306',
'user' => 'username',
'password' => 'password',
'dbname' => 'database',
)
)
)
),
);
See https://github.com/doctrine/DoctrineORMModule/blob/master/README.md
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;
}
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',
),
),
);
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.
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',
),
),
),
);