Creating a Database using Zend 3 and Doctrine2

Let’s say we need to create a database on the fly and use it within our Zend 3 project.

Typically you will create the database then store the credentials within your global or local php config file in your autoload directory. But this time we do need to create a second database which name depends on a data stored in the primary base.

See the following picture to ease your understanding :

 

Database creation - Doctrine & ZF3

Connection parameters

If you are using the common procedure on using Doctrine along with Zend or other platforms, you will have your parameters defined as follow :


use Doctrine\DBAL\Driver\PDOMySql\Driver as PDOMySqlDriver;


return [
		
		'doctrine' => [
				'connection' => [
						'orm_default' => [
								'driverClass' => PDOMySqlDriver::class,
								'params' => [
										'host'     => '127.0.0.1',
										'user'     => 'test',
										'password' => '######',
										'dbname'   => 'test',
								]
						],
				]
		],
];

If you need additional bases, you can simply add the parameters below the orm_default and name them differently as covered in olegkrivtsov’s book on Github.

But how about defining them or changing the parameters within a service manager or a controller ?

Changing connection parameters in a ZF3 class

Let’s achieve a tiny task : replacing the database name which is originally set up within the local.php configuration file.

In order to know how to do that, we just followed the documentation about the Doctrine ORM Module which gave us the registered service name :

doctrine.connection.orm.default 

The above service is actually an instance of Doctrine\DBAL\Connection class which you can find on Github.

Check out the content of this class near the following lines :


namespace DoctrineORMModule\Options;
use Doctrine\DBAL\Driver\PDOMySql\Driver;
use Zend\Stdlib\AbstractOptions;
/**
 * DBAL Connection options
 *
 * @license MIT
 * @link    http://www.doctrine-project.org/
 * @author  Kyle Spraggs 
 */
class DBALConnection extends AbstractOptions
{
        //..


    /**
     * Driver specific connection parameters.
     *
     * @var array
     */
    protected $params = [];

    //..


    /**
     * @param array $params
     */
    public function setParams($params)
    {
        $this->params = $params;
    }
    /**
     * @return array
     */
    public function getParams()
    {
        return $this->params;
    }

//..

I’m sure you recognized the params array above, now you have an idea on how to retrieve the content of that array from another class of your own.

I’m using a controller factory to load the class and pass it to the controller :

<?php 
namespace MyBase\Controller\Factory; 

use Interop\Container\ContainerInterface; 
use Zend\ServiceManager\Factory\FactoryInterface; 
use MyBase\Controller\IndexController; 

/** 
* This is the factory for IndexController. Its purpose is to instantiate the 
* controller. 
*/ 

class IndexControllerFactory implements FactoryInterface { public function __invoke(ContainerInterface $container, $requestedName, array $options = null) 
{ 
        $entityManager = $container->get('doctrine.entitymanager.orm_default');
	$connectionManager = $container->get('doctrine.connection.orm_default');
		
	// Instantiate the controller and inject dependencies
	return new IndexController($entityManager,$connectionManager);
}
}

Now the controller where we can work on the parameters :

<?php 
namespace MyBase\Controller; 

use Zend\Mvc\Controller\AbstractActionController; 
use Zend\View\Model\ViewModel; 

class IndexController extends AbstractActionController 
{ 

/** 
* Connection manager. 
* @var Doctrine\ORM\ConnectionManager 
*/ 

        private $connectionManager; 

/** 
* Constructor. 
*/ 
public function __construct($entityManager,$connectionManager) 
{ 

      $this->entityManager = $entityManager;
      $this->connectionManager = $connectionManager;
	
}

public function indexAction()
{

      $cur_db = $this->connectionManager->getParams();

      // Return the current database name to the view
      return new ViewModel([
		'db' => $cur_db['dbname']
		]);
}

We will see later how to change the parameters.

Creating the database using Zend 3 and Doctrine 2

Since the beginning of Doctrine (version 1), there is a method which allows the creation of a database :

createDatabase()

This is a feature belonging to the Doctrine Database Abstraction Layer (DBAL) which stands on top of PDO (Php Data Objects).

As you already work on the connection Manager ($this->connectionManager), all you need to do is getting the shema manager from this instance and then apply the required function for creating your database.


// Create DB :

$sm = $this->connectionManager->getSchemaManager();

$sm->createDatabase($dbname);

Of course if you just apply the function to a page of your website, you will encounter an issue with access rights. You can fix this by allowing your user to create database depending on your type of base (ie: Mysql…).

For instance in Mysql, you may use this :

mysql> GRANT ALL PRIVILEGES ON . TO youruser@’localhost’;

Beware that this query will provide your user all types of rights with your databases. We will talk about it later in another tutorial to see what we can do to fix such security matters.

Feel free to comment, I’ll be glad to answer your requests.

Leave a Reply

Want more information?

Related links will be displayed here in this section for you to pick up another good spot to get more details about Web marketing and Search Engine Optimization. There will be some sites which we selected to ease the work of any webmaster or/and web marketer on the Internet.

%d bloggers like this: