За последние 24 часа нас посетили 22402 программиста и 1142 робота. Сейчас ищут 636 программистов ...

Вопрос про ООП

Тема в разделе "Прочие вопросы по PHP", создана пользователем vintbolt, 5 сен 2021.

  1. vintbolt

    vintbolt Новичок

    С нами с:
    6 авг 2021
    Сообщения:
    6
    Симпатии:
    0
    Кто подскажет, куда копать в поисках инфы??
    Напишу на примере,так будет понятнее.
    Имеется класс View где-то в ядре с публичными интерфейсами
    PHP:
    1. public function show($template)
    и
    PHP:
    1. public function with($variables)
    . Т.е show грубо говоря возвращает(подключает) какое-либо представление, а with передает туда переменные. Т.е вызовы вида
    PHP:
    1. View::show('main')->with(['var' => 'value'])
    . Вопрос: существуют ли способы, чтобы сначала выполнялся код в методе with, а уже потом show, который производит шаблон и передает туда переменные из with? Без сохранения состояния метода with(), а на лету. Может какие-то технологии, про которые я еще не слышал?
     
    #1 vintbolt, 5 сен 2021
    Последнее редактирование: 5 сен 2021
  2. don.bidon

    don.bidon Активный пользователь

    С нами с:
    28 мар 2021
    Сообщения:
    861
    Симпатии:
    132
    А зачем?
     
  3. vintbolt

    vintbolt Новичок

    С нами с:
    6 авг 2021
    Сообщения:
    6
    Симпатии:
    0
    чтоб писать красивые публичные интерфейсы(методы) для классов...
    в приведенном мной примере сначала выполнится код метода show(), которые во своей сути возвращает какой-либо файл с представлением..соответственно следующий за ним метод with() будет бесполезен, т.к. представление уже вернулось....
    В ларавеле это как то реализовано, или там эти методы и данный класс просто формируют все данные, а шаблоны возвращает уже какой-то другой класс
     
  4. don.bidon

    don.bidon Активный пользователь

    С нами с:
    28 мар 2021
    Сообщения:
    861
    Симпатии:
    132
    Не смотрел их код, полагаю, View::show() возвращает класс View с установленном свойством $template, а не распаршенный шаблон, и метод View::with() возвращает уже распаршенный шаблон.
    И вообще, не вижу смысла в методе View::with(), когда скоуп можно передать сразу в View::show() вторым необязательным параметром, ибо незачем плодить лишние сущности.
     
    vintbolt нравится это.
  5. vintbolt

    vintbolt Новичок

    С нами с:
    6 авг 2021
    Сообщения:
    6
    Симпатии:
    0
    Да. Но если нам нужно вызвать шаблон без переменных, то мы использует только View::show() без with().
    В общем я пришел к выводу, что просто нужен еще один метод, который и возвращает шаблон, и использован где-то в другом месте кода(скрыт подальше от глаз) после того как мы уже добавили данные с помощью View::show()->with() или просто View::show().
    Можно конечно. Но мне просто было интересно как в ларавеле обрабатываются такие цепочки. Думал что существует может какая-то возможность "заглянуть в будущее", т.е чтоб при вызовах View::show()->with() я в методе show мог сразу узнать что мне передано в метод with, т.е обработать вызов сзада наперёд грубо говоря...Но это из мира фантастики...
     
  6. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.072
    Симпатии:
    1.237
    Адрес:
    там-сям
    ну вот зачем ты так! :D если выкинуть это искусственное ограничение, то всё делается без проблем.

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

    потом, когда нам понадобится получить результат, например строковое представление шаблона, мы вызовем явный или неявный "конечный" метод, который вернёт уже не $this этого объекта , а нужные данные, сгенерированные на основе его внутренних переменных.
    для шаблонизатора таким методом может быть _toString().

    покажу упрощенно без реализации фасада, т.к. это отдельный класс:

    PHP:
    1. // вызовы методов можно менять местами, а with можно вызвать несколько раз с разными данными, они будут накапливаться
    2. // в конце концов echo неявно обратится за строкой к _toString()
    3. echo (new View)->show('main')->with(compact('product', 'user'));
    4.  
    5. class View
    6. {
    7.   private $template;
    8.   private $data = [];
    9.  
    10.   public function show($template)
    11.   {
    12.     $this->template = $template;
    13.     return $this;
    14.   }
    15.  
    16.   public function with($data)
    17.   {
    18.     $this->data = array_merge($this->data, $data);
    19.     return $this;
    20.   }
    21.  
    22.   public function __toString()
    23.   {
    24.     return $this->render($this->template, $this->data);
    25.   }
    26.   // ...
    27. }
    в случае Laravel, контроллер должен вернуть объект соответствующий контракту ViewContract. поэтому в самом контроллере мы не видим вызова render() или чего-то вроде того. этот объект будет использован для рендеринга уже где-то в недрах фреймворка.

    точно так же работает реализация eloquent / query builder. есть "конечные" методы вроде get() и first(), и есть "присваивающие" методы вроде where() и orderBy(). пока не вызван конечный метод, можно в цепочке вызывать присваиватели в любой очередности. только конечный метод вызовет конструктор запроса SQL на основе сохранённых параметров.
     
    vintbolt нравится это.
  7. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.072
    Симпатии:
    1.237
    Адрес:
    там-сям
    я думаю что в недрах фреймворка происходит что-то такое
    PHP:
    1. // нам нужен объект типа Response, а контроллер может вернуть разные данные
    2. // - готовый Response (например RedirectResponse)
    3. // - строку
    4. // - объект, соответствующий контракту ViewContract
    5. $result = $controller->$action(...$params);
    6. if ($result instanceof Response) {
    7.   return $result;
    8. }
    9. // для объектов приведение к строке вызовет магический метод _toString()
    10. return new Response((string) $result);
     
    vintbolt нравится это.
  8. vintbolt

    vintbolt Новичок

    С нами с:
    6 авг 2021
    Сообщения:
    6
    Симпатии:
    0
    Хорошо описал. Да, действительно, эти методы нужны по сути для установки данных и должны возвращать ничто иное как текущий объект($this), т.к мы их юзаем в цепочке. А потом где то уже мы просто вызываем явно или неявно метод, который служит для возврата собранных данных. Вроде все просто, но что-то не подумал об этом, а начал надумывать какую-то фигню, чтоб идти по кратчайшему пути) Спасибо за инфу!