0

Before I describe the issue, please forgive any incorrect terms and accidental references to objects instead of arrays and vice-versa, I'm not completely up to speed on this but working my way through it.

I have the following array in PHP saved as a session variable:

{"CategoryF":[],"CategoryA":["Life","There","People","Land","Family"],"CategoryC":["Various"]}

After a thumbnail in a grid of images is dragged into a new order, it execute a function in javascript and makes a call to a PHP script using ajax. It currently only retrieves the most up to date version of a session array. It will later progress to make the necessary steps to save the updated array back to session variable and database:

var sorty = Sortable.create(thumbcontainer, { 
        animation: 250,
        draggable: "img",
        dataIdAttr: 'id',
        onUpdate: function (/**Event*/evt) {
            var orderList = sorty.toArray();
            var catsArray = 
            $.ajax({
                type: 'POST',
                url: 'includes/proc_cats.php',
                dataType: 'json'
            }).done(function(returnedCatsArray) {
                console.log(returnedCatsArray);
            });
            console.log('Dragged. Order is: ' + orderList);
        }
    });

proc_cats.php

<?php
// Access the existing session
session_start();
// $catsArray is a session variable, in the format as above.
$catsArray = json_encode($_SESSION['categoriesPics']);
echo $catsArray;
?>

The var orderList will produce a string with the order of each thumbnail by id, separated by comma: '42,35,95,12,57'.

The console shows the PHP array as a javascript array fine but in a different order. I want to be able to insert the string containing the orders into the array and save it back into the database. It will associate with its relevant category, similar to:

{"CategoryF":[],"CategoryA":["Life":["23,74,47,12,86,83,12"],"There","People","Land","Family"],"CategoryC":["Various"]}

But can't lose the order as other parts of the site reference the array by indices using array_keys. The console produces:

Object:
   CategoryA:Array[0]
   CategoryC:Array[0]
   CategoryF:Array[5]

Have I missed something? I believe that the overall array is an object rather than an array because it didn't have any index whereas the subcategories did and they get presented as an array. array_keys in PHP have made it straightforward enough to work around any indexing problems up until now on the PHP side in other areas of the site but I'm wondering if the solution for the javascript side is something as straightforward? The subcategories currently have indices only because I've yet to associate and orderList with them so I'm not trying not to backtrack and build an index for the array as it's going to get difficult (unless there's a simple way to do this that I've overlooked).

(This is a more specific version of a question I asked an hour ago that I've now deleted for being too broad).

biscuitstack
  • 10,233
  • 1
  • 20
  • 34

2 Answers2

1

I believe you have a slight confusion based on the terms 'associative array' and 'array'. A php associative array corresponds to a javascript object. returnedCatsArray should be accessed similar to $catsArray. ie. with keys. If one of those keys returns an an actual array, you can then index into it.

php array_keys would be Object.keys(returnedCatsArray) in javascript.

Coburn Berry
  • 242
  • 1
  • 8
  • You're correct, I believed that an associative array was something else. I can get the keys using the method you suggested but was led to believe that I can't rely on guaranteed order being retained in javascript objects. e.g. : http://stackoverflow.com/questions/5525795/does-javascript-guarantee-object-property-order . Now, I believe that a javascript array is also a javascript object. If my console is stating that `returnedCatsArray` is an object containing 3 arrays, should I disregard it being labeled as an object and treat it as an array that I can guarantee getting the correct order from? – biscuitstack Apr 27 '15 at 11:49
  • 1
    returnedCatArray is definitely an object. The contents of Array's referenced within the object will have correct ordering. The Arrays themselves should be accessed by using their keys ie. returnedCatsArray['CategoryC'][5] – Coburn Berry Apr 27 '15 at 15:18
  • But will the top-level arrays in the object retain an order between them? They have no index but retain an reliable order on the PHP side of things. They are keeping order perfectly for me in tests with client-side javascript but the link above suggests I shouldn't rely on this. I need to reach `returnedCatsArray['CategoryC'][5]` from a variable such as `2-5`, which I can do successfully, but need to be sure that this will always be the same result unless I change the order or values myself. – biscuitstack Apr 27 '15 at 15:47
  • yes, `returnedCatsArray['CategoryC'][5]` will always return the correct item. Whether `returnedCatsArray == {categoryA:[] , categoryC: [1,2] }` or `returnedCatsArray == {categoryC:[1,2] , categoryA: [] }` shouldn't matter because you should access it with the keys ie. `returnedCatsArray["categoryC"] == [1,2]` in both cases. The order of the keys is not guaranteed, but they tend to stay in the correct order in practice. – Coburn Berry Apr 27 '15 at 15:58
  • So it looks like they may not keep the order between them (if categoryA and categoryC could potentially switch order like you illustrate)? If I get array keys from a variable like '2-5' I cannot guarantee that the key for `2` will be the same value that PHP would obtain on a different area of the site. This is the problem and why I'm interested in retaining order. – biscuitstack Apr 27 '15 at 16:04
  • `returnedCatsArray['categoryC'][5]` will always equal `$catsArray['categoryC'][5]`. Why do you want to use indexes to get the properties of your associative array? The data structure gives the properties names, why not use them? – Coburn Berry Apr 27 '15 at 16:11
  • This is a small part of a larger admin panel for a site. The admin panel is, in turn, a small part of a larger image portfolio site. Referencing array keys by name throughout the whole site makes little sense to me as the key names change too often dynamically and have too many math operations performed on arrays. For example, I can use far less code to lay out a menu of the categories that is guaranteed to have the same order for each visitor. – biscuitstack Apr 27 '15 at 16:25
0

From further research it appears this is just not doable. So the best way to do this may be to provide an order array alongside my category array.

If I add the additional code of:

$parentCatOrder = array_keys($catsArray);

in my proc_cats.php script I have a concise way of generating an index reference for my original array on the fly each time. This produces an array similar to:

$parentCatOrder = {'categoryF', 'categoryA', 'categoryC'};

which has an index that I can refer to that keeps its order. So $parentCatOrder[2] will always produce 'categoryC' unless I've changed the array myself.

I then return both arrays to javascript using the following:

$return_data['catsarray'] = $catsArray;
$return_data['parentcatsorder'] = $parentCatOrder;
// Encode it back into a JSON object before sending
echo json_encode($return_data);

In javascript I can reference returnedCatsArray.catsarray[returnedCatsArray.parentcatsorder[1]][3] if I'm working with an index of 1-3 and guarantee this will produce the same result for every user unless the array has been changed by the user.

biscuitstack
  • 10,233
  • 1
  • 20
  • 34