0
\$\begingroup\$

In this question here on S.O, the accepted answer suggests to use both anonymous function and factory pattern for dealing with PDO connection. I believe the anonymous function is used in case a connection to a different database needs to be established, a different function will be defined for that. In that case, will it be alright to move the anonymous function to the factory class itself? With this approach just passing the PDO parameters to the constructor will achieve the same as the original answer.

Something like:

class StructureFactory
{
    protected $provider = null;
    protected $connection = null;

    public function __construct( $PDO_Params )
    {
        $this->provider = function() {
            $instance = new PDO($PDO_Params["dsn"], $PDO_Params["username"], $PDO_Params["password"]);
            $instance->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            $instance->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
            return $instance;
        };
    }

    public function create( $name)
    {
        if ( $this->connection === null )
        {
            $this->connection = call_user_func( $this->provider );
        }
        return new $name( $this->connection );
    }

}
\$\endgroup\$
2
\$\begingroup\$

TL;DR: no.

The construction that is shown in the original example provided the following functionality:

  • decoupling from MySQL (you dont, need disable emulation of prepared statements, if you are not using mysql, and you usually dont need to provide username and password with SQLite)
  • option to use MySQLi or SOAP or any other DAL without rewriting the factory (see OCP)
  • replacing PDO with a mock object, when running unit tests
  • a way to alter the anonymous function, so that you can share the same PDO instance among multiple factories (when appropriate changes added)
  • establishing a connection to data source, only when it is necessary (connecting to SOAP can be really slow, and RDBMS under heavy load can actually run out of "connections" that can be opened)
\$\endgroup\$
  • \$\begingroup\$ Can you tell me a little bit more about the 4th point: "a way to alter the anonymous function, so that you can share the same PDO instance among multiple factories (when appropriate changes added)" \$\endgroup\$ – feetnappy May 12 '17 at 1:08
  • \$\begingroup\$ The quick-and-dirt way would be to just create a static variable withing the anonymous function, where you can store the PDO instance. A more elaborate way is to create a closure: 3v4l.org/6OON2. \$\endgroup\$ – tereško May 12 '17 at 7:35
0
\$\begingroup\$

I am not understanding what value you are gaining in defining a closure here in your constructor. The closure being applied will never change, so it might as well be traditional static code.

I also question the general value of this factory as constructed. It looks like you are trying to implement a singleton, but did not really do it properly, so there is really nothing to prevent calling code from instantiating lots of different factory objects and thus lots of DB connections.

I also very much question this being a factory to instantiate objects that need PDO objects. I would think that most classes in a complex application might need dependencies beyond just a PDO object, so can this class only instantiate a subset of the overall classes in your application?

It looks like what you are really after is a dependency injection container. I would suggest you look into common PHP DI containers like Pimple or PHP-DI to deliver this functionality.

\$\endgroup\$
  • \$\begingroup\$ The usecase for the original factory was initialization of data mappers. And those should only require a persistence abstraction (like PDO or REST client or SOAP or something) as a dependency. And it came from environment, where performance was the king (which also happens to be very unfriendly environment for DI containers). \$\endgroup\$ – tereško May 11 '17 at 15:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.