【问题标题】:Converting PHP object to JSON object using only Javascript仅使用 Javascript 将 PHP 对象转换为 JSON 对象
【发布时间】:2016-03-06 22:51:21
【问题描述】:

我正在使用 Phonegap 制作一个移动应用程序,并使用 Wordpress 作为后端。我正在使用带有 Google Maps 帖子字段的高级自定义字段,该字段使用 JSON API 将 PHP 对象返回给应用程序。我的 Wordpress 后端向应用程序发送一个普通的 JSON 对象,但在该对象内部是一个字符串化的 PHP 对象被返回的地方。

我需要在客户端(不在 Wordpress 中的应用程序)以某种方式将 PHP 对象转换为 JSON 对象。我已经查看了其他说要为此使用json_encode 的答案,但我的问题是该应用程序只是 HTML/Javascript 而没有 PHP。有没有办法在 Javascript 函数中间使用 PHP 代码来做到这一点?还是最好更改后端以便它首先返回 JSON 对象而不是 PHP 对象?如果是这样,我该怎么做?

我在 PHP 方面的经验仍然有限,因此不胜感激。

编辑:为了澄清一点,我在与我的 Phonegap 应用程序不同的域上使用 Wordpress,并且仅在 Wordpress 端使用 JSON API 插件。然后我使用 jQuery Ajax 调用从 Wordpress 后端检索数据。

