Фишки php 5.4

fixxxer

К.О.
Партнер клуба
Кто что придумал? Начну.

Transaction-блоки а-ля ruby:

PHP:
class Database_Connection { // delegates to Pdo
    // ...
    public function transaction(Closure $c) {
        $this->beginTransaction();
        try {
            $result = $c->bindTo($this)->__invoke();
            $this->commit();
        } catch (Exception $e) {
            $this->rollback();
            throw $e;
        }
        return $result;
    }
    // ...
}

// Usage:
$Connection->transaction(function() {
    // inside a transaction...
});
 

fixxxer

К.О.
Партнер клуба
Не-а.

$c->bindTo($this)->__invoke();

Ну, то есть, как бы можно, но обычно нужно такое:

PHP:
class SiteModel {

    public function insert($site, $domains) {
         $this->transaction(function() use ($site, $domains) {
              $this->insertSite($site);
              $this->insertDomains($domains);
         });
    }

    protected function insertSite($site) { ... }
    protected function insertDomains($domains) { ... }

}
Можно было только через жопу - передавая внутрь $this параметром или через костыль вида $Model = $this ... use($Model), и при этом делать public-ами по сути внутренние методы и свойства только ради этого.
 

fixxxer

К.О.
Партнер клуба
Вот еще скопипащу из недавней темы:

PHP:
trait strict {
    public function __get($key) {
        throw new Exception('Attempt to read undefined property $'.$key.' of '.get_class($this).' class');
    }

    public function __set($key, $value) {
        throw new Exception('Attempt to set value to undefined property $'.$key.' of '.get_class($this).' class');
    }
}

class Foo {
    use strict;
    // ...
}
Неидеально, конечно - __get и __set получаются "заняты"...
 

Вурдалак

Продвинутый новичок
Singleton с помощью trait, наверное, можно. Но писать не хочу (нет под рукой 5.4).
 

fixxxer

К.О.
Партнер клуба
Singleton с помощью trait, наверное, можно. Но писать не хочу (нет под рукой 5.4).
Угу, элементарно
PHP:
trait Singleton {

    private function __construct() {}

    private function __clone() {}

    private static $instance = null;

    public static function getInstance() {
        if (null === self::$instance) {
            self::$instance = new self;
        }
        return self::$instance;
    }

}
 

fixxxer

К.О.
Партнер клуба
Трейты надо использовать там, где без них ты копипастишь одни и те же методы в разные классы. Тогда - добро.

Ну скажем у меня есть простейшие интерфейсы типа IDatasource, IExportable, IRenderable итд, и их реализация совпадает в 90% случаев. Тут мне трейты идеально подходят.

Ну или по-другому - если приходило в голову сделать супер-дупер-класс типа FrameworkObject, от которого наследовать дофига чего - то тут тоже вероятно нужны трейты.
 

Absinthe

жожо
– Батюшка, скажите, а можно писать посты во время поста?
– Можно, сын мой, но только в Twitter, кратенько. В Facebook и ЖЖ нельзя.
Кстати насколько я знаю о христианстве, никакие нельзя(т.к. нельзя развлекаться в пост).
 

AmdY

Пью пиво
Команда форума
Absinthe
негодяй, как можно твиттер назвать развлечением. в христиансте не приветствуется праздность, вот твиттер как раз заполняет минуты свободного времени.

в 5.4 начала нормально работать проверка isset()
5.4.0 Проверка нечислового индекса строки теперь возвращает FALSE.
fixxxer
ещё чуть чуть и в пыхе появится полноценный yield, надеюсь до выхода php 6
 

Absinthe

жожо
негодяй, как можно твиттер назвать развлечением. в христиансте не приветствуется праздность, вот твиттер как раз заполняет минуты свободного времени.
Если это по работе или в целях обучения - то можно. Если это для убийства времени - то нельзя, т.к. это и есть праздное проведение времени.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
я давно юзаю поведения, и для полного счастья трейтам не хватает параметризации вроде
class A { use B('param');...

через трейты неплохо можно реализовать коллекции
 

Redjik

Джедай-мастер
grigori
как раз хотел отметить, что не хватает праметрезации трейтов, тогда бы fixxxer смог бы присоединять трейты вообще не трогая реализацию (я про те 10% процентов, которые не совпадают)
 

fixxxer

К.О.
Партнер клуба
grigori

А что ты имеешь ввиду под параметризацией?

В принципе можно в трейте проверять $this->param. Наверное в таких случаях так и надо, ведь трейты это же просто compile time автоматизированный копипаст, yii-поведения это скорее mixins :)
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
fixxxer
а тут возникает 2я проблема: чтобы проверять $this->param, надо быть уверенным, что он существует.
но трейту нельзя указать, какой интерфейс обязателен для объекта, в который он вживляется, и остается только вводить соглашения,

параметризация успешно работает в автоматизированном копипасте #define

в yii поведения в 90% случаев добавляются не на лету, а в коде класса как трейты.
технически на лету возможно, но очень редко нужно, т.к. хотеть этого случается в основном для моделей, а у них для всех операций есть колбеки типа afterFind()
 

fixxxer

К.О.
Партнер клуба
Можно в трейтах делать методы, которые по умолчанию ничего не делают, типа

PHP:
protected function processList(array $list) {
   return $list;
}
UPD: не совсем так. Вот как-то так

PHP:
trait ListModel {

    protected $count = 0, $list = array();

    protected function loadList($Criteria) {
        $count = $this->loadCount($this->convertToCountQuery($Criteria));
        $rs = $this->loadChunk($Criteria);
        $list = $this->convertRecordsetToList($rs);
        $this->count = $count;
        $this->list = $list;
    }   
    
    // .......
}

trait ListModelDefault extends ListModel {

    protected function convertRecordsetToList($rs) {
        return $rs;
    }   

}   

class FooListModel {
    use ListModelDefault;
}   

class BarListModel {
    use ListModel;

    protected function convertRecordsetToList($rs) {
        //...
    }
}
Ну да, получается наследование или набор "дополнительных" к "основному" трейтов вместо параметризации. Не вижу в этом ничего плохого. Для пущей красоты можно использовать интерфейсы - которые неважно как реализуются, в классе или одном из трейтов.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
> набор "дополнительных" к "основному" трейтов
т.е. соглашения :) и это не плохо, но так же, как было без них

для меня трейты пока что кажутся упрощенной формой привычных поведений, реализованной на уровне компилятора, но самостоятельно они недостаточно гибкие для реальных задач
 
Сверху