сохранить массив объектов в файл и использовать его повторно — получение ошибки Call to undefined method

Моя первая запись здесь, так что будьте терпеливы со мной.

В настоящее время я делаю следующее: мне нужно написать гостевую книгу с 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)

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

1

Решение

Если вы хотите сериализовать объект через 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());
}
}
1

Другие решения

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
}
}

Надеюсь, поможет.

С уважением.

0

По вопросам рекламы [email protected]