New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ZF 3 with DeveloperTools #224

Open
rogatec opened this Issue Jul 26, 2016 · 9 comments

Comments

Projects
None yet
3 participants
@rogatec

rogatec commented Jul 26, 2016

Hi,

  1. I installed zf3 via composer (all dependencies for testing purposes).
  2. Vhost application env to "development"
  3. Added via composer require-dev "zendframework/zend-developer-tools": "^1.1"
  4. Added a development.config.php to my /config folder with the following content:
<?php
// zf3-tutorial/config/autoload/zenddevelopertools.local.php
return [
    // Development time modules
    'modules' => [
        'ZendDeveloperTools',
    ],
    'module_listener_options' => [
        // Turn off caching
        'config_glob_paths' => [realpath(__DIR__) . '/autoload/{,*.}{global,local}-development.php'],
        'config_cache_enabled'     => false,
        'module_map_cache_enabled' => false,
    ],
    'view_manager' => [
        'display_exceptions' => true,
    ],
];

When I comment out the modules value part for the ZendDeveloperTools my system is starting, but if I want the DevTools the system is crashing with the following error:

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/USER/rogatec/zf3-tutorial/vendor/zendframework/zend-servicemanager/src/ServiceManager.php on line 754

( ! ) Zend\Db\Adapter\Exception\InvalidArgumentException: createDriver expects a "driver" key
to be present inside the parameters in /var/www/USER/rogatec/zf3-tutorial/vendor/zendframework/zend-db/src/Adapter/Adapter.php on line 262

So the upper problem seems to be a problem with the database adapters I've configured in my global.php and local.php file.

So take a look to the db part global.php:

// zf3-tutorial/config/autoload/global.php
use Zend\Db\Adapter\AdapterAbstractServiceFactory;
return [
    'service_manager' => [
        'abstract_factories' => [
            AdapterAbstractServiceFactory::class,
        ],
    ],
];

local.php:

// zf3-tutorial/config/autoload/local.php
'db' => [
        'adapters' => [
            'db1' => [
                'driver' => 'Pdo',
                'dsn' => 'mysql:dbname=database1;host=localhost',
                'driver_options' => [
                    PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
                ],
                'username' => 'test',
                'password' => 'test',
            ],
            'db2' => [
                'driver' => 'Pdo',
                'dsn' => 'mysql:dbname=database2;host=localhost',
                'driver_options' => [
                    PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
                ],
                'username' => 'test',
                'password' => 'test',
            ],
        ],
    ],

Any hints what I've might done wrong or any missing information you need for give some solution hints?

The problem occurs because the AdapterServiceFactory misses the single db configuration:

// single db adapter solution example
return [
    'db' => [
        'driver' => 'Pdo',
        'dsn' => 'mysql:dbname=database;host=localhost',
        'driver_options' => [
               PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
        ],
        'username' => 'test',
        'password' => 'test',
    ],
];

The documentation says, that when using a multi db configuration you should implement the abstract_factories part, which I obviously did.

@robob4him

This comment has been minimized.

Show comment
Hide comment
@robob4him

robob4him Aug 30, 2016

@rogatec What call are you making to the service manager to retrieve the db instance? If you call "get('db1')" or "get('db2')" I should think this setup should work.

robob4him commented Aug 30, 2016

@rogatec What call are you making to the service manager to retrieve the db instance? If you call "get('db1')" or "get('db2')" I should think this setup should work.

@rogatec

This comment has been minimized.

Show comment
Hide comment
@rogatec

rogatec Aug 31, 2016

Hi @robob4him - for example in my AlbumControllerFactory I do this:

public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
    {
        $albumTable = $container->get(AlbumTable::class);
        $svAdapter = $container->get('db2');

        return new AlbumController($albumTable, $svAdapter);
    }

Then in my AlbumController I can call the db adapter:

public function gotoAction()
    {
        // second adapter
        $db = new Sql($this->svAdapter);
        $select = $db->select('projects');
        $select->where(['id' => 139]);
        $stmt   = $db->prepareStatementForSqlObject($select);
        $result = $stmt->execute();

        // ...
    }

So this setup works fine - but when I enable the development-mode (now the ZendDeveloperTools module is active) via terminal my page crashes with the exception from my initial post.

rogatec commented Aug 31, 2016

Hi @robob4him - for example in my AlbumControllerFactory I do this:

