php json - 以返回的数组顺序显示问题(json 排序)

Posted

技术标签:

【中文标题】php json - 以返回的数组顺序显示问题(json 排序)【英文标题】:php json - Issue display in returned array order (json sort) 【发布时间】:2016-09-01 01:46:48 【问题描述】:

简介:

我有 2 个下拉菜单。第二个下拉列表通过 json (json_display.php) 基于第一个下拉列表 (index.html) 的值加载。我已经使用 json - append() 来加载下拉列表。

问题:

json append() 到下拉列表总是按数组键的升序排列。预期结果是以json_display.php 返回的任何数组顺序的格式显示。

我有警报 jquery theResponse,显示错误的排序顺序。 我已经尝试将数组键作为整数和字符串,在这两种情况下,输出也是相同的。

注意:

(其实我是在尝试按日期降序检索 mysqli 行并将id => name 存储在数组中并返回)

为简单起见,我已将代码的问题部分提取到index.htmljson_display.php,它们是更大编码的一部分。还将 mysql 检索更改为数组。为了便于说明,名称和所有值都已更改。

图解说明


index.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Test</title>
<script type="text/javascript" src="//code.jquery.com/jquery-1.11.0.min.js"></script>
<script type="text/javascript" src="//code.jquery.com/jquery-migrate-1.2.1.min.js"></script>

<script type="text/javascript">
$(document).ready(function()

    $("#frm").on('change', ' #first_select_box', function()
        var $this    = $(this);
        var this_val = $this.val();

        $('#second_select_box option').not(':eq(0)').remove();

        $.ajax(
            type     : "POST",
            url      : "json_display.php",
            data     :  first_select_id: this_val ,
            dataType : 'json',
            success  : function(theResponse) 

                //alert(JSON.stringify(theResponse));

                $.each(theResponse, function(key, value) 
                    $('#second_select_box')
                    .append($("<option></option>")
                    .attr("value",key)
                    .text(value));
                );
            

        );

    );
); 
</script>
</head>

<body>

<form id="frm" name="frm" method="post" action="#a">

<select id="first_select_box" name="first_select_box">
<option value="0">[First Drop Down]</option>
<option value="1">Numbers</option>
<option value="2">Fruits</option>
<option value="3">Teens</option>
</select>

<select id="second_select_box" name="second_select_box">
<option value="0">[Select]</option>
</select>

</form>

</body>
</html>

json_display.php

<?php
$Array[0] = array();
$Array[1] = array(10 => 'Ten', 
                  9  => 'Nine', 
                  8  => 'Eight', 
                  7  => 'Seven', 
                  6  => 'Six', 
                  5  => 'Five', 
                  4  => 'Four'
                  );

$Array[2] = array(8 => 'Apple', 
                  1 => 'Orange', 
                  3 => 'Banana', 
                  2 => 'Watermelon', 
                  7 => 'Lemon'
                  );

$Array[3] = array(17 => 'Seventeen', 
                  11 => 'Eleven', 
                  13 => 'Thirteen', 
                  15 => 'Fifteen', 
                  12 => 'Twelve', 
                  14 => 'Fourteen', 
                  16 => 'Sixteen'
                  );

$first_select_id      = isset($_POST['first_select_id']) ? $_POST['first_select_id'] : 0;

$return_array = $Array[$first_select_id];

echo json_encode($return_array);

?>

【问题讨论】:

问题是????? 这是浏览器中javascript的行为,你可以将键(值)作为字符串标识符传递吗?这将维持秩序 @Thamizhan 你的意思是把钥匙当作字符串吗,我也试过了。 @Devs Yes.. 尝试在其上附加一个字符,例如 D1@1 【参考方案1】:

使用array_flip()函数交换数组中的键值

改变

echo json_encode($return_array);

echo json_encode(array_flip($return_array));

你会得到预期的结果。

【讨论】:

array_flip() 是用值交换键。问题不在于数组翻转。它的 jquery 会自动按 theResponse 的升序对键进行排序【参考方案2】:

它显示正确,因为json_display.php 发送到index.htmljson_display.php 发送索引数组,因此它显示正确。例如查看您的第一个索引$Array

$Array[1] = array(10 => 'Ten', 
                  9  => 'Nine', 
                  8  => 'Eight', 
                  7  => 'Seven', 
                  6  => 'Six', 
                  5  => 'Five', 
                  4  => 'Four'
                  );

这意味着$Array[1]10th 索引将具有Ten 值等等。因此,当涉及到 JS 时,它已经编入索引并将显示 Four 作为第一个选项,Ten 作为最后一个选项。您需要将数组键括在引号中。所以以你的例子为例,你的数组应该像这样转换

$Array[1] = array('10' => 'Ten', 
                  '9'  => 'Nine', 
                  '8'  => 'Eight', 
                  '7'  => 'Seven', 
                  '6'  => 'Six', 
                  '5'  => 'Five', 
                  '4'  => 'Four'
                  );

这应该可以解决您的订单问题。希望对您有所帮助。

更新:

由于所有浏览器仍然索引数组数字键,IMO 唯一的选择是发送正确的索引数组。例如 php 应该以下列格式发回数组

Array[1] = array(0 =>array("key"=>10, "value"=> 'Ten'), 
                  1 =>array("key"=>9, "value"=> 'Nine'),
                  2 =>array("key"=>8, "value"=> 'Eigth'),
                  3 =>array("key"=>7, "value"=> 'Seven'),
                  4 =>array("key"=>6, "value"=> 'Size'),
                  5 =>array("key"=>5, "value"=> 'Five'),
                  6 =>array("key"=>4, "value"=> 'Four'),
                  );

