A
A
Alexey Konovalov2018-04-27 22:39:04
PHP
Alexey Konovalov, 2018-04-27 22:39:04

How to call the correct class?

Hello! Help me understand how best to call the desired class.
I will simplify the presentation of the question to a few modules on the site ... Let's say the site has modules: comment, posts, users .
Each module has its own set of features (like for comments and posts, subscription for the user, etc.). Let's just take like as an example.
My likes are set according to the principle: the type of the object and its ID are sent to a single file on the server like.php . So by liking post 333 , the like.php file gets the value: type == post and id == 333
Further, for each type of object there are classes that are responsible for generating the notification object in the database. those. When setting the like post to 333 , the like.php file must create an object of the LikePost class and call the createNotify method passing the necessary parameters to it. Here is how I do it now:

// это файл 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;
      //..... и т.д.
    }
//.........

Everything works out for me, everything works, but the code turns out to be very scattered, it turns out that if you can subscribe to an object, like it, add a comment, share it. Then in each such file as like.php , I need to create such checks. And when adding some new type of object to the site, do not forget to add it all for each such file, in addition, changing the name of the object type, I will need to look for it in each tick file and rename it.
As far as I understand, this is not the right approach, but I can’t think of another, so I ask you to explain how this is all beautifully done in reality?

Answer the question

In order to leave comments, you need to log in

3 answer(s)
Y
Yan-s, 2018-04-28
@Yan-s

It is difficult to understand what you have there in general.
Wouldn't it be better to implement the required interfaces directly on Post objects? That is, we execute $post->like() and the post already starts the creation of the like object with the necessary parameters. We get rid of a lot of long switches, when a new type of object is added, interfaces are implemented directly in it.
Read the patterns https://refactoring.guru/en/design-patterns , I think you will find a combination that will solve your problem.

I
Ilya, 2018-04-27
Hrebet @hrebet

For example:

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

But be careful with the incoming data)

A
Alexander Kubintsev, 2018-05-04
@akubintsev

Need whitelist $object_type to fix security issue.
In principle, you started doing just that, only the switch-case option is cumbersome.
Much better to do a view mapping

$classMap = [
    'some_input_obj_type' => RealClassName::class,
    'another_input_obj_type' => RealAnotherClassName::class,
];

And then use the construct:
if (!isset($classMap[$object_type])) {
    //какой-то код возвращающий ошибку
}
$class = $classMap[$object_type];
$class::someMethod('some args1');

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question