返回的 PHP 对象也如下所示:a:3:{s:7:\"address\";s:48:\"8915 W 159th St, Orland Hills, IL, United States\";s:3:\"lat\";s:17:\"41.60111599999999\";s:3:\"lng\";s:11:\"-87.8364575\";}

我刚刚想到的另一种方法是,是否可以将其保留为 PHP 对象并仍然以某种方式从中读取值?我不需要它是一个 JSON 数组,我只需要一种方法以一种或另一种方式读取数组中的各个元素。

这也是返回的 JSON 的一个小 sn-p,以澄清我在说什么。

"custom_fields": { "location": [ "a:3:{s:7:\"address\";s:48:\"8915 W 159th St, Orland Hills, IL, United States\";s:3:\"lat\";s:17:\"41.60111599999999\";s:3:\"lng\";s:11:\"-87.8364575\";}" ] }

这当然不是整个 JSON 对象,但它让您了解我正在处理的内容。

【问题讨论】:

  • 我已经做过很多次了,但遗憾的是没有使用 JSON API 插件,所以在您的特殊情况下我无能为力。但是,从您显示的 PHP 内容来看,它必须是 unserialized,然后才能将其传递给您的插件。您显示的是字符串,而不是 PHP 对象。
  • @Hobo 是的,抱歉,我将编辑帖子以澄清这一点,它是一个经过标记的 PHP 对象。基本上发生的事情是 JSON API 插件返回一个包含所有帖子的常规 JSON 对象,但在包含有关地图信息的属性中的该对象内部由于某种原因以 PHP 形式返回。
  • 好的,明白了。所以 ACF 没有反序列化数据的设置?我仍然认为在服务器上反序列化比尝试在客户端上进行反序列化要好得多。 ACF 是否在该字段上有一个可以挂钩的过滤器?如果没有,您是否可以在拥有对象后取消序列化该字段(例如$obj->map_data = unserialize($obj->map_data)?抱歉,如果语法关闭,我已经有一段时间没有用 PHP 编码了
  • @Hobo 我不相信 ACF 具有返回普通 JSON 对象的内置方法,因为我认为它不是为此而设计的。我必须添加一些我在网上找到的额外 PHP 代码来获取 JSON API 来返回 ACF 字段。我现在将尝试四处寻找,看看是否可以找到该属性的返回位置,并尝试按照您所说的去做。
  • 好吧,这更有意义。这是一个 json 数组中的 PHP 对象,请参阅stackoverflow.com/a/29519646/1876047 问题是它已被转义。因此,您首先要从位置列表中提取对象,这可以通过解码 json 结构来完成。之后你想去掉斜线,我相信 PHP 有一个 strip_slashes 方法?完成后,您应该能够使用 unserialize() 方法并恢复 PHP 对象。然后,要将其传递给您的客户端应用程序,只需使用 json_encode 将其重新编码为 JSON。希望这是有道理的:)

标签: javascript php json wordpress advanced-custom-fields


【解决方案1】:

我知道你有一个可以在前端运行的解决方案,但我仍然认为最好在服务器上解决这个问题。

根据我们在 cmets 中的对话,我仔细查看了 the code in the WordPress forum。问题似乎是location 字段是一个字符串数组,而不仅仅是一个字符串。 maybe_unserialize(和它使用的is_serialized)不处理数组。这是更新后的代码,您应该可以将其放入主题的functions.php。我做了一个快速测试,它对我有用。

class unserialize_php_arrays_before_sending_json {
    function __construct() {
        add_action( 'json_api_import_wp_post',
            array( $this, 'json_api_import_wp_post' ),
            10,
            2 );
    }

    function json_api_import_wp_post( $JSON_API_Post, $wp_post ) {
        foreach ( $JSON_API_Post->custom_fields as $key => $custom_field ) {
            if (is_array($custom_field)) {
                $unserialized_array = array();
                foreach($custom_field as $field_key => $field_value) {
                    $unserialized_array[$field_key] = maybe_unserialize( $field_value );
                }
                $JSON_API_Post->custom_fields->$key = $unserialized_array;
            }
            else {
                $JSON_API_Post->custom_fields->$key = maybe_unserialize( $custom_field );
            }
        }
    }
}

new unserialize_php_arrays_before_sending_json();

【讨论】:

    【解决方案2】:

    如果您使用 JSON API 来检索数据,那么为什么不将 JSON 格式的数据传送到您的应用程序?否则,您似乎首先删除了使用 API 的大部分意义......如果您真的想要,当然可以在 JavaScript 中解析该字符串,但这是一个非常丑陋且容易出错的解决方案。

    JSON API 插件似乎确实使用了 JSON:

    https://wordpress.org/plugins/json-api/screenshots/

    【讨论】:

    • 是的,我知道这将是一个更好的解决方案,但就像我说的,我不太了解 PHP,所以我什至不确定在哪里做,我自己没有编写 API ,我正在使用插件。你能指出我正确的方向吗?是的,JSON API 插件确实返回了完整的 JSON,但在 JSON 对象内部是字符串化的 PHP 对象所在的位置,这就是我获取该对象的方式。
    • 如前所述,您只有一个字符串,没有别的。这是一个序列化数组,您需要先取消转义然后再取消序列化。这是一个可能对你有用的 JS 函数:phpjs.org/functions/unserialize
    • 效果很好!我宁愿让 Wordpress 返回一个普通的 JSON 对象,但在我得到它之前我会使用它。谢谢!
    【解决方案3】:

    我需要在客户端(不在 Wordpress 中的应用程序)以某种方式将 PHP 对象转换为 JSON 对象。

    这里的这一点让我感到困惑。您在客户端没有 PHP 对象,PHP 是一种后端技术。返回给客户端的是一个字符串,可以是 HTML、XML、JSON、任何其他编码形式的纯文本。

    也就是说,假设您在 PHP 中有一个对象 $obj,您可以将它传递给您的前端应用程序,创建一个端点 retrieve_object.php 并在其中:

    echo json_encode($obj);
    

    只要这是您输出的唯一内容,您的客户端应用程序就可以向retrieve_object.php 发出请求(例如:AJAX)并获取json 对象。

    BUT ,这对于序列化对象属性很重要(!)。您将丢失任何 PHP 对象方法。如果任何对象属性是对象本身(例如:数据库连接),那么它也会丢失。

    希望这会有所帮助!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-01-07
      • 1970-01-01
      • 2015-01-02
      • 2013-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多