0

I am trying to create a class (working as factory class) in my Zend Expressive APP as follows:

declare(strict_types=1);

namespace App\Install\Factory;

use App\Install\Model as Models;
use App\Install\Abstracts\AttributeInterface;

class AttributeEntityFactory{

    public static function create($type1 ='Attribute') : AttributeInterface
    {
        $resolvedClass = "Models\\$type1";
        $resolvedClass1 = 'Models\\'.$type1;
        //return new $resolvedClass();
        //return new $resolvedClass1();
        return new Models\Attribute();
    }
}

The above code works perfectly for me. However, if try to use any of the other two return statements it shows

Class 'Models\Attribute' not found

How can I achieve dynamic instantiation?

The attribute class code is as follows:

namespace App\Install\Model;
use App\Install\Abstracts\AttributeInterface;

class Attribute implements AttributeInterface
{
    protected $attribute;

    public function setAttribute($attribute)
    {
        $this->attribute = $attribute;
    }

    public function getAttribute()
    {
        return $this->attribute;   
    }  
}

My PHP version is:

PHP 7.2.13 (cli) (built: Dec 14 2018 04:20:16) ( NTS )

2 Answers 2

0

you may need to pass in the full namespace?

"App\Install\Model\" . $type1;

and more...

the model Attribute you have is in the namespace App\Install\Model, and the object you are trying to create is from Models\\ . $type1

maybe you need to change Models to Model

Sign up to request clarification or add additional context in comments.

Comments

0

Personally, I would avoid such factory implementation because of several reasons:

  1. It involves magic.
  2. Less predictable code.
  3. Harder to read for both humans and IDE's (E.g: PHPStorm would not find the usages of Attribute class in such code when you need to find it)
  4. Harder to analyze using static analyzers

Instead, I would rewrite this to a more explicit factory, even if I had dozens of different classes in App\Install\Model namespace:

<?php declare(strict_types=1);

namespace App\Install\Factory;

use App\Install\Model as Models;

class AttributeEntityFactory
{
    public static function create($type = 'Attribute') : AttributeInterface
    {
        switch ($type) {
            case 'Attribute':
                return new Models\Attribute();
            case 'SomethingElse':
                return new Models\SomethingElse();
            default:
                throw new \InvalidArgumentException(
                    sprintf('An unknown type %s requested from %s', $type, __METHOD__)
                );
        }
    }
}

As a rule of thumb:

  • Never compose classnames / namespaces using strings concatenated with variables / parameters / constants whatever.
  • Never call methods in such way, too.

You'll thank me when your application/business/codebase grows enough.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.