«phpClub» — архив тем ("тредов"), посвящённых изучению PHP и веб-технологий.
Аноним 2019/03/04 13:08:18  №1359022 1
Создал я, значит, сущность юзер, к нему маппер, базу ещё. Заполнился юзер данными, но вот только одна беда, некому оперировать этой сущностью. Какой слой модели вызывает методы этой сущности и возвращает результат контроллеру? Или может контроллер сам это делает?
Ответы: >>1359196 >>1359948
пакетик 2019/03/04 17:44:47  №1359196 2
>>1359022
В операциях чтения ни чего такого нету. Можешь вызывать из контроллера
Ответы: >>1359366
Аноним 2019/03/05 00:08:43  №1359366 3
>>1359196
Мне кажется, хуевый план. А если мне нужно будет этих юзеров рассортировать, пропустить их через валидатор, то где мне это делать? Явно не в контроллере. Опчик, ты ведь знаешь ответ? Взываю к тебе!
Ответы: >>1359392 >>1359394 >>1359949
Аноним 2019/03/05 05:37:07  №1359392 4
>>1359366
Операции чтения стейт приложения не меняют.
Поэтому их может быть очень много.
Аноним 2019/03/05 05:44:26  №1359394 5
>>1359366
что тебя смущает я не понимаю.
class Controller
{
private $search;
public function __construct(Search $search)
{
$this->search = $search;
}

public function index()
{
$result = $this->search->search();
}

}
Аноним 2019/03/06 02:33:28  №1359948 6
>>1354838

Он зато лаконичный. И там есть IPython Notebook - отличнейшая штука. Но отсутствие тайп-хинтов, конечно, убивает.

>>1359625

Вернет в любом случае то, что указано в тайп-хинте, в нестрогом режиме при этом допускает автоматическую конвертацию в int.

>>1359071

Можно как 3 функции, можно как 3 класса, можно как 3 метода в одном классе. Метод может принимать экземпляр Компании и делать с ней какие-то операции.

>>1359022

Зависит от того, как сделана работа с БД. Если у тебя используется дата маппер, то в нем и будет метод для загрузки моделек из БД.

> Какой слой модели вызывает методы этой сущности и возвращает результат контроллеру? Или может контроллер сам это делает?

Вызывать метод загрузки данных может контроллер. Либо сервис, который загружает данные из БД и делает какие-то еще преобразования.
Ответы: >>1360508
Аноним 2019/03/06 02:33:51  №1359949 7
>>1359366

Зависит от ситуации. Контроллер должен быть тонким, то есть в основном в нем вызовы разных сервисов (тех же мапперов) для получения разных данных и передача их во View. Для валидации можно сделать отдельный класс-валидатор. Для сортировки - если это что-то простое, нужно только для вывода и не повторно используемое, то делаем в контроллере. В задаче про студентов сортировку логично сделать аргументом в методе для получения студентов:

findStudents($searchBy, $orderBy, $orderDir, $offset, $limit): iterable

Этот метод может быть в маппере для работы с БД.

В таком случае мы можем получать отсортированный список студентов из любого места кода.

Контроллер отвечает за управление процессом обработки запроса, за интерпретацию команд пользователя. То есть контроллер как-то (например, из $_GET) определяет, какая сортировка нужна пользователю, и вызывает метод для загрузки студентов с сортировкой по данному полю. А затем передает найденных студентов во View и отдает пользователю сгенерированную HTML страницу.

>>1358638

Обычно это делают так:

class Controller
{
public function indexAction(Request $req)
{
if (!$this->isLoggedIn($req)) {
return $this->redirectTo(...);
}

...
}
}

То есть перед выполнением нужных действий проверяем наличие логина. При отсутствии - редирект на форму логина с передачей текущего URL (и проверкой, что он с нашего сайта). На форме логина пишется: "Чтобы XXX, вам надо зарегистрироваться, или ввести логин и пароль, если вы уже зарегистрированы". При желании можно как-то заморочиться и например, сделать проверку на уровне контроллера (то есть закрыть доступ ко всем методам этого контроллера сразу). Это удобно в админке, например.

В твоем варианте пользователь может попробовать обойти авторизацию, вызвав напрямую метод "методПослеПосещения".
Ответы: >>1360508
Аноним 2019/03/07 00:13:51  №1360508 8
>>1359945
>Реестр - это паттерн, который описыв
Спасибо, исчерпывающий ответ. Написал бы ты всеобъемлющую книгу по всем этим аспектам. Они ведь не устаревают. Будет пользоваться популярностью.

>>1359946
>У меня просто времени иногда нет, последние пару недель адски загружен.

А можно узнать, чем ты занимаешься? В студии трудишься или в каком-нибудь банке софт ваяешь?

>Ни в коем случае. Идея DI контейнера - IoC - предполагает
Хорошо, проблему синглтона контейнер решает.
А вот еще вопрос. Создал я класс подключения к мускулу, сделал для него сервис-провайдер, где он создается, а потом внедряю его, куда нужно.

А вот, скажем, мне нужен не один объект, а нужно итеративно и с условиями получить много, тогда что? Нужно будет в контейнере хранить не объект, а класс, а потом внедрять этот класс и там создавать через new?

>Я думаю, сервис провайдеры и сервисы хранятся в отдельных папках.

Спасибо, теперь все понятно.

>>1359948
Если у тебя используется дата маппер, то в нем и будет метод для загрузки моделек из БД.

То есть вообще всем управляет маппер, а сущности это такие пассивные ячейки памяти, к которым маппер обращается, и сущность сама по себе ничего делать не должна? И в контроллере правильно будет вызывать именно методы маппера?

>>1359949
> В задаче про студентов сортировку логично сделать аргументом в методе для получения студентов:

Спасибо за разъяснение особенно за последний абзац и за метод, ты сэкономил мне кучу времени.

>То есть перед выполнением нужных действий проверяем наличие логина. При отсутствии - редирект на форму логина с передачей текущего URL

А можно такую проверку делать в конструкторах? Например, в общий абстрактный контроллер засунуть. А то не делать же ее в каждом методе (боль, лол). И если юзверь не залогинен, то просто будет редирект на контроллер залогинивания, который этот конструктор не наследует.

>В твоем варианте пользователь может попробовать обойти авторизацию, вызвав напрямую метод "методПослеПосещения".

Но у него не получится, если я объявлю этот метод закрытым. Можно вообще все методы сделать закрытыми и вызывать их через indexAction, в котором сформировать настройки и всякие проверки. Сигнатуру формировать по маршруту. Получится эдакий фронт контроллер, только не физический файл, а метод. Но это что-то идиотское, да? Лол.

>Не думал, что у файлообменника такая сила. Сейчас, вроде начинающие разработчики делают сокращатели ссылок, но это уже неприлично просто.

А это разве не проще, чем файлообменник? Там ведь просто идет редирект на реальный URI при обращении к твоей ссылке. За вечер-другой можно сделать.

>>1359951
>Обычно делают отдельно шаблон для "лейаута" (шапка/подвал) и "контента". Лейаутов может быть несколько - например, один для морды, другой для админки. Как передавать параметры для лейаута? Тут есть варианты:


Я придумал вот что. Я в контроллере общем создал контейнер обычный массив data, куда записываю данные со всех уголков контроллеров и приходящие данные из моделей. В контроллерах-родителях задаю общие данные, в контроллерах специфичные, в методах контроллеров данные еще специфичнее. Данные записываются не через переопределение свойств, а через методы суперкласса.
Потом этот контейнер передаю в вид и обращаюсь к нему из шаблонов типа $data['title'], foreach($data['posts'] as $key => $post) {}, ну и все в таком духе. То есть "лейаут" и "контент" получаются данные из одного глобального массива data, переданного в вид. Так нормально?

>Не очень понятно, как это. Вызывать из одного шаблона другие шаблоны можно.

Ну я имел ввиду, можно ли несколько "контентов" подключать в "лейаут".

Спасибо за ответы, ты будто чистое знание вливаешь мне прямо в мозг. Я, бывает, что-то очень долго ищу, бывает, несколько дней занимает поиск ответа на какой-то вопрос, иногда бывает сам додумываюсь до ответа, но проблема в том, что я не знаю, правильный он или нет. Но вот так очень круто зайти сюда и прочитать ответы на все, что я задавал. Пасиба.
Ответы: >>1360509 >>1361818
Аноним 2019/03/07 00:15:56  №1360509 9
>>1360508
>а нужно итеративно и с условиями получить много, тогда что? Нужно будет в контейнере хранить не объект, а класс, а потом внедрять этот класс и там создавать через new?
Хранить в контейнере factory, через нее создавать объекты.
Ответы: >>1360515
Аноним 2019/03/07 00:35:41  №1360515 10
>>1360509
Еще до фабрик не дошел, сейчас самое время, спасибо, анонче.
Аноним 2019/03/10 06:19:53  №1361818 11
>>1360508

> А можно узнать, чем ты занимаешься?

Просто обычная удаленная работа.

> А вот, скажем, мне нужен не один объект, а нужно итеративно и с условиями получить много, тогда что? Нужно будет в контейнере хранить не объект, а класс, а потом внедрять этот класс и там создавать через new?

Можно хранить фабрику (класс, создающий нужные объекты), можно в контейнере сделать метод, который позволяет создавать объекты с параметрами. Но вообще, надо подумать, а нужны ли в таких объектах зависимости? Обычно, если это объект типа "Пользователь", у них нет зависимостей и их можно просто создавать через new. То есть такие "сущности" обычно в контейнер не кладут.

> То есть вообще всем управляет маппер, а сущности это такие пассивные ячейки памяти, к которым маппер обращается, и сущность сама по себе ничего делать не должна? И в контроллере правильно будет вызывать именно методы маппера?

Если ты читал мой урок https://github.com/codedokode/pasta/blob/master/db/patterns-oop.md то знаешь, что есть ACtiveRecord, где сущности умеют сами себя сохранять в БД и Data Mapper, где они не умеют.

Второй подход имеет тот плюс, что ты в принципе можешь где-то (например, для теста) создавать сущности, не имея базы данных и использовать их. То есть код работы с БД отделен от кода сущностей и от кода, который использует эти сущности. Ты можешь в теории создать просто массив этих сущностей и весь остальной код даже не заметит, что у тебя не подключена БД (только в теории, на практике часто это не работает, так как код все равно пытается что-то искать и загружать из БД).

> А можно такую проверку делать в конструкторах?

Плохая идея, из конструктора нельзя возвращать значения, да и он не для этого. Но ты можешь сделать метод вроде beforeRequest() и обязательно его вызывать из фронт-контроллера.

> Я придумал вот что. Я в контроллере общем создал контейнер обычный массив data, куда записываю данные со всех уголков контроллеров и приходящие данные из моделей. В контроллерах-родителях задаю общие данные, в контроллерах специфичные, в методах контроллеров данные еще специфичнее. Данные записываются не через переопределение свойств, а через методы суперкласса.

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