Как реализовать статическое обращение к пространству имён?

Есть класс:

namespace project;

abstract class Helper
{
    ....
}


От него будут наследоваться классы Helper в других пространствах имён, например:

namespace project\soft;

class Helper extends \project\Helper
{
    ....
}


В каждом из этих пространстве имён будет свой класс Mapper. Мне необходимо сделать в базовом абстрактном Helper'e метод getMapper, который будет для каждого наследника возвращать Mapper из текущего пространства имён, cо своим экземпляром в конструкторе. Как-то так:

namespace project;

abstract class Helper
{
    public fucntion getMapper()
    {
        return new __STATIC_NAMESPACE__\Mapper(new static);
    }
}


Как получить пространство имён наследника? Есть что-то вроде getNamespace(static)?
Как тогда прилепить его к "Mapper(new static)"?

Есть какие-то стандартные решения этой задачи?
  • Вопрос задан
  • 148 просмотров
Решения вопроса 2
miraage
@miraage
Старый прогер
<?php

namespace project {
    abstract class Helper
    {
        public static function getMapper()
        {
            $self = new static();
            
            $ref = new \ReflectionClass($self);
            $ns = $ref->getNamespaceName();
            
            $mapper = sprintf('%s\\Mapper', $ns);
            
            return new $mapper($self);
        }
    }
}

namespace project\soft {
    use project\Helper as BaseHelper;
    
    class Helper extends BaseHelper
    {
        
    }
    
    class Mapper
    {
        private $helper;

        public function __construct($helper)
        {
            $this->helper = $helper;
        }
    }
}

namespace {
    $mapper = \project\soft\Helper::getMapper();
    
    var_dump($mapper);
}
Ответ написан
Audiophile
@Audiophile Автор вопроса
Как оказалось, есть аж два способа получить полное имя реально вызываемого касса (с неймспейсом):

$self = static::Class;
$self = get_called_class();


Вот пример статического PersistenceFactory без создания самоэкземпляров:

abstract class StaticFactory
{
    protected static function getForNS($class_name, ...$args)
    {
        $self_class = '\\'.static::Class; // (Or get_called_class())
        $ns = substr($self_class, 0, strrpos($self_class, '\\'));
        $class_full_name = $ns.'\\'.$class_name;
        return new $class_full_name(...$args);
    }
         
    public static function getDomainObjectAssembler()
    {
        $self = static::Class;
        return self::getForNS('DomainObjectAssembler', static::Class);
    }
}
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы