PHP - 将对象数组保存到文件中并重用它 - 获取调用未定义方法错误


PHP - save array of objects to a file and reuse it - getting Call to undefined method error

我在这里发的第一篇文章,所以请耐心等待。

我目前正在做以下工作:我需要用 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)反序列化到此对象中,因此您需要添加某种反序列化方法,该方法将从'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不

返回类型为"entry"的对象,因此会出现错误(返回的对象没有定义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)
}

您的代码需要更正(或使条目实现 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
    }
}

希望对您有所帮助。

亲切问候。