Подтвердить что ты не робот

PHP 5.4 - Черты и self/static

Я хочу связать вызовы методов на моих классах следующим образом:

new Obj($args, $if, $any)->foo()->bar();

К сожалению, я должен заключить конструкцию в круглые скобки:

(new Obj($args, $if, $any))->foo()->bar();

Итак, я хотел бы иметь черту, которую я мог бы использовать в каждом классе, я хочу сделать что-то вроде:

Obj::create($args, $if, $any)->foo()->bar();

Я хочу, чтобы это была черта, поэтому мои классы все еще могут наследоваться от других классов. Я пришел к этому моменту:

trait Create
{
    public static final function create()
    {
        $reflect = new ReflectionClass(/* self ? static ? Anything else ? */);
        return $reflect->newInstanceArgs(func_get_args());
    }
}

class Obj
{
    use Create;

    // ...
}

Но похоже, что черты не обрабатывают само или статические ключевые слова, и я не могу сделать get_class($this), так как это статично. Есть ли четкий способ сделать то, что я хочу, пожалуйста?

Спасибо за чтение.

EDIT: для тех, кто задается вопросом, вот почему я хочу, чтобы он был признаком, а не абстрактным базовым классом:

$database = (new Database())
    ->addTable((new Table())
        ->addColumn((new Column('id', 'int'))
            ->setAttribute('primary', true)
            ->setAttribute('unsigned', true)
            ->setAttribute('auto_increment', true))
        ->addColumn(new Column('login', 'varchar'))
        ->addColumn(new Column('password', 'varchar')));

$database = Database::create()
    ->addTable(Table::create()
        ->addColumn(Column::create('id', 'int')
            ->setAttribute('primary', true)
            ->setAttribute('unsigned', true)
            ->setAttribute('auto_increment', true))
        ->addColumn(Column::create('login', 'varchar'))
        ->addColumn(Column::create('password', 'varchar')));

Меньшая глубина скобки, меньше ошибок и меньше времени, необходимого для исправления этих ошибок, плюс более легкий для чтения код и, на мой взгляд, более красивый код.

4b9b3361

Ответ 1

Да, есть get_called_class(), который делает именно то, что вы хотите.

Ответ 2

Я не понимаю, почему вы не хотите использовать скобки - это не совсем худший синтаксис в мире (на самом деле, я бы сказал, что с визуальной точки зрения это лучше, чем двойной синтаксис двоеточия, который вы хотите для его замены)

Но если вы хотите иметь метод factory, подобный этому, на всех ваших классах, почему бы просто не создать базовый класс, который распространяется на все ваши другие классы, который определяет метод create? Я не вижу, что вам нужна черта для этого.

class BaseClass {
    public function create() {
        ...
    }
}

а затем все остальные классы extends BaseClass, где у вас уже нет extends.

Ответ 3

Черты - это новая функция PHP. эта функция представлена ​​в версии 5.4. Это заменяет множественное наследование в PHP

Пример:

trait Net
{
    public function net()
    {
        return 'Net';
    }
}

trait Tuts
{
    public function tuts()
    {
        return 'Tuts';
    }
}

class NetTuts
{
    use Net, Tuts;
    public function plus()
    {
        return 'Plus';
    }
}

$o = new NetTuts;
echo $o->net(), $o->tuts(), $o->plus();

вывод: NetTutsPlus

echo (new NetTuts)->net(), (new NetTuts)->tuts(), (new NetTuts)->plus();

вывод: NetTutsPlus

с помощью объекта $o мы можем получить доступ к значению функции trait..