2

I realise there are a few other questions regarding this and I have read them and attempted the solutions however they are not working for me. It may be because I am serializing the post twice because I am passing the entire form serialized by jQuery/JavaScript.

My PHP array is a 2 dimensional? one containing filenames:

$aDocumentFilesArrayFileName[0][0];

I generally have 1 dimensional arrays in my PHP so I pass them by using:

<input type="hidden" name="arrayName[]" value="$value[$i]"> // (while in a loop

I am not sure what syntax I should use when I reference the first array in terms of name and also what value I should use.

I've tried to use the value as: serialize($aDocumentFilesArrayFileName) and decode at the other end but I get an error saying string expected found array?

** EDIT **

I think I could have made the question clearer but just to clarify. Here is my jQuery Ajax submit function:

var conflictData = $("input, select", conflictsTable.fnGetNodes()).serialize(); // fnGetNodes is just a datatables function to go through every row in a table - don't worry about that

$.ajax(
{
    type: 'POST',
    url: 'sqlHandleConflictsDocumentRegister.php?node='+nodeType+'&id='+nodeId,
    cache: false,
    data: conflictData,
    success: function(result)
    {
        // Do stuff here
    }
});

I have tried the solution to use json_encode rather than serialize on my PHP input statement. That isn't working. Here is the exact code I use in the PHP form. Please be aware that this line is within a loop that occurs for each row of the table in the form.

<input type="hidden" name="arrayFileName[]" value="<?php echo json_encode($aDocumentFilesArrayFileName[$i]); ?>">

Here is the code I use on the PHP ajax script:

$fileNames = json_decode($_POST['arrayFileName']);

Error is: json_decode() expects parameter 1 to be string, array given in C:\wamp\www\document\sqlHandleConflictsDocumentRegister.php on line 65

Is the problem that I am serializing (in JavaScript) varying dimensions of array data? My other inputs are from rows that have simple array data (one value for each row) and they work fine. This particular array input has an unlimited number of filenames associated per table row, so the input value is an array.

I also pass the value of the quantity of files (per table row) in another input. Perhaps I can use this to help extract the array on the other side.

<input type="hidden" name="quantityFiles[]" value="<?php echo $aDocumentQuantityFiles[$i]; ?>">

** UPDATE **

I used alert(conflictData) and found that the array data is fine apart from it is empty for the arrayFileName field. If I echo json_encode($aDocumentFilesArrayFileName[$i]) then I get the expected result.

Hence, it looks as if the jQuery serialize() is destroying this data. Perhaps there is a way I can prepare the data variable better for ajax submission?

** UPDATE 2 **

Thank you all for your assistance and contributions to the answer. I was already using json_encode to get the data into javascript for operating on it there so I have abandoned using an input field to serialize and send the data and instead directly used the data parameter of $.ajax to send the array for processing.

As there was no distinctly correct solution provided I have posted a solution below and will mark it as the correct answer since I am now able to obtain the multidimensional array data in the destination PHP file.

James Pitt
  • 451
  • 2
  • 8
  • 19

3 Answers3

1

Serialize over ajax(user involved) opens a range of security vulnerability's because the user could make you unserialize a object and try to execute that.

Try to use the appropriate function json, http://php.net/manual/en/book.json.php. Json is the way to go for using with Ajax(Javascript).

Simplect
  • 286
  • 1
  • 4
  • I have edited the question. I'm not sure how serialize over ajax is vulnerable? It is used all the time in solutions on stackoverflow. – James Pitt Jun 13 '13 at 15:35
  • https://www.owasp.org/index.php/PHP_Object_Injection There you go. and here is a extended presentation: http://turbochaos.blogspot.nl/2013/06/exploiting-exotic-vulnerabilities.html Also note that you used json_decode instead of json_encode that will give you the expected string but given array error because json_decode "decodes" a string into it's original form . json_encode "encodes" a variable/array etc. into a string (but i think you already know that) – Simplect Jun 14 '13 at 07:09
  • Thanks - I'll have a read. As for the json_encode / json_decode I think you may have misread. I encode on the source side and decode at destination, surely that is correct? – James Pitt Jun 14 '13 at 07:39
  • Yes that is correct, but when you get the error "Error is: json_decode() expects parameter 1 to be string, array given" the function did not get a proper Json string. But you already fixed that i just read. About the data that gets destroyed, do you have the same result using Json? – Simplect Jun 14 '13 at 07:59
  • I couldn't manage to read the presentation due to the file format, however I have read the first link and it seems this refers more to code injection, SQL injection and other factors rather than vulnerability in the serialize function. Not to criticise, but a lot of responses on SO diversify from the original question to point out security vulnerabilities. So often however the advice is given without knowledge of where the software is to be used, the users, and also whether additional sanitation code has been removed from the examples. This seems far more critical to me. Still encoding is a + – James Pitt Jun 14 '13 at 08:05
  • Yes, to be fair I'm not sure why it was giving me that error when I suppose there was no data to be found. I'm sure it is the JavaScript / jQuery Serialize that is losing me the multi dimensional array data. – James Pitt Jun 14 '13 at 08:08
1

You can use json_encode function of php to send php array to javascript.

Please use

echo json_encode($phpArray);

and you have to set last parameter of $.post() is 'json' if you are using $.post() method or if you are usig $.ajax() method than you have to set

dataType: 'json'

http://api.jquery.com/jQuery.post/

Abhishek
  • 689
  • 3
  • 14
  • I have updated the question with what I have tried so far with json_encode. I think $.ajax auto detects type anyway and I'm using javascript serialized data to push the other values so perhaps this is what is causing the method to fail? – James Pitt Jun 13 '13 at 15:38
  • try php unserialize instead of json_decode. http://php.net/manual/en/function.unserialize.php – Abhishek Jun 13 '13 at 15:50
  • @ahbi - still get unserialize() expects parameter 1 to be string, array given – James Pitt Jun 13 '13 at 15:55
  • please have a look at http://stackoverflow.com/questions/8890524/pass-array-to-ajax-request-in-ajax?lq=1 – Abhishek Jun 13 '13 at 16:15
  • Thanks - I have read that one but I need to gain a better understanding of how to manage my multidimensional array. These are regular arrays and the formatting of the $.ajax data variable doesn't take into account that I am passing several other serialized input values (also basic arrays). – James Pitt Jun 14 '13 at 07:49
0

jQuery serialize works fine for regular arrays but not multidimensional arrays in this scenario. It seems to corrupt when mixing the data from various arrays.

Solution:

json_encode the multidimensional PHP array data and pass to javascript using the code below:

<script>
    var aQuantityFiles = <?php echo json_encode($aDocumentQuantityFiles); ?>; // this is a regular array which is also related to the multidimensional array
    var aDocumentFilesArrayFileName = <?php echo json_encode($aDocumentFilesArrayFileName); ?>; // this is a multidimensional array
</script>

Use the data parameter in the $.ajax request to individually pass the prepared javascript variable:

$.ajax(
{
    type: 'POST',
    url: 'sqlHandleConflictsDocumentRegister.php?node='+nodeType+'&id='+nodeId,
    cache: false,
    data: 
    {
        aQuantityFiles: aQuantityFiles,
        aDocumentFilesArrayFileName: aDocumentFilesArrayFileName 
    },
    success: function(result)
    {
         //Do Something
    }
});

On the destination PHP side it is now very simple (no need to decode)

<?php

    $aQuantityFiles = $_POST['aQuantityFiles'];
    $fileNames = $_POST['aDocumentFilesArrayFileName'];

    for ($i = 0; $i < $numberRows; $i++)
    {
        // This is the bigger loop cycling through the rows of data which contain the multiple files
        for ($j = 0; $j < $quantityFiles; $j++)
        {
            // Echo to illustrate that data is extracted multidimensionally as expected
            echo $fileNames[$i][$j];                 
            echo "<br/>";
        }
    }
?>

Optional

Now the multidimensional array data is accepted by the destination PHP file but you may need to bundle the additional form data with the extended array data before you send it with $.ajax. I found out how to do this using the $.param function from the site below. http://www.jblotus.com/2011/07/12/combine-serialized-form-post-data-with-arbitrary-object-in-jquery/

James Pitt
  • 451
  • 2
  • 8
  • 19