Всё есть объект
Возьмём массив постингов выбранного топика из предыдущего сообщения. Как обычно строится работа с ним?
code php
$topic_posts = bors_find_all(...);
if($topic_posts)
foreach($topic_posts as $post)
...
Или в шаблонах, в том же Smarty:
code smarty
...
Основная же идея нового подхода в том, что возвращаться будет не массив (или NULL в случае отсутствия и т.п.), а объект, содержащий итератор:
foreach(b2::find(...)->...->all() as $post)
По синтаксису не сказать, что больше упрощение или усложнение, но — унификация. Таким образом планируется использовать практически любые системные объекты. Вот практический пример. Вставка привязанного к объекту изображения. Пусть это будет картинка по умолчанию для того же топика форума. Как это делается в BORS1:
code smarty
{if $this-
>image
()}{$this-
>image
()-
>thumbnail
('200x150')-
>html_code
()}{/if}
Потому что если у нас нет изображения, то
->image() возвращает NULL и попытка обратиться к методу вернёт ошибку.
Так вот, в B2 основная концепция — никакой метод не должен возвращать NULL. Только корректные для обработки значения. Так что можно сразу выкидывать условие:
code smarty
{$this->image()->thumbnail('200x150')->html_code()}
Особенно это полезно при реально длинных цепочках. Например:
code smarty
{if $this-
>cabinet
()-
>owner
()}
{if $this-
>cabinet
()-
>owner
()-
>logo
()}
{$this->cabinet()->owner()->logo()->thumbnail('128x96')->html_code()}
Теперь же [будет] достаточно одной
таблетки цепочки:
code smarty
{$this->cabinet()->owner()->logo()->thumbnail('128x96')->html_code()}
Не важно, в какой момент возникнет пустой объект (cabinet/owner/logo) — важно, что любая операция от пустого объекта вернёт также пустой объект. И никаких исключений не возникнет.
Нужно проконтролировать, чтобы был обязательно не ноль? Легко добавить в цепочку контролирующий метод, в духе
...->assert()->..., который уже и выбросит исключение в случае ошибки.
К сожалению, усложняется прямая проверка на непустой статус объекта. Увы, записать в PHP:
code php
if(empty($this->target())) ...
уже не получится. Жаль, что в PHP отсутствуют магические методы для empty(). Придётся писать как:
code php
if($this->target()->is_empty()) ...
(и, увы,
...->empty() мы написать тоже не сможем — это недопустимое для метода имя).
Вот тут вылезает одна из серьёзных несовместимостей с BORS1. Потому что придётся реально переписывать массу
if(empty($this->target())). Поэтому я продумываю вариант введения такой логики совершенно отдельным слоем и отдельным набором методов/объектов.