Today I bought a book to learn the Zend Framework 2. Having started with the skeleton Application & skeleton module, I made good progress, until database interaction started. Now every time I want to do something with the database, I get the following exception:
Zend\ServiceManager\Exception\ServiceNotFoundException
File: /Applications/AMPPS/www/myproject/ZendSkeletonApplication/vendor/zendframework/zendframework/library/Zend/ServiceManager/ServiceManager.php:529
Message:
Zend\ServiceManager\ServiceManager::get was unable to fetch or create an instance for Zend\Db\Adapter\Adapter
Possible reasons for this could be incorrect database details, but having used the same credentials for other projects, I know they are correct (local development).
My global.php looks like this – I can't see any errors:
return array(
'db' => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=mydatabasename;host=localhost',
'username' => 'root',
'password' => 'mysql',
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
),
'service_manager' => array(
'factories' => array(
'Zend\Db\Adapter\Adapter' => 'Zend\Db\Adapter\AdapterServiceFactory'
),
),
)
);
Following the stacktrace, the error must be in the beginning of this method:
protected function createUser(array $data)
{
$sm = $this->getServiceLocator();
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$resultSetPrototype = new \Zend\Db\ResultSet\ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new \Users\Model\User);
$tableGateway = new \Zend\Db\TableGateway\TableGateway('user', $dbAdapter, null, $resultSetPrototype);
$user = new User();
$user->exchangeArray($data);
$userTable = new UserTable($tableGateway);
$userTable->saveUser($user);
return true;
}
But again, I can't see any error here, which leaves me a bit puzzled. I guess the error is more than just a typo.
The class that method is located in uses the following Zend Framework 2 components (besides self written ones):
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
Do I need to add something here, maybe to be able to use the getServiceLocator() method? I don't know there that method is located.
Do you have anymore ideas what could cause this exception? I am using Zend Framework 2.3.2
You have put the service_manager key as a subset to db. This is wrong.
The service_manager key needs to be top level.
return array(
'db' => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=mydatabasename;host=localhost',
'username' => 'root',
'password' => 'mysql',
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
),
),
'service_manager' => array(
'factories' => array(
'Zend\Db\Adapter\Adapter' => 'Zend\Db\Adapter\AdapterServiceFactory'
)
)
);
Related
I am new to mongodb. I am working on Zend framework. My zend application is currently connected to mysql. I want to connect it with mongodb. I have successfully created a mongodb database and a collection. Now I need to link it with my application? Any help will be appreciated.
/*return array(
'db' => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=zf2;host=localhost',
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
),
),
'service_manager' => array(
'factories' => array(
'Zend\Db\Adapter\Adapter'
=> 'Zend\Db\Adapter\AdapterServiceFactory',
),
),
);
*/
use Mongo;
use Zend\Session\SaveHandler\MongoDB;
use Zend\Session\SaveHandler\MongoDBOptions;
use Zend\Session\SessionManager;
$mongo = new Mongo();
$options = new MongoDBOptions(array(
'database' => 'posts',
'collection' => 'posts',
));
$saveHandler = new MongoDB($mongo, $options);
$manager = new SessionManager();
$manager->setSaveHandler($saveHandler);
While creating a mongo client in your app, provide the hostname and port.
That's all you need to connect to mongo :)
I have following in the configuration of a Zend project
'db' => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=food;host=localhost',
'username' => 'root',
'password' => '',
'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 am trying to get DB adapter
($adapter = $adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
( $adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
in a controller but is always stuck with.
class: "Zend\ServiceManager\Exception\ServiceNotCreatedException"
file:
" /path/vendor/zendframework/zendframework/library/Zend/ServiceManager/ServiceManager.php"
line: 909 message: "An exception was raised while creating
"Zend\Db\Adapter\Adapter"; no instance returned"
An exception was raised while creating "Zend\Db\Adapter\Adapter"; no instance returned
This could be your problem. The __construct method can throw an InvalidArgumentException(docs).
You should try to create an instance of Zend\Db\Adapter\Adapter on your own and see if an exception is thrown.
I'm trying to create a ZF2 application with multiple databases. Based on a user, the database should be dynamically set.
Right now I've the following:
database.local.php
return array(
'db' => array(
'adapters' => array (
'master_db' => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=master_db;host=localhost',
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
),
'username' => 'USERNAME',
'password' => 'PASSWORD'
),
'tentant_db' => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=tenant_db;host=localhost',
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
),
'username' => 'USERNAME',
'password' => 'PASSWORD'
),
)
),
'service_manager' => array(
'abstract_factories' => array(
'Zend\Db\Adapter\AdapterAbstractServiceFactory',
)
),
);
For test purposes I've created a form that has a method to fetch some data and put it in a select box. The code to get the database connection is shown in the code below.
MyController.php (in some module)
//... some code
public function someAction(){
$dbAdapter = $this->getServiceLocator()->get('tentant_db');
$form = new AddEolConnectorForm($dbAdapter);
$viewModel = new ViewModel(array(
'form' => $form
));
return $viewModel;
}
//... some more code
My question is, how can I dynamically set the dbname for the tentant_db adapter in my controller (or module)?
Thanks for your help.
The config merge event is one of zend newer event's I believe. It triggers when zend is mergin the config array's which is perfect for the problem you are facing since you can override some array key's dynamically.
public function onMergeConfig(ModuleEvent $e)
{
$configListener = $e->getConfigListener();
$config = $configListener->getMergedConfig(false);
// I'm actually not sure if you have the route match here otherwise you may have to
// use some other method to retrieve the url.
$match = $e->getRouteMatch();
switch ($match) {
case 'first-dependency':
$config['db']['adapter'] => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=master_db;host=localhost',
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
),
'username' => 'USERNAME',
'password' => 'PASSWORD',
),
break;
case 'second-dependency':
$config['db']['adapter'] => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=tenant_db;host=localhost',
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
),
'username' => 'USERNAME',
'password' => 'PASSWORD',
),
break;
// Pass the changed configuration back to the listener:
$configListener->setMergedConfig($config);
}
Based on the above answer I've created to following:
Module.php
class Module implements AutoloaderProviderInterface
{
public function init(ModuleManager $moduleManager)
{
$events = $moduleManager->getEventManager();
// Registering a listener at default priority, 1, which will trigger
// after the ConfigListener merges config.
$events->attach(ModuleEvent::EVENT_MERGE_CONFIG, array($this, 'onMergeConfig'));
}
public function onMergeConfig(ModuleEvent $e)
{
$db = $this->getTentantDb();
$configListener = $e->getConfigListener();
$config = $configListener->getMergedConfig(false);
$config['db']['adapters']['tenant_db']['dsn'] = 'mysql:dbname='. $db .';host=localhost';
$configListener->setMergedConfig($config);
}
// Some more code
public function getTenantDb(){
$tenant_db = 'tenant_12345'
return $tenant_db;
}
}
I don't know if it is the best solution, but the above code is working. I think the next steps should be to put the code in a generic module or something so I can access it from all my modules.
I'm sorry I'm completely new to Zend Framework 2 with some tutorials I'm trying to connect my DB connection as follows,
Created a file in
xampp\htdocs\articlemanager\application\configs\autoload\global.php
Inserted the following Zend DB connection code to global.php
<?php
return array(
'service_manager' => array(
'factories' => array(
'Zend\Db\Adapter\Adapter' => 'Zend\Db\Adapter\AdapterServiceFactory',
),
'aliases' => array(
'db' => 'Zend\Db\Adapter\Adapter',
),
),
'db' => array(
'driver' => 'PDO_MYSQL',
'dsn' => 'mysql:dbname=articlemanager;host=localhost',
'username' => 'root',
'password' => '',
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
),
),
);
and In the Indexcontroller (\xampp\htdocs\articlemanager\application\controllers\IndexController.php) tested adding $this->db = $this->getServiceLocator()->get('db'); in the indexAction as follows
public function indexAction()
{
$this->db = $this->getServiceLocator()->get('db');
}
When I refresh page it display as
An error occurred
Application error
Can I know what I missed here?
Also I would like to know My Zend Library is in the \xampp\php\Zend and My global.php file in the xampp\htdocs\articlemanager\application\configs\autoload\global.php is it OK?
Why are you using an Alias on 'Db' ?
Try this, your driver name is different from mine.
In addition, please move your username and password to local.php.. so they do not persist in Git projects
global.php
<?php
return array(
'db' => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=articlemanager;host=localhost',
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
),
),
'service_manager' => array(
'factories' => array(
'Zend\Db\Adapter\Adapter' => 'Zend\Db\Adapter\AdapterServiceFactory',
),
),
);
local.php example
<?php
return array(
'db' => array(
'username' => 'DB_USERNAME',
'password' => 'DB_PASSWORD',
),
);
database connection problems can be a number of different issues that are not necessarily obvious from looking at the creds / db config info.
have you taken a look at any logs? my application has several different logs setup - PHP error, access log, mysql error log, etc. - depending on your application, you may not have this many as discretely defined, but checking any logs you do have will give you a whole lot more information than just "An error has occurred" :)
I am taking the Zend Framework 2 Skeleton tutorial but have elected to use the mysql database in my container at my.phpcloud.com.
In the global.php file I have:
return array(
'db' => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=mycontainer;host=mycontainer-db.my.phpcloud.com',
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
),
),
'service_manager' => array(
'factories' => array(
'Zend\Db\Adapter\Adapter'
=> 'Zend\Db\Adapter\AdapterServiceFactory',
),
),
);
In my local.php file I have:
return array(
'db' => array(
'username' => 'mycontainer',
'password' => 'mypassword',
),
);
I receive no errors, even if I purposely put in incorrect credentials. My view loads properly...except that there are no records. I've verified that the table exists and it is named correctly. I've verified that the table contains records.
If I return the Controller to call an array for the view, rather than a populated ViewModel, it loads the view with errors, as expected, since the AlbumTable does not load. In other words, the View is being routed correctly. It just seems like the database is returning no results. I've copied and pasted everything to the correct files and triple checked it all. I completed this tutorial locally with Zend Server and MySql and it runs perfectly. It's just the PHPCloud, which issues no errors, that seems to be returning no records from its database, whether I purposely introduce bad credentials or not.
Thanks for any assistance in advance.
Try something like this:
$dsn = sprintf(
'mysql:dbname=%s;host=%s',
get_cfg_var('zend_developer_cloud.db.name'),
get_cfg_var('zend_developer_cloud.db.host')
);
return array(
'db' => array(
'driver' => 'pdo',
'dsn' => $dsn,
'username' => 'mycontainer',
'password' => 'mypassword',
),
);