然后在index.html中需要修改响应码为。

$.each(theResponse, function( index, obj ) 
                $('#second_select_box')
                .append($("<option></option>")
                .attr("value",obj.key)
                .text(obj.value));
            );

这可能会有所帮助 How do you stop Chrome and Opera sorting JSON objects by Index ASC?

【讨论】:

我已经尝试过将数组键作为字符串,结果是一样的。 @Devs 好的,我测试过,如果数字键用引号引起来,浏览器似乎仍会对其进行索引,因此在我看来,唯一的选择是使用正确的索引更新数组。我会更新我的答案。【参考方案3】:

在将密钥发送到浏览器之前,在密钥后面加上空格。这个 json 现在不会被排序。 它是一种默认行为,无论您以何种顺序发送数据,都会对键进行排序。但是,如果通过在键之前附加空格将它们作为字符串给出,它们将不会被排序。

【讨论】:

这是个好建议。如果可以做任何其他可能性而不是将id 更改为数据库中的动态唯一ID,将不胜感激。【参考方案4】:

使用下面的代码可以获得所需的结果,但我不确定是否有更好的方法。

json_display.php

<?php
$Array[0] = array();
$Array[1] = array(10 => 'Ten', 
                  9  => 'Nine', 
                  8  => 'Eight', 
                  7  => 'Seven', 
                  6  => 'Six', 
                  5  => 'Five', 
                  4  => 'Four'
                  );

$Array[2] = array(8 => 'Apple', 
                  1 => 'Orange', 
                  3 => 'Banana', 
                  2 => 'Watermelon', 
                  7 => 'Lemon'
                  );

$Array[3] = array(17 => 'Seventeen', 
                  11 => 'Eleven', 
                  13 => 'Thirteen', 
                  15 => 'Fifteen', 
                  12 => 'Twelve', 
                  14 => 'Fourteen', 
                  16 => 'Sixteen'
                  );

$first_select_id      = isset($_POST['first_select_id']) ? $_POST['first_select_id'] : 0;

$return_array_temp = $Array[$first_select_id];
$return_array = array();
foreach ($return_array_temp as $key => $value) 
    $return_array[$key." "] = $value;

echo json_encode($return_array);

?>

index.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Test</title>
<script type="text/javascript" src="//code.jquery.com/jquery-1.11.0.min.js"></script>
<script type="text/javascript" src="//code.jquery.com/jquery-migrate-1.2.1.min.js"></script>

<script type="text/javascript">
$(document).ready(function()

    $("#frm").on('change', ' #first_select_box', function()
        var $this    = $(this);
        var this_val = $this.val();

        $('#second_select_box option').not(':eq(0)').remove();

        $.ajax(
            type     : "POST",
            url      : "json_display.php",
            data     :  first_select_id: this_val ,
            dataType : 'json',
            success  : function(theResponse) 

                //alert(JSON.stringify(theResponse));

                $.each(theResponse, function(key, value) 
                    $('#second_select_box')
                    .append($("<option></option>")
                    .attr("value",key.trim())
                    .text(value));
                );
            

        );

    );
); 
</script>
</head>

<body>

<form id="frm" name="frm" method="post" action="#a">

<select id="first_select_box" name="first_select_box">
<option value="0">[First Drop Down]</option>
<option value="1">Numbers</option>
<option value="2">Fruits</option>
<option value="3">Teens</option>
</select>

<select id="second_select_box" name="second_select_box">
<option value="0">[Select]</option>
</select>

</form>

</body>
</html>

【讨论】:

这不起作用,因为浏览器仍然按升序索引它,因为键是数字的。不管你是否用引号括起来。 @Devs 我已经更新了我的答案,这可能会帮助您解决问题【参考方案5】:

我遇到了类似的问题。我的 C# 应用程序允许用户覆盖表中值列表的默认排序顺序,因此传递回 javascript 的数据不一定按字母或数字顺序。当数据离开我的 MVC 控制器操作时,数据的顺序正确,但是在检查返回给浏览器的响应时,列表已按数字键排序。

由于我需要我的选择列表选项按照用户指定的顺序排列,我尝试按照 Thamilan 的建议在密钥的开头添加一个空格,但不幸的是,这不起作用。仅仅添加任何旧字符也是行不通的,因为它仍然会根据字母数字排序规则对其进行排序,而且我根本不希望它被排序。

因此,我在循环中添加了一个计数器,该计数器添加到返回给浏览器的列表中,并在计数器的值前面加上一个“。”到我的键,因为它被添加到列表中,所以当我返回到浏览器时,我返回的列表看起来像这样:

这确保了字母数字排序始终按照我特意创建的顺序进行。所以我在 javascript 中所要做的就是根据我的应用程序的要求为选项列表提取正确的键值。为此,我只是删除了前缀计数器和“。”使用拆分从我的密钥:

var optionValue = xhrKey.split(".")[1]; 

生成的选择列表与从我的控制器返回的顺序相同,并且为选择列表中的选项分配了正确的值。

【讨论】:

以上是关于php json - 以返回的数组顺序显示问题(json 排序)的主要内容,如果未能解决你的问题,请参考以下文章

Ajax以JSON访问从PHP返回的多维数组

ajax接收返回二维数组的json数据后显示为null

numpy.ndenumerate 以 Fortran 顺序返回索引?

如何在 Jquery 中使用 JSON?

修改PHP代码以获取sql输出的相反顺序?

PHP json_encode($arr) 为啥会改变数组的顺序,怎么解决。在线等