ZF-Commons / ZfcUser

A generic user registration and authentication module for ZF2. Supports Zend\Db and Doctrine2. (Formerly EdpUser)
BSD 3-Clause "New" or "Revised" License
495 stars 343 forks source link

passwd in not a legal key for Pdo connection string #40

Closed markushausammann closed 12 years ago

markushausammann commented 12 years ago

There is a mistake in the Zend\Db post-install instruction:

    'masterdb' => array(
        'parameters' => array(
            'dsn'            => "mysql:dbname={$mdb['dbname']};host={$mdb['host']}",
            'username'       => $mdb['user'],
            'passwd'         => $mdb['pass'],
            'driver_options' => array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''),
        ),
    ),

passwd is not a legal key, it has to either be pass or password.

EvanDotPro commented 12 years ago

Actually passwd is the name of the parameter passed to the PDO class __construct.

markushausammann commented 12 years ago

exactly, and that class doesn't accept that key, the switch statement only accepts pass and password, which is just as well since passwd is not a good variable name anyways.

EvanDotPro commented 12 years ago

Actually, the PHP docs are wrong in this case. Internally the parameter is called passwd. You can verify thus using reflection:

<?php
$class = new ReflectionClass('PDO');
$methods = $class->getMethods();
var_dump($methods[0]);
markushausammann commented 12 years ago

we're not talking about the same thing. this array is pre-processed by Zend\Db. If I use passwd it doesn't work, if I use password, it works. I'm not philosophising, I'm using the module and it only works, if I change it. Maybe the Zend API has changed I don't know.

EvanDotPro commented 12 years ago

What version of PHP are you using? I have the opposite result, where if I put password it does not work, but passwd works.

EvanDotPro commented 12 years ago

The array in question is not actually processed by Zend\Db. In fact, Zend\Di creates an instance of PDO with the parameters given, then that instantiated PDO instance is injected into a Zend\Db adapter. I do it this way for reasons mentioned here. My only guess as to why it is not working for you until you rename the parameter is possibly that PHP changed the internal API for the PDO object.

markushausammann commented 12 years ago

So, in any case, the provided solution didn't work, I got an catchable fatal error among the lines of that some component excepts a zend db adapter adapter but PDO given. So I remodeled the config as follows:

return array(
    'di' => array(
        'instance' => array(
            'alias' => array(
                'masterdb' => 'Zend\Db\Adapter\Adapter',
            ),
            'masterdb' => array(
                'parameters' => array(
                    'driver' => array(
                        'driver' => 'Pdo',
                        'dsn' => "mysql:dbname={$mdb['dbname']};host={$mdb['host']}",
                        'username' => $mdb['user'],
                        'password' => $mdb['pass'],
                        'driver_options' => array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''),
                    ),
                ),
            ),
            'Zend\Db\Adapter\Driver\Pdo\Pdo' => array(
                'parameters' => array(
                    'connection' => 'Zend\Db\Adapter\Driver\Pdo\Connection',
                ),
            ),
            'Zend\Db\Adapter\Driver\Pdo\Connection' => array(
                'parameters' => array(
                    'connectionInfo' => 'masterdb',
                ),
            ),
        ),
    ),
);

This should explain why 'passwd' doesn't work, because in my case, it is preprocessed by Zend Db.

so the question would change into the question why I got this error in the first place.

EvanDotPro commented 12 years ago

Okay so you changed the config strategy to simply configure a Zend\Db\Adapter\Adapter directly. That's your answer. In my provided config, I instead configure a PDO instance, then inject that. I do this so that the PDO instance is available for injection in other places in the future such as other database libraries, etc. This is a good practice in a modular environment.

EvanDotPro commented 12 years ago

As for why you got the error in the first place -- I'm not sure. I'm unable to reproduce what you've described. Using the provided config from the docs seems to work just fine for me. I just tried again with a fresh clone of ZfcUser, ZfcBase, ZendSkeletonApplcation and zf2 to verify.

markushausammann commented 12 years ago

well... I guess we'll never know :) misterious world of tech. thanks for your time and work. today I just need pragmatic solutions and I can't take the time to analyse it... it works now.