public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
    {
        $albumTable = $container->get(AlbumTable::class);
        $svAdapter = $container->get('db2');

        return new AlbumController($albumTable, $svAdapter);
    }

Then in my AlbumController I can call the db adapter:

public function gotoAction()
    {
        // second adapter
        $db = new Sql($this->svAdapter);
        $select = $db->select('projects');
        $select->where(['id' => 139]);
        $stmt   = $db->prepareStatementForSqlObject($select);
        $result = $stmt->execute();

        // ...
    }

So this setup works fine - but when I enable the development-mode (now the ZendDeveloperTools module is active) via terminal my page crashes with the exception from my initial post.

@robob4him

This comment has been minimized.

Show comment
Hide comment
@robob4him

robob4him Aug 31, 2016

I'll take a guess and say you have the db profiler enabled. The problem with that is that bjyprofiler doesn't support multiple db connections via the adapter factory. It wouldn't be hard, really, just combine the functionality of the adapter factory and the Zend\Db\Adapter\AdapterAbstractFactory and enable it in the service manager instead of zend framework's. If you have a fuller trace of the exception you could verify that it is bjyprofiler throwing the exception. If I remember I'll try this setup to try to break down exactly where it's happening.

robob4him commented Aug 31, 2016

I'll take a guess and say you have the db profiler enabled. The problem with that is that bjyprofiler doesn't support multiple db connections via the adapter factory. It wouldn't be hard, really, just combine the functionality of the adapter factory and the Zend\Db\Adapter\AdapterAbstractFactory and enable it in the service manager instead of zend framework's. If you have a fuller trace of the exception you could verify that it is bjyprofiler throwing the exception. If I remember I'll try this setup to try to break down exactly where it's happening.

@rogatec

This comment has been minimized.

Show comment
Hide comment
@rogatec

rogatec Sep 1, 2016

Sadly to say, but I neither have the db profiler enabled nor installed.

This is my modules.config.php

return [
    'Zend\InputFilter',
    'Zend\Filter',
    'Zend\Hydrator',
    'Zend\I18n',
    'Zend\ServiceManager\Di',
    'Zend\Session',
    'Zend\Mvc\Plugin\Prg',
    'Zend\Mvc\Plugin\Identity',
    'Zend\Mvc\Plugin\FlashMessenger',
    'Zend\Mvc\Plugin\FilePrg',
    'Zend\Mvc\Console',
    'Zend\Log',
    'Zend\Form',
    'Zend\Db',
    'Zend\Router',
    'Zend\Validator',
    'Application',
    'Album',
];

The ZendDeveloperTools are getting enabled via composer development-enable - then the existing development.config.php.dist in my /config folder will be transformed to a valid php file with the following content:

return [
    // Additional modules to include when in development mode
    'modules' => [
        'ZendDeveloperTools',
    ],
    // Configuration overrides during development mode
    'module_listener_options' => [
        'config_glob_paths' => [realpath(__DIR__) . '/autoload/{,*.}{global,local}-development.php'],
        'config_cache_enabled' => false,
        'module_map_cache_enabled' => false,
    ],
];

rogatec commented Sep 1, 2016

Sadly to say, but I neither have the db profiler enabled nor installed.

This is my modules.config.php

return [
    'Zend\InputFilter',
    'Zend\Filter',
    'Zend\Hydrator',
    'Zend\I18n',
    'Zend\ServiceManager\Di',
    'Zend\Session',
    'Zend\Mvc\Plugin\Prg',
    'Zend\Mvc\Plugin\Identity',
    'Zend\Mvc\Plugin\FlashMessenger',
    'Zend\Mvc\Plugin\FilePrg',
    'Zend\Mvc\Console',
    'Zend\Log',
    'Zend\Form',
    'Zend\Db',
    'Zend\Router',
    'Zend\Validator',
    'Application',
    'Album',
];

The ZendDeveloperTools are getting enabled via composer development-enable - then the existing development.config.php.dist in my /config folder will be transformed to a valid php file with the following content:

return [
    // Additional modules to include when in development mode
    'modules' => [
        'ZendDeveloperTools',
    ],
    // Configuration overrides during development mode
    'module_listener_options' => [
        'config_glob_paths' => [realpath(__DIR__) . '/autoload/{,*.}{global,local}-development.php'],
        'config_cache_enabled' => false,
        'module_map_cache_enabled' => false,
    ],
];
@samsonasik

