«phpClub» — архив тем ("тредов"), посвящённых изучению PHP и веб-технологий.
Аноним 2019/03/03 18:27:00  №1358638 1
А вот такое знает кто?
Есть у меня к примеру экшен, который вызывается один раз по умолчанию, когда юзверь заходит на страниц. Потом, когда программа юзверя запомнила, она будет вызывать другой экшен, при заходе на эту же страницу по умолчанию.
Можно ли сделать вот так?

методПоУмолчанию {
if (тутБылЮзверь) {
методПослеПосещения()
}
"Юзверь, зарегистрируйся!"
}

методПослеПосещения {
выводимИнфу()
}

То есть я понимаю, что чисто физически я могу вызвать один метод в другом, но можно ли так делать в MVC шаблоне?
Ответы: >>1358643 >>1359949
Аноним 2019/03/04 13:08:18  №1359022 2
Создал я, значит, сущность юзер, к нему маппер, базу ещё. Заполнился юзер данными, но вот только одна беда, некому оперировать этой сущностью. Какой слой модели вызывает методы этой сущности и возвращает результат контроллеру? Или может контроллер сам это делает?
Ответы: >>1359196 >>1359948
пакетик 2019/03/04 17:44:47  №1359196 3
>>1359022
В операциях чтения ни чего такого нету. Можешь вызывать из контроллера
Ответы: >>1359366
Аноним 2019/03/05 00:08:43  №1359366 4
>>1359196
Мне кажется, хуевый план. А если мне нужно будет этих юзеров рассортировать, пропустить их через валидатор, то где мне это делать? Явно не в контроллере. Опчик, ты ведь знаешь ответ? Взываю к тебе!
Ответы: >>1359392 >>1359394 >>1359949
Аноним 2019/03/06 02:33:51  №1359949 5
>>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 6
>>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 7
>>1360508
>а нужно итеративно и с условиями получить много, тогда что? Нужно будет в контейнере хранить не объект, а класс, а потом внедрять этот класс и там создавать через new?
Хранить в контейнере factory, через нее создавать объекты.
Ответы: >>1360515
Аноним 2019/03/07 00:35:41  №1360515 8
>>1360509
Еще до фабрик не дошел, сейчас самое время, спасибо, анонче.
Аноним 2019/03/10 06:19:53  №1361818 9
>>1360508

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

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

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

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

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

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

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

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

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

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

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