@Alk90
php, mysql, jquery, css, html, api

Как правильно вызвать нужный класс?

Всем привет! Помогите понять как лучше всего вызвать нужный класс.
Я упрощу изложение вопроса до нескольких модулей на сайте... Допустим, на сайте есть модули: комментарий, посты, пользователи.
Для каждого модуля есть свой набор возможностей (лайк для комментариев и постов, подписка для пользователя и т.д.). Возьмем для примера только лайк.
Лайки у меня ставятся по принципу: тип объекта и его ID отсылается к единому файлу на сервере like.php. Значит ставя лайк для поста 333, файл like.php получает значение: type == post и id == 333

Далее, для каждого типа объекта есть свой классы, которые отвечают за генерацию объекта уведомления в БД. т.е. Устанавливая лайк посту 333, файл like.php должен создать объект класса LikePost и вызвать метод createNotify передавая в него нужные параметры. Вот как я это делаю сейчас:
// это файл like.php

//.........

switch($object_type){
	// проверяем тип объекта и вызываем метод создания уведомления нужного класса
	case 'post':
		/* 
		* т.к. файл like.php знает только тип и ID объекта
		* то уже внутри класса LikePost вызывается модель (в этом случае поста)
		* и получаем ID автора поста, чтобы записать его вместе с уведомлением как
		* получателя этого уведомления
		*/
			LikePost::createNotification($auth->user_id, $object_id);
				break;
		case 'comment':
			// тот же смысл что при type == post
			LikeComment::createNotification($auth->user_id, $object_id);
				break;
		case 'news':
			// тот же смысл что при type == post
			LikeNews::createNotification($auth->user_id, $object_id);
				break;
			//..... и т.д.
		}
//.........


У меня все получается, все работает, но код получается очень разбросанным, выходит что если на объект можно подписаться, поставить лайк, добавить комментарий, поделиться. То в каждом таком файле как like.php, мне нужно создавать такие проверки. И при добавлении на сайт какого-то нового типа объекта не забывать добавлять это все по каждому такому файлу, кроме того, изменяя название типа объекта, мне нужно будет в каждом тиком файле искать его и переименовывать.
На сколько я понимаю - это не правильный подход, но другого я придумать не могу, поэтому прошу объяснить, как на самом дела это все красиво делается?
  • Вопрос задан
  • 137 просмотров
Пригласить эксперта
Ответы на вопрос 3
@Yan-s
Сложно понять что у вас там в целом.

Не лучше ли будет реализовать нужные интерфейсы непосредственно на объектах типа Post? То есть выполняем $post->like() а пост уже запускает создание объекта лайк с нужными параметрами. Избавляемся от множества длинных свитчей, при добавлении нового типа объекта реализуются интерфейсы непосредственно в нем.

Почитайте паттерны https://refactoring.guru/ru/design-patterns я думаю найдете комбинацию, которая решит вашу проблему.
Ответ написан
Например:

$class_name = 'Like'.mb_strtoupper($object_type);
$class_name::createNotification($auth->user_id, $object_id);

Но будьте осторожны с входящими данными)
Ответ написан
akubintsev
@akubintsev
Опытный backend разработчик
Нужен вайт-лист $object_type, чтобы решить проблему безопасности.
В принципе вы так и начали делать, только вариант через switch-case громоздкий.
Гораздо лучше сделать маппинг вида
$classMap = [
    'some_input_obj_type' => RealClassName::class,
    'another_input_obj_type' => RealAnotherClassName::class,
];


А далее использовать конструкцию:
if (!isset($classMap[$object_type])) {
    //какой-то код возвращающий ошибку
}
$class = $classMap[$object_type];
$class::someMethod('some args1');
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы