About mvc db connection, mysqlAdapter

I got

return [
    'db' => [
        'driver' => 'Pdo',
        'adapters' => [
            mysqlAdapter::class => [
                'driver' => 'Pdo',
                'dsn' => 'mysql:dbname=your_database_name;host=your_mysql_host;charset=utf8',
                'username' => 'your_mysql_username',
                'password' => 'your_mysql_password',
                'driver_options' => [
                    PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
                ],
            ],
        ],
    ],
];

then I use

public function getServiceConfig()
    {
        return [
            'factories' => [
                Model\MemberTable::class => function($container) {
                    $tableGateway = $container->get(Model\MemberTableGateway::class);
                    return new Model\MemberTable($tableGateway);
                },
                Model\MemberTableGateway::class => function($container){
                    $dbAdapter = $container->get(mysqlAdapter::class);
                    $resultSetPrototype = new ResultSet();
                    $resultSetPrototype->setArrayObjectPrototype(new Model\Member());
                    return new TableGateway('member', $dbAdapter, null, $resultSetPrototype);
                },
            ],
        ];
    }

However I got error like

Unable to resolve service “Application\mysqlAdapter” to a factory; are you certain you provided it during configuration?

How to fix this? Anyone can help?

It 's all about namespacing. As long as your config file does not use namespaces the mysqlAdapter::class statement must be used as a use statement in your Module.php or with a forwarding backslash.

<?php
declare(strict_types=1);
namespace Application;

use mysqlAdapter;

class Module
{
    public function getServiceConfig()
    {
        return [
            'factories' => [
                $dbAdapter = $container->get(mysqlAdapter::class); 
                // or as \mysqlAdapter::class without the use statement above
                $resultSetPrototype = new ResultSet();
                $resultSetPrototype->setArrayObjectPrototype(new Model\Member());
                return new TableGateway('member', $dbAdapter, null, $resultSetPrototype);
            ]
        ];
    }
}

thank you so much! Yes, you are right, when I add use mysqlAdapter; at to top of module.php
Everything goes right!

Hi @jobsfan,

I am just curious to know can you still use Lamda functions in Laminas. The one you’ve used above is here.

Thanks!

Lambda functions still do not pose a problem. Looking at the current laminas/laminas-servicemanager package the class ServiceManager recognizes callables when getting factories. In line 534ff at ServiceManager.php factories are first, it is checked whether the specified factory is a string and the named class exists. This case covers factories as classes. Immediately afterwards, it is checked whether the specified factory is a callable. Since every factory class should implement the PSR __invoke() method, it is a callable, too. So the service manager handles classes and lambdas as well.

I myself prefer to write factories as classes, as this seems much clearer to me. The code is encapsulated and is exactly where it should be. However, callables are still a tried and tested means.

I actually started taking my adapter out of Module.php. I find it to be much easier.

local.php

return [
    'service_manager' => [
        'services' => [
            'model-adapter-config' => [
                'driver' => 'PDO',
                'dsn' => 'mysql:host=host;dbname=dbname',
                'username' => 'username',
                'password' => 'password',
            ],
        ],
    ],
];

module.config.php

'service_manager' => [
        'aliases' => [
        ],
        'factories' => [
            'model-adapter' => ModelAdapterFactory::class,
        ],
    ],
];

src/Service/Factory/ModelAdapterFactory.php

namespace Service\Factory;

use Psr\Container\ContainerInterface;
use Laminas\Db\Adapter\Adapter;
use Laminas\ServiceManager\Factory\FactoryInterface;

class ModelAdapterFactory implements FactoryInterface
{
    public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
    {
        $adapter = new Adapter($container->get('model-adapter-config'));
        return $adapter;
    }
}

@COMCDUARTE,

I’ve to agree to disagree here with your approach. When a much easier and more understandable approach is defined here. Why should I go with your solution which is a sacrilege? Sacrilege is just used here in a humble sense. Don’t take it as an offence. Thanks!

No Offense. Good information though. Coding is a art, many different techniques out there.

Thanks for understanding. Agreed on coding is an art. But, when joining a community I have this dumb idea some configuration should resemble exactly what is shown by the people who have created this community. Then we bring everyone to some common way of writing. But that is just my dumb opinion. In the end thanks for understanding.