29

I've already read those questions but none of them answer to my need:

(the latest one said just add hard-coded quotes ie [''] but I can't do this, I'm calling a function that returns an Array)

So here's my code (note that the problem lies to the empty array new Array()):

function AjaxSend() {
  $.ajax({
    url: '/json/myurl/',
    type: 'POST',
    dataType: 'jsonp',
    data : { 'tab':new Array() },
    context: this,
    success: function (data) {
      if (data.success) {
        console.log('ok');
      }   
      else {
        console.log('error');
      }   
    }   
  }); 
}

Simple eh? Here's my Php code:

echo '_POST='.var_export($_POST,true)."\n";

And here's the result:

_POST=array (
)
jQuery1710713708313414827_1329923973282(...)

If I change the empty Array by a non-empty, i.e.:

'tab':new Array({ 't':'u' },{ 'v':'w' })

The result is:

_POST=array (
  'tab' => 
  array (
    0 => 
    array (
      't' => 'u',
    ),
    1 => 
    array (
      'v' => 'w',
    ),
  ),
)
jQuery1710640656704781577_1329923761425(...)

So this clearly means that when there's an empty Array() to be sent, it is ignored, and it's not added to the POST variables.

Am I missing something?

PS: my jQuery version is from the latest google CDN i.e.:

http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js

and

http://ajax.googleapis.com/ajax/libs/jqueryui/1/jquery-ui.min.js

I want the array to be sent, even if it's empty (= send [])! Any solution? Any idea? I've already tried to add this option traditional: true without success.

Community
  • 1
  • 1
  • 3
    Have you thought about sending a separate variable containing the length of the array? When the length is zero, the array is empty. You can use this check rather than trying to account for the missing array variable in the post. – tvanfosson Feb 22 '12 at 15:32
  • @FelixKling You're right, that gives the same (abnormal) result. –  Feb 23 '12 at 08:15

2 Answers2

20

The problem is that you can't really send empty array. Have you tried to send an empty array manually? How would that uri look (note that it's the same reasoning for POST)?

/path?arr[]

This would result in a $_GET like this:

array (
 'arr' => array (
    0 => ''
  )
)

That's not really an empty array, is it? It's an array with a single element of an empty string. So what jQuery does, and I would agree that this is the correct way of handling it, is to not send anything at all.

This is actually really simple for you to check on the server. Just add an extra check whether the parameter exists or not, i.e:

$tabs = array();
if(isset($_POST['tab'])) {
  $tabs = $_POST['tab'];
}
PatrikAkerstrand
  • 45,315
  • 11
  • 79
  • 94
  • 4
    So, from your point of view, this is a normal behavior? I mean, maybe it sounds like it stays "homogeneous" with GET / POST principles in Php, but, even though it stays "homogeneous", this is not normal from a "rational" point of view. –  Feb 23 '12 at 08:18
  • 2
    So what I do is: if the param is not present, I simply set it as an empty array, and the final result is that it empties the actual array. So, if a hacker tries a `wget` with no param, the basket will be emptied, whereas (it's my opinion) it should return an error. –  Feb 23 '12 at 08:20
  • 1
    I don't understand your point.. if the parameter HAS to be present, why are we having this discussion? Instead of setting an empty array, return an error page if the parameter is not set? – PatrikAkerstrand Feb 23 '12 at 09:44
  • 2
    This is in an event when the user clicks on a image, in JavaScript, to remove something from the basket. And if the basket is empty, still send the "empty basket" as a POST. –  Feb 23 '12 at 10:02
  • You should be checking with 'array_key_exists('tab', $_POST)' because even if `$_POST['tab'] = null;' then `isset` would still return `false`. – Buksy Jul 25 '16 at 06:44
0

Try

php

<?php
// `echo.php`
if (isset($_POST["emptyArray"])) { 
  function arr() { 
    $request = $_POST["emptyArray"]; 
    if(is_array($request) && count($request) === 0) { 
      // do stuff
      echo $request;
    };
  };
  arr();
};

js

    $.post("echo.php", {"emptyArray":[]}
      , function (data, textStatus, jqxhr) {
          if (textStatus === "success" && data.length === 0) {
            // do stuff
            console.log(data.length === 0 ? new Error("error").message : data);
          };
    });

jsfiddle http://jsfiddle.net/guest271314/Lf6GG/

guest271314
  • 1
  • 15
  • 104
  • 177