PHP Using Factory Template for SDK

I got a little lost here because I want to do something very simple in Java, but it seems a bit complicated in PHP.

We are building the SDK for our product and in Java, we have this one class that should not (!) Be created by the user (i.e. the encoder), since there are several integrity restrictions. So we built it as a nested class “X” inside “XFactory”, and you get an instance of X by calling XFactory.buildMeMyX (); - Easy...

Now PHP does not support nested classes at all, and I am wondering how to apply this here. In Java, the X constructor is hidden (private), so only XFactory can call it.

In PHP, it seems I will have to make __construct () public and move the nested X class from XFactory. Consequently, the user will be able to create an instance without Factory.

Now - you CAN move the factory functionality to X itself and move all things there, but this will partially break the SDK design. Is there a useful way to do such things in PHP after all?

+4
source share
3 answers

As others have said, there is currently no clean way to implement this behavior in PHP. In my opinion, the only valid examples of using private constructors are factories within the class that implement these factories .

, , . PHP.

, , . , , : . .

<?php

class Dependency {}

class SomeClass {

    protected $dep;

    private function __construct(Dependency $dep) 
    {
        $this->dep = $dep;
    }

    public function doSomething()
    {
        var_dump($this->dep);
        echo "Doing Stuff and even having dependencies";
    }

}

class SomeClassFactory {

    public function buildSomeClass()
    {
        return $this->instantiateSomeClassWith(new Dependency);
    }

    protected function instantiateSomeClassWith()
    {
        $reflectionClass = new ReflectionClass('SomeClass');
        $someClass = $reflectionClass->newInstanceWithoutConstructor();

        $constructor = $reflectionClass->getConstructor();
        $constructorClosure = $constructor->getClosure($someClass);
        call_user_func_array($constructorClosure, func_get_args());
        return $someClass;
    }

}

$factory = new SomeClassFactory();
$someClass = $factory->buildSomeClass();
$someClass->doSomething();

?>

: object(Dependency)#2 (0) { } Doing Stuff and even having dependencies

. , Factory, . Factory .

, call_user_func_array(). , Injection Dependency , .

. , . ,

, .

+1

PHP 5.x , / , .

, PHP 7 .

- ( , . fooobar.com/questions/82922/...), :

class XFactory
{
    public function buildMeMyX()
    {
        return new class() implements XInterface {
            public function doWhatEverAnXCanDo()
            {
                // X X X
            }
            // ...
        };
    }
}
interface XInterface
{
    function doWhatEverAnXCanDo();
}
+3

. , " ", factory, "" , inistantition.

class X
{

    function __construct()
    {
        new Y();
    }
}

class Y
{
    function __construct()
    {
        $trace = debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT, 2);

        if (!isset($trace[1]['object']) || !($trace[1]['object'] instanceof X)) {
            throw new \RuntimeException('This is a private class');
        }
    }
}

new X(); // All is fine

new Y(); // Exception

, , - .

+1

Source: https://habr.com/ru/post/1598718/


All Articles