Задать вопрос
@Evdokim001
PHP & WordPress developer

Как вызывать метод один раз а потом запоминать его значение?

Добрый день. В PHP записал класс
Class Neptun(){
  private function method1(){
    $users_count = get_users();
    return $users_count;
  }
  private function method2(){
    if($this->method1 > 10){
        return 'it more than 10';
     }
   }
private function method3(){
    if(in_array(10, $this->method1())){
         return 'there are user with ID 10';
     }

public function finish(){
   echo $this->method2() . ' ' . $this->method3();
}
}

В таком пример method 1 запускает функцию get_users() 2 раза. Как сделать чтобы функция get_users() сработала только 1 раз а во всех остальных случаях подставлялась статическая переменная? Надеюсь, объяснил все правильно)
  • Вопрос задан
  • 322 просмотра
Подписаться 1 Простой 5 комментариев
Решения вопроса 2
@Akela_wolf
Extreme Programmer
Статическая переменная в функции. И проверять - если не null - то возвращать её значение. Это один из самых простых вариантов кэширования. При наличии у функции аргументов - статический массив.

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

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

По второму случаю у вас в коде нарушение принципа единственности ответственности: функции method2 и method3 жестко связаны (coupled) с функцией method1 (а функция finish - с ними всеми). Собственно это и порождает проблему. Код можно переписать, например так:
сlass Neptun(){
  private function method1(){
    $users_count = get_users();
    return $users_count;
  }

  private function method2($users){
    if($users > 10){
        return 'it more than 10';
     }
   }

  private function method3($users){
    if(in_array(10, $users)){
         return 'there are user with ID 10';
    }
  }

  public function finish(){
    $users = $this->method1();
     echo $this->method2($users) . ' ' . $this->method3($users);
  }
}


Все, функции method2 и method3 "расцеплены" (decoupled) с функцией method1. А "сборку" в общую конструкцию осуществляет публичный метод finish
Ответ написан
Compolomus
@Compolomus Куратор тега PHP
Комполом-быдлокодер
сделайте типо кэш, результат метода записывайте в свойство, и при обращению к методу, проверяйте существует ли свойство с данными, если нет, то выполняйте метод и записывайте свойство, иначе просто отдавайте данные из свойства
Можно запилить какой нибудь магический метод, если таких методов с кэшем несколько, и добавлять этот кэш автоматически, даже можно вынести в трейт например. Если нужен пример, могу нарисовать
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

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

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