Из-за тега JavaScript я предполагаю, что вы пишете реализацию палача, которая использует запросы AJAX. Если это предположение верно, то это ваше утверждение является таким же ложным, как может быть:
PS. библиотека вызывается только один раз, поэтому __construct
не проблема.
PHP не имеет гражданства. Это означает, что для каждого запроса, который получает сервер, ваш экземпляр создается, а когда отправляется ответ, все изменения во всех экземплярах теряются. В результате, вот что такое Аякса управляемый поток выглядит следующим образом:
[request 1] => new Word --> constructor initialize $usrAnswer to ['_','_','_']
initialize $answer to ['C', 'A', 'T']
=> destroy instances and resources
=> send response
[request 2] => guess a letter (send via AJAX)
=> new Word --> constructor is called, same as request 1
=> update $usrAnswer
=> destroy instance
=> send response
[request 3] => see [request 2]
[request N] => see [request 2]
Что вам нужно сделать, то есть иметь JavaScript отправить полное состояние угадали ответ на каждый запрос, а не только одну букву. Что-то вроде следующего объекта будет делать:
var requestData = {
state: {
validGuesses: ['A'],
invalidGuesses: ['X', 'Q'] //<-- number of attempts, check if current guess is not a duplicate
},
guess: 'C'
};
Затем на стороне сервера (в PHP), изменить конструктор, чтобы принимать аргументы (массив в этом случае будет делать). Как и в сторону, код ниже применяет coding standards, который я очень рекомендую вам следовать, тоже:
public function __construct(array $userState = array())
{
$this->answer = ['C', 'A', 'T'];
$this->usrAnswer = ['_','_','_'];
foreach ($userState as $value) {
$key = array_search($value, $this->answer);
if ($key === false) {
//handle invalid state, I'd suggest:
throw new InvalidArgumentException(
sprintf('%s is not a valid answer', $value)
);
}
$this->usrAnswer[$key] = $value;
}
}
Теперь, когда вы звоните guess
, значение $usrAnswer
будет правильным.
Update:
Чтобы прояснить мой последний комментарий (о добавлении $answer
аргумента конструктора), вот что я хотел бы сделать:
public function __construct($answer = 'CAT', array $state = [])
{
$this->answer = str_split(strtoupper($answer));//ensure upper-case, create array
//create array containing the correct amount of _ chars
$this->usrAnswer = array_fill(0, strlen($answer), '_');
foreach ($state as $value) {
$key = array_search($value, $this->answer);
if ($key === false) {
throw new InvalidArgumentException(
sprintf('%s is not a valid answer', $value)
);
}
$this->usrAnswer[$key] = $value;
}
//replace _ with dash, if the answer contains dashes (eg ice-cream)
$pos = -1;
while (($pos = strpos($answer, '-', $pos +1)) !== false) {
$this->usrAnswer[$pos] = '-';
}
}
Что касается использования класса, то, ничего действительно меняется:
$cat = new Word();
для когда Ajax запрос должен обработки исключения:
$cat = new Word('cat', $state);//where $state is the request data
Другой пример:
$iceCream = new Word('ice-cream', ['C', 'A']);
//sets usrAnswer to _C_-C__A_
$iceCream->guess('I');
//usrAnswer is now IC_-C__A_
Спасибо вам большое, я не знал об этом, спасибо за обстоятельный ответ, который я должен изучить его! –
@JoeSmith: Добро пожаловать. PS: Я также предлагаю вам разрешить второй аргумент в вашем конструкторе передать значение '$ answer' экземпляру:' public function __construct ($ answer, array $ userState = []); ', тогда вы можете использовать длина '$ answer' для создания массива' $ usrAnswer', что делает ваш класс более гибким. –
@JoeSmith: Обновлен мой ответ, но чтобы получить дополнительную информацию о том, как вы можете улучшить свой класс, лучше всего представить свой код [по обзору кода] (http://codereview.stackexchange.com). Сайт только что закончил бета-стадию, и стоит посмотреть –