This comment has been minimized.

Show comment
Hide comment
@samsonasik

samsonasik Sep 9, 2016

Contributor

should already fixed by #218 , close-able.

Contributor

samsonasik commented Sep 9, 2016

should already fixed by #218 , close-able.

@rogatec

This comment has been minimized.

Show comment
Hide comment
@rogatec

rogatec Sep 11, 2016

@samsonasik nope this (f75787f) does not fix the issue.

What's the correct configuration for multi-db adapters, that works with the dev tools?

Why is:

'db' => [
        'adapters' => [
            'db1' => [
                'driver' => 'Pdo',
                'dsn' => 'mysql:dbname=zf3;host=localhost',
                'driver_options' => [
                    PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
                ],
            ],
            'db2' => [
                'driver' => 'Pdo',
                'dsn' => 'mysql:dbname=redmine;host=localhost',
                'driver_options' => [
                    PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
                ],
            ],
        ],
    ],

working, when dev tools are disabled, but not if it is?

rogatec commented Sep 11, 2016

@samsonasik nope this (f75787f) does not fix the issue.

What's the correct configuration for multi-db adapters, that works with the dev tools?

Why is:

'db' => [
        'adapters' => [
            'db1' => [
                'driver' => 'Pdo',
                'dsn' => 'mysql:dbname=zf3;host=localhost',
                'driver_options' => [
                    PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
                ],
            ],
            'db2' => [
                'driver' => 'Pdo',
                'dsn' => 'mysql:dbname=redmine;host=localhost',
                'driver_options' => [
                    PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
                ],
            ],
        ],
    ],

working, when dev tools are disabled, but not if it is?

@samsonasik

This comment has been minimized.

Show comment
Hide comment
@samsonasik

samsonasik Sep 11, 2016

Contributor

@rogatec I think the 'root' adapter of 'db' should be defined first if you define 'db' key, so, your config may be:

'db' => [
     // root adapter called from $services->get(\Zend\Db\Adapter\AdapterInterface::class);
     'driver' => 'Pdo',
     'dsn' => 'mysql:dbname=zf3;host=localhost',
     'driver_options' => [
            PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
      ],

       // more adapters
        'adapters' => [
            'db1' => [
                'driver' => 'Pdo',
                'dsn' => 'mysql:dbname=zf3;host=localhost',
                'driver_options' => [
                    PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
                ],
            ],
            'db2' => [
                'driver' => 'Pdo',
                'dsn' => 'mysql:dbname=redmine;host=localhost',
                'driver_options' => [
                    PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
                ],
            ],
        ],
    ],
Contributor

samsonasik commented Sep 11, 2016

@rogatec I think the 'root' adapter of 'db' should be defined first if you define 'db' key, so, your config may be:

'db' => [
     // root adapter called from $services->get(\Zend\Db\Adapter\AdapterInterface::class);
     'driver' => 'Pdo',
     'dsn' => 'mysql:dbname=zf3;host=localhost',
     'driver_options' => [
            PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
      ],

       // more adapters
        'adapters' => [
            'db1' => [
                'driver' => 'Pdo',
                'dsn' => 'mysql:dbname=zf3;host=localhost',
                'driver_options' => [
                    PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
                ],
            ],
            'db2' => [
                'driver' => 'Pdo',
                'dsn' => 'mysql:dbname=redmine;host=localhost',
                'driver_options' => [
                    PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
                ],
            ],
        ],
    ],
@rogatec

This comment has been minimized.

Show comment
Hide comment
@rogatec

rogatec Sep 12, 2016

@samsonasik - yes this is a workaround when you are in development mode.

But you can work with adapters only, when in production mode - this is quite confusing.

rogatec commented Sep 12, 2016

@samsonasik - yes this is a workaround when you are in development mode.

But you can work with adapters only, when in production mode - this is quite confusing.

@samsonasik

This comment has been minimized.

Show comment
Hide comment
@samsonasik

samsonasik Sep 12, 2016

Contributor

this default 'db' config by @weierophinney may fixes this issue zendframework/zend-db#164

Contributor

samsonasik commented Sep 12, 2016

this default 'db' config by @weierophinney may fixes this issue zendframework/zend-db#164

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment