【问题标题】:How to json_encode php array but the keys without quotes如何json_encode php数组但没有引号的键
【发布时间】:2012-11-11 12:03:46
【问题描述】:

我正在尝试(使用Flot)绘制带有一些数据的饼图

var data = <?php echo json_encode($data)?>

我得到的结果是这样的:

var data = [
{"label":"Crear Usuario", "data":"2"},
{"label":"Impresoras", "data":"1"},
{"label":"Problema Correo", "data":"1"},
{"label":"Requisicion Equipo", "data":"1"},
{"label":"Sitio Web", "data":"1"}
]

这里的问题是我需要不带引号的labeldata,我已经尝试过json_encode($data, JSON_NUMERIC_CHECK);,但只删除了数字中的引号。

以下格式是我需要的:

var data = [
    {label:"Crear Usuario",data:2}, ...

【问题讨论】:

  • 你想在 php 中进行这种转换吗?
  • 嗯,我认为 PHP 的转换会更好,是的。
  • 为什么要不带引号?,带或不带引号是等价的(尽管不带引号不是 JSON)。
  • @Musa:这就是 Flot 需要格式化对象的方式:/
  • 我很确定问题出在其他地方。

标签: php javascript arrays flot json


【解决方案1】:

首先,您必须在 php 中生成数组,因此数据的值是整数,而不是字符串:

我从你的 json_encode() 模拟了你的数组,我猜它看起来像这样(或者应该这样):

$array =  array(
                array("label" => "Crear Usuario",   "data" => 2),
                array("label" => "Impresoras",      "data" => 1),
                array("label" => "Problema Correo", "data" => 1),
                array("label" => "Requisicion Equipo", "data" => 1),
                array("label" => "Sitio Web", "data" => 1)
            );

    $data = json_encode($array);
  • 请注意,2 和 1 不带引号,因此它们是整数,这一点很重要。

那么你在 Javascript 中错过了 JSON.parse() 以实际将输出转换为 json 对象:

<script>
    var data = '<?php echo $data; ?>';
    var json = JSON.parse(data);
    console.log(json);
    console.log(json[0]);
</script>
  • 请注意 var data = ... 是单引号,因此您可以将 php 的回显作为字符串捕获

console.log() 为我输出这个:

[Object, Object, Object, Object, Object] // First console.log(): one object with the 5 Objects. 
Object {label: "Crear Usuario", data: 2} // secons console log (json[0]) with the first object 

看起来像你需要的,对吗?

【讨论】:

  • 只有var data = &lt;?php echo $data; ?&gt;;(去掉了单引号)会做同样的事情——不需要在客户端解析
【解决方案2】:

带引号和不带引号的键没有区别。问题在于对实际数据值的引用,因为 Flot 需要数字,而不是字符串。

json_encode 函数根据您提供的数据类型决定是否引用。在这种情况下,看起来您为创建 $data 执行的任何操作都在生成字符串值而不是整数。您需要重新检查这些操作,或者明确告诉 PHP 将它们解释为数字,使用 (int) 或 (float) 转换,或 intval/floatval 函数。

【讨论】:

    【解决方案3】:

    试试这样的:

    function buildBrokenJson( array $data ) {
    
       $result = '{';
    
       $separator = '';
       foreach( $data as $key=>$val ) {
          $result .= $separator . $key . ':';
    
          if( is_int( $val ) ) {
             $result .= $val;
          } elseif( is_string( $val ) ) {
             $result .= '"' . str_replace( '"', '\"', $val) . '"';
          } elseif( is_bool( $val ) ) {
             $result .= $val ? 'true' : 'false';
          } else {
             $result .= $val;
          }
    
          $separator = ', ';
       }
    
       $result .= '}';
    
       return $result;
    }
    

    当运行时

    $a = array("string"=>'Crear "Usuario', 'foo'=>':', "int"=>2, "bool"=>false);
    var_dump( buildBrokenJson($a) );
    

    它给出:

    string(54) "{string:"Crear \"Usuario", foo:":", int:2, bool:false}"
    

    【讨论】:

    • 我想要不带引号的“标签”一词,以及“数据”。
    • 这些是字符串类型。将被引用。您可以编写自己的 json_encode - 应该不难(我现在正在打电话)
    【解决方案4】:

    我创建了一个类来用 php 格式化 json,键上没有引号是它

    class JsonFormatter
    {
    static $result = '';
    static $separator = '';
    
    public static function iterateArray($data) : string
    {
        static::$result .= '[';
        static::$separator = '';
        foreach ($data as $key => $val) {
            if (is_int($val)) {
    
            } elseif (is_string($val)) {
                static::$result .= '"' . str_replace('"', '\"', $val) . '"';
            } elseif (is_bool($val)) {
                static::$result .= $val ? 'true' : 'false';
            } elseif (is_object($val)) {
                static::iterateObject($val);
                static::$result .= ', ';
            } elseif (is_array($val)) {
                static::iterateArray($val);
                static::$result .= ', ';
            } else {
                static::$result .= $val;
            }
            if (!is_int($val)) {
                static::$separator = ', ';
            }
        }
    
        static::$result .= ']';
        return static::$result;
    }
    
    public static function iterate($data)
    {
        if (is_array($data)) {
            static::iterateArray($data);
        } elseif (is_object($data)) {
            static::iterateObject($data);
        }
        return static::$result;
    }
    
    public static function iterateObject($data)
    {
        static::$result .= '{';
        static::$separator = '';
        foreach ($data as $key => $val) {
    
            static::$result .= static::$separator . $key . ':';
    
            if (is_int($val)) {
                static::$result .= $val;
            } elseif (is_string($val)) {
                static::$result .= '"' . str_replace('"', '\"', $val) . '"';
            } elseif (is_bool($val)) {
                static::$result .= $val ? 'true' : 'false';
            } elseif (is_object($val)) {
                static::iterate($val, true);
                static::$result .= ', ';
            } elseif (is_array($val)) {
                static::iterateArray($val, true);
                static::$result .= ', ';
            } else {
                static::$result .= $val;
            }
            static::$separator = ', ';
        }
        static::$result .= '}';
        return static::$result;
    }
    
    }
    

    你现在可以打电话了

    $jsonWithoutKeyQuotes  = JsonFormatter::iterate($data);
    

    感谢 Marcin Orlowski

    【讨论】:

      【解决方案5】:

      TL;DR:缺少引号是 Chrome 显示它是 JSON 对象而不是字符串的方式。确保您有 Header('Content-Type: application/json; charset=UTF8');在PHP的AJAX响应中解决真正的问题。

      详情: 想要解决这个问题的一个常见原因是在调试返回的 AJAX 数据的处理时发现了这种差异。

      就我而言,我使用 Chrome 的调试工具看到了不同之处。当连接到旧系统时,成功后,Chrome 根据调试器显示响应中的键周围没有引号。这允许在不使用 JSON.parse() 调用的情况下立即将对象视为对象。调试我的新 AJAX 目标时,响应中显示了引号,变量是字符串而不是对象。
      当我在外部测试 AJAX 响应时,我终于意识到了真正的问题,发现遗留系统实际上确实在键周围有引号。这不是 Chrome 开发工具所显示的。 唯一的区别是在遗留系统上有一个标头指定内容类型。我将此添加到新的(WordPress)系统中,调用现在与原始脚本完全兼容,并且成功函数可以将响应作为对象处理,而无需任何解析。现在我可以在旧系统和新系统之间切换,而无需更改目标 URL。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-07-16
        • 1970-01-01
        • 1970-01-01
        • 2011-06-18
        • 2013-02-23
        • 2014-02-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多