PHP Stati c Класс автоматического сброса - PullRequest
1 голос
/ 23 января 2020

Я пишу класс, который планирую звонить только статически, и я заметил то, чего не ожидал. Рассмотрим следующий код:

<?php
class Greeting {
  public static $greetingMSG;

  public static function setGreeting(string $greeting){
    self::$greetingMSG = $greeting;
    return new static;
  }

  public static function greet() {
    echo self::$greetingMSG;
  }
}

Greeting::greet();

Greeting::setGreeting('Hello World!')->greet();

Greeting::greet();

?>

Я бы подумал, что первый и третий вызов Greeting::greet(); дал бы одинаковый результат. Вместо этого второй и третий вызов дает одинаковый результат. Я понимаю, что это должно быть потому, что каждый вызов класса Greeting не создает новый экземпляр класса. Я мог бы сделать класс mimi c тем, что ожидал, добавив метод reset().

<?php
class Greeting {
  public static $greetingMSG;

  public static function setGreeting(string $greeting){
    self::$greetingMSG = $greeting;
    return new static;
  }

  public static function greet() {
    echo self::$greetingMSG;
    self::reset();
  }

  private static function reset() {
    self::$greetingMSG = '';
  }
}

Greeting::greet();

Greeting::setGreeting('Hello World!')->greet();

Greeting::greet();

?>

Это ведет себя так, как я ожидал, и "Hello World!" выводится только один раз. Есть ли более техническое объяснение относительно того, что здесь происходит, и является ли метод reset() лучшим способом, чтобы имитировать c того, что я ожидал?

Ответы [ 2 ]

1 голос
/ 23 января 2020

Я понимаю, что это должно быть потому, что каждый вызов класса greeting не создает новый экземпляр класса

Я думаю, что у вас есть базовое c недопонимание о некоторых Основы здесь.

Это не имеет никакого отношения к тому, является ли $greetingMSG stati c или нет. После того как вы установите переменную члена класса, ее значение останется неизменным, пока вы не измените ее. Все последующие вызовы, чтобы вызвать переменную, будут просто повторять значение, которое вы уже установили один раз ранее. Это будет вести себя одинаково, независимо от того, было ли это * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Да, вы можете использовать метод сброса, который очищает значение, если вы хотите, и вы действительно просто делаете ту же работу, что и setGreeting('');.

В любом случае, я не уверен, что цель этого класса в том, чтобы заполниться методами stati c, в первую очередь, или почему у вас есть частный метод сброса. На мой взгляд, это не очень хорошо разработанный класс.

Почему бы не просто обычный класс без методов stati c? Это было бы более гибким и имеет больше смысла. Вот пример нескольких примеров использования:

$greeting = new Greeting('Hello World!');
$greeting->greet();

$greeting->setMessage('Goodbye World!');
$greeting->greet();
$greeting->greet();

$greeting2 = new Greeting();
$greeting2->setMessage('Finished');
$greeting2->greet();

$greeting->greet();

Это печатает в следующем порядке:

Hello World!
Goodbye World!
Goodbye World!
Finished
Goodbye World!

Некоторые замечания по этому поводу:

  1. Таким образом, вы можете иметь несколько экземпляров приветствия с разными сообщениями.

  2. Из моего кода можно сделать вывод, что класс Greeting имеет конструктор, который позволяет вам установить сообщение при создании экземпляра, или вы можете создать пустой и установить сообщение позже с setMessage().

  3. Чтобы показать мою точку зрения о том, как значение переменной остается неизменным, пока вы измените его, обратите внимание, что после того, как мы создадим второй экземпляр Greeting, эхо-сообщение о первом объекте Greeting по-прежнему будет иметь то же значение, что и раньше, поскольку оно все еще не было изменено.

0 голосов
/ 23 января 2020

Свойство $reetingMSG имеет значение stati c, что означает, что его содержимое является общим для всех экземпляров класса приветствия. Позволяет go пройти через:

Первый шаг:

greeting::greet();

Это выведет пустую строку, верно? Поскольку значение $reetingMSG еще не определено.

Второй шаг:

greeting::setGreeting('Hello World!')->greet();

На этом шаге вы определяете значение для свойства $reetingMSG stati c, печатаете его и определите пустую строку как ее значение снова. Тем не менее, вывод будет «Hello, World!».

Третий шаг:

greeting::greet();

Наконец, это снова выведет пустую строку, потому что вы только что определили, что $reetingMSG является снова пустая строка.

...