会话数组的排序未按预期输出

usort of session array not outputting as expected

我有一个 img 正方形网格,可以使用可排序库将其拖入任何顺序。每个 img 都是 mySQL 数据库查询结果的可视化表示,该查询选择共享 'imageparent' 标识符的任何图像。它们在网格中的显示顺序取自数据库中的 'imageorder' 列,从 0 开始,按顺序工作,直到返回的第 n 个图像。

拖动img格子的目的是为了能够改变'imageorder'索引。拖动完成后,可排序库 POSTS 一个 'imageorder' var 从 ajax 到 service.php 并被正确接收。因此,它发送的不是原始的 0,1,2,3,4,5,6,7 顺序,而是像 2,1,0 这样的字符串,3,4,5,7,6。不太难掌握。在我切换顺序后,发送到 service.phporderList var 始终是正确的,但是我最终发送到数据库并设置为我的会话 var 的数组在第二个或第三个之后顺序变得有点乱码拖,我不太清楚为什么。

代码示例和注释


$_SESSION['selectedCsImages']数组结构:

[0] => Array
    (
        [imagename] => "Title"
        [imageorder] => 0
        [imageid] => 43
    )

[1] => Array
    (
        [imagename] => "Title"
        [imageorder] => 1
        [imageid] => 21
    )

[2] => Array
    (
        [imagename] => "Title"
        [imageorder] => 2
        [imageid] => 3
    )
etc...

Services.php 摘录:

if (session_status() == PHP_SESSION_NONE) {
    session_start();
}
// Turn the orderList posted into an array
$removeChars = array('"','[',']');
$orderList = str_replace($removeChars, "", $_POST['order']); // POST received fine.
$listArray = explode(",",$orderList);
// Retrieve the session array
$sorting = $_SESSION['selectedCsImages'];

/* My logic is that I compare the $sorting array to $listArray and reorder $sorting by 'imageorder' to match $listarray */
usort($sorting, function($a, $b) use ($listArray) {
    return array_search($a['imageorder'], $listArray) - array_search($b['imageorder'], $listArray);
});
/* I now have a $sorting array that (sometimes, hence the problem) matches the order that the images had just been dragged into by the user. Typically, as I mentioned above, it's correct after the first drag, but not always after the second or third where it creates a new order that I can't see a pattern or logic in. */

/* Had there not been errors with the usort function, I (would) have a $sorting array in the order I want but with imageorder values referring to pre-sorting. I iterate through the array and set each key to 0, 1, 2, etc. so that I have an array in the correct order and with each imageorder correctly stating its place.*/

$i = 0;
foreach ($sorting as $key => $value) {
    $sorting[$key]['imageorder'] = $i;
    $i++;
}

/* The information is attempted to be sent to the db and, on success I update the session var */
// Database code (runs succesfully and updates the db as per the image orders found in the $sorting array)
$_SESSION['selectedCsImages'] = $sorting;

调试中:


从调试来看,当我第二次或第三次从 ajax 调用此页面时,usort 函数似乎发生了一些问题。在此之后的一切都很好,并按照预期处理正确或不正确的订单。 sortable 发布的 orderList var 每次都是正确的。我会在每次 usort 之后提供一个 $sorted var 的样本,但是按照我在拖动后没有指定的顺序来描述它就像上面的数组示例一样简单,而且我看不到模式它输出的顺序看似随机。

通过研究,我认为这是一个问题,因为会话变量在页面刷新之前一直保留,但似乎 ajax 对 services.php 的调用应该刷新 $_SESSION['selectedCsImages'] 变种。我还读过,也许我在不知不觉中使用了引用的数组值,并且-当我从会话变量获取新数组并最终从该数组保存回该会话变量时-我可能创建了一些混乱的引用反馈.但是,我在尝试 usort 之前尝试使用 $sorted = (array)clone(object)$_SESSION['selectedCsImages'];,结果没有改变。

PHP 错误日志未显示任何内容。

更新:


根据@Ayaou 的建议,我检查了 $listArray 的输出并得到了一些意想不到的结果。我错误地认为,由于发布的 $orderList 是正确的,所以分解数组不会是罪魁祸首。

这是完成以下 16 个 img 元素的顺序交换后 print_r($listArray) 的输出:第 1 与第 2、第 2 最后与最后、第 6 与第 7:

1st and 2nd:
(
    [0] => 1
    [1] => 0
    [2] => 2
    [3] => 3
    [4] => 4
    [5] => 5
    [6] => 6
    [7] => 7
    [8] => 8
    [9] => 9
    [10] => 10
    [11] => 11
    [12] => 12
    [13] => 13
    [14] => 14
    [15] => 15
)

last and 2nd last:
(
    [0] => 1
    [1] => 0
    [2] => 2
    [3] => 3
    [4] => 4
    [5] => 5
    [6] => 6
    [7] => 7
    [8] => 8
    [9] => 9
    [10] => 10
    [11] => 11
    [12] => 12
    [13] => 13
    [14] => 15
    [15] => 14
)

6th with 7th:
(
    [0] => 1
    [1] => 0
    [2] => 2
    [3] => 3
    [4] => 4
    [5] => 6
    [6] => 5
    [7] => 7
    [8] => 8
    [9] => 9
    [10] => 10
    [11] => 11
    [12] => 12
    [13] => 13
    [14] => 15
    [15] => 14
)

我的想法是 $listArray 会显示连续的 0、1、2、3 等。每次只有两个交换的项目显示订单更改。事实上,我将再次回顾 $orderList 并检查我的可排序库是否正在更新它从更新的会话变量中正确获取的订单。较旧的订单掉期被保留在链条中不应保留的地方。

解决方案在您的 sortable 表单(在前端)上,因此不要在您的 'order' post 数据上发送 imageorder,而是发送 imageid索引.

然后像这样更改排序回调

//Use imageid index instead of imageorder
usort($sorting, function($a, $b) use ($listArray) {
        return array_search($a['imageid'], $listArray) - array_search($b['imageid'], $listArray);
    });