Моя первая запись здесь, так что будьте терпеливы со мной.
В настоящее время я делаю следующее: мне нужно написать гостевую книгу с php. У меня есть форма, с которой новые записи представляются. Запись представлена классом:
class entry{
private $name;
private $email;
private $text;
...
construct-method and a output() method for html code
...
function getName()
{return $this->name;}}
Когда форма отправлена, я вызываю «addToGuestbook.php», где я зачитываю $ _POST [..] и создаю новую запись:
$ent = new entry($name, $email, $text);
Поскольку я хочу сохранить запись для дальнейшего использования, я помещаю ее в массив и сохраняю с помощью json:
$entries = json_decode(file_get_contents('entries.json'), false);
$entries[] = $ent;
file_put_contents("entries.json",json_encode($entries));
После этого я хочу манипулировать одной из html-страниц, поэтому я включаю файл функции и вызываю функцию …
include "functions.php";
setUpSingleEntries();
… в котором я перебираю сохраненный массив
$entries = json_decode(file_get_contents('entries.json'), false);
foreach($entries as $entry)
{
if($entry->getName() == $name)
{
fwrite($file, $entry->output());
}
}
Когда я запускаю все это, я получаю Call to undefined method stdClass::getName() in C:\XAMPP\htdocs\ex9\functions.php on line 32
ошибка, а какая строка 32
if ($ entry-> getName () == $ name)
Я почти закончил, поскольку я пытаюсь закодировать гостевую книгу уже несколько дней, и я не могу устранить эти ошибки — также, поскольку я не нашел решения для этого здесь.
Если вы хотите сериализовать объект через JSON, вы должны сначала реализовать JsonSerializable интерфейс. Предполагая, что вы используете PHP 5.4+ (что вам нужно):
class Entry implements \JsonSerializable
{
private $name;
private $email;
private $text;
public function jsonSerialize()
{
return array(
'name' => $this->name,
'email' => $this->email,
'text' => $this->text
);
}
}
Это будет сериализовать ваш объект как ассоциативный массив. Тем не менее, вы не можете десериализовать (json_decode
) непосредственно в этот объект, поэтому вам нужно будет добавить какой-нибудь метод unserialize, который создаст объект для вас из \stdClass
, Например:
class Entry implements \JsonSerializable
{
private $name;
private $email;
private $text;
// assuming you have a constructor like this
public function __construct($name, $email, $text)
{
$this->name = $name;
$this->email = $email;
$this->text = $text;
}
public function jsonSerialize()
{
return array(
'name' => $this->name,
'email' => $this->email,
'text' => $this->text
);
}
public static function fromStdClass(\stdClass $entry)
{
// here you can do some validation if $entry actually has these properties
return new self($entry->name, $entry->email, $entry->text);
}
}
Теперь вы можете использовать код так:
$entries = json_decode(file_get_contents('entries.json'), false);
foreach ($entries as $entry) {
$entryObj = Entry::fromStdClass($entry);
if ($entryObj->getName() == $name) {
fwrite($file, $entryObj->output());
}
}
json_decode не возвращает объекты типа «запись», поэтому ошибка (возвращенный объект не имеет метода getName, он также не имеет метода вывода).
От php.net
<?php
$json = '{"a":1,"b":2,"c":3,"d":4,"e":5}';
var_dump(json_decode($json));
var_dump(json_decode($json, true));
?>
будет выходить
object(stdClass)#1 (5) {
["a"] => int(1)
["b"] => int(2)
["c"] => int(3)
["d"] => int(4)
["e"] => int(5)
}
array(5) {
["a"] => int(1)
["b"] => int(2)
["c"] => int(3)
["d"] => int(4)
["e"] => int(5)
}
Ваш код нуждается в исправлениях (или заставьте Entry реализовать JsonSerializable, как это предлагается в других ответах):
$entries = json_decode(file_get_contents('entries.json'), false);
foreach($entries as $obj)
{
if($obj->{'name'} == $name)
{
fwrite($file, /*Something else*/);// $entry->output() won't work, figure something else out
}
}
Надеюсь, поможет.
С уважением.