gpt4 book ai didi

php - 使用 json_encode 临时存储来自 YouTube 数据 API 的资源

转载 作者:行者123 更新时间:2023-12-03 06:18:35 25 4
gpt4 key购买 nike

我一直在开发一个自定义 WordPress 插件,用于将 YouTube 内容集成到游戏博客中,为了限制每日 API 配额的压力,我一直在尝试想出一种方法来存储过期的临时缓存对象24小时后。

我创建了以下类来管理数据:

public class YouTubeDataCache {
protected $dataObject;
protected $expirationDate;

__construct($dataObject) {
$this->dataObject = $dataObject;
$this->expirationDate = time() + 86400;
}

public function isExpired() {
return $this->expirationDate < time();
}

public function getDataObject() {
return $this->dataObject;
}
}

然后,我调用 json_encode($dataCache)在此类的实例上生成我可以存储在数据库中的实例的 JSON 表示。

但是,一旦我开始对此进行测试,我就注意到了两个重大问题:
  • 尽管验证了 Google 的 API 返回了实际结果,但数据库条目是空白的。
  • 调用json_decode()当我尝试调用 isExpired() 时,从数据库中拉出的字符串返回了未定义方法的 fatal error 在解码的对象上。

  • 我的问题有两个:
  • 如何确保所有必要的数据元素都被编码到 JSON 字符串中?
  • 如何在调用 json_decode() 后保留对对象方法的访问权限? ?
  • 最佳答案

    花了一些时间来追踪这个问题,但这是我想出的解决方案。

    如何在缓存中存储所有必要的数据元素?

    具体细节会因个别用例而略有不同,但要点如下:json_encode()只会编码 公众 变量。

    因为我的$dataObject$expirationDate被定义为 protected , json_encode()无法访问这些值,因此编码了空白对象。哎呀。

    再深入一点,从 YouTube API 返回的对象也包含很多 protected数据元素,所以即使我将类变量更改为 public ,我在尝试存储视频缩略图等内容时仍然会遇到类似的问题。

    最终,我不得不创建自己的序列化函数。

    较新版本的 PHP 可以使用 JsonSerializable接口(interface)并定义一个特定于类的实现,根据文档,“返回可以由 json_encode() 序列化的数据”

    由于我无法准确预测该插件的 PHP 用户将运行哪个版本,我选择只创建一个 toJSON()方法,并修改构造函数以从 $dataObject 中提取特定数据元素.

    一、构造函数/类变量:

    对于我的特定用例,我只关心 ID、片段、状态和缩略图信息。如果您需要其他数据元素,则需要深入研究响应对象的结构,以查看您的序列化函数需要手动包含的内容。

    YouTubeDataCache {
    protected $objectId;
    protected $snippet;
    protected $status;
    protected $thumbnails = array();
    protected $expirationDate;

    __construct($dataObject = null) {
    $this->expirationDate = time() + 86400;

    if ($dataObject === null) {
    return; // I'll explain later
    }

    $this->objectId = $dataObject->getId();
    $this->snippet = $dataObject->getSnippet();
    $this->status = $dataObject->getStatus();

    $thumbs = $dataObject->getThumbnails();

    if ($thumbs->getDefault()) {
    $this->addThumbnail('default', $thumbs->getDefault());
    }
    if ($thumbs->getMedium()) {
    $this->addThumbnail('medium', $thumbs->getMedium());
    }
    if ($thumbs->getHigh()) {
    $this->addThumbnail('high', $thumbs->getHigh());
    }
    if ($thumbs->getMaxRes()) {
    $this->addThumbnail('maxRes', $thumbs->getMaxRes());
    }
    }

    public function setExpirationDate($expirationDate) {
    $this->expirationDate = $expirationDate;
    }

    public function addThumbnail($name, $data) {
    $this->thumbnails[$name] = $data;
    }

    public function getObjectId() {
    return $this->objectId;
    }

    public function setObjectId($objectId) {
    $this->objectId = $objectId;
    }

    public function getSnippet() {
    return $this->snippet;
    }

    public function setSnippet($snippet) {
    $this->snippet = $snippet;
    }

    public function getStatus() {
    return $this->status;
    }

    public function setStatus($status) {
    $this->status = $status;
    }
    }

    注意:这里有一个警告。从技术上讲,缩略图信息包含在 Snippet 中,但它与 protected 相关联。大批。由于我最终需要将其从该数组中拉出,因此在这里执行此操作可为接下来的操作提供更一致的访问模式。

    接下来我添加了自定义序列化方法

    注意:这是一个类方法。我只是为了可读性而把它拉出来
    public function toJSON() {
    $array = array(
    'objectId' => $this->objectId,
    'snippet' => $this->snippet,
    'status' => $this->status,
    'thumbnails' => $this->thumbnails,
    'expirationDate' => $this->expirationDate
    );

    return json_encode($array);
    }

    有了这个功能,我现在可以调用 $cacheObject->toJson()生成数据的准确编码 JSON 表示,然后我可以将其写入数据库,这将我们带到解决方案的第二部分。

    如何保留对缓存对象方法的访问权限?

    原来 json_decode创建一个 stdClass实例或关联数组(取决于您选择调用函数的方式)。在这两种情况下,它都没有最初用于创建 JSON 字符串的类中的任何方法,因此我最终还必须创建自定义反序列化方法。

    我选择制作这个特殊功能 static这样我就不需要缓存对象的实例来使用它。
    public static function fromJSON($json) {
    $data = json_decode($json);

    $cacheObject = new YouTubeDataCache();
    /* This is why the constructor now accepts a null argument.
    I won't always have access to an API response object from
    Google, and in such cases, it's faster to just call setters
    on this class rather than jumping through hoops to create the
    Google class instance. */

    $cacheObject->setExpirationDate($data->expirationDate);
    $cacheObject->setObjectId($data->objectId);
    $cacheObject->setSnippet($data->snippet);
    $cacheObject->setStatus($data->status);

    foreach($data->thumbnails as $name => $thumbnail) {
    $cacheObject->addThumbnail($name, $thumbnail);
    }

    return $cacheObject;
    }

    最终类定义

    仅供引用,这里是一个地方的最终类定义:
    YouTubeDataCache {
    protected $objectId;
    protected $snippet;
    protected $status;
    protected $thumbnails = array();
    protected $expirationDate;

    __construct($dataObject = null) {
    $this->expirationDate = time() + 86400;

    if ($dataObject === null) {
    return;
    }

    $this->objectId = $dataObject->getId();
    $this->snippet = $dataObject->getSnippet();
    $this->status = $dataObject->getStatus();

    $thumbs = $dataObject->getThumbnails();

    if ($thumbs->getDefault()) {
    $this->addThumbnail('default', $thumbs->getDefault());
    }
    if ($thumbs->getMedium()) {
    $this->addThumbnail('medium', $thumbs->getMedium());
    }
    if ($thumbs->getHigh()) {
    $this->addThumbnail('high', $thumbs->getHigh());
    }
    if ($thumbs->getMaxRes()) {
    $this->addThumbnail('maxRes', $thumbs->getMaxRes());
    }
    }

    public function setExpirationDate($expirationDate) {
    $this->expirationDate = $expirationDate;
    }

    public function addThumbnail($name, $data) {
    $this->thumbnails[$name] = $data;
    }

    public function getObjectId() {
    return $this->objectId;
    }

    public function setObjectId($objectId) {
    $this->objectId = $objectId;
    }

    public function getSnippet() {
    return $this->snippet;
    }

    public function setSnippet($snippet) {
    $this->snippet = $snippet;
    }

    public function getStatus() {
    return $this->status;
    }

    public function setStatus($status) {
    $this->status = $status;
    }

    public function toJSON() {
    $array = array(
    'objectId' => $this->objectId,
    'snippet' => $this->snippet,
    'status' => $this->status,
    'thumbnails' => $this->thumbnails,
    'expirationDate' => $this->expirationDate
    );

    return json_encode($array);
    }

    public static function fromJSON($json) {
    $data = json_decode($json);

    $cacheObject = new YouTubeDataCache();

    $cacheObject->setExpirationDate($data->expirationDate);
    $cacheObject->setObjectId($data->objectId);
    $cacheObject->setSnippet($data->snippet);
    $cacheObject->setStatus($data->status);

    foreach($data->thumbnails as $name => $thumbnail) {
    $cacheObject->addThumbnail($name, $thumbnail);
    }

    return $cacheObject;
    }
    }

    关于php - 使用 json_encode 临时存储来自 YouTube 数据 API 的资源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40096303/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com