1

I've got this problem with php, and I guess the worst part is that it's working fine on my dev environment (php v5.4) but breaks on the test/live site on the webserver (php v5.2).

So when I var_dump my $_POST["formData"] I get an array that looks like this:

array(42) {
    [0] => array(2) {
        ["name"] => string(2) "id";
        ["value"] => string(4) "3972";
    }
    [1] => array(2) {
        ["name"] => string(2) "action";
        ["value"] => string(4) "edit";
    }
...
}

To separate this, I use this (or some variation of this):

for($i=0;$i<count($_POST["formData"]);$i++) {
    $data[$_POST["formData"][$i]["name"]] = $_POST["formData"][$i]["value"];
}

So I end up being able to access everything with:

foreach($data as $key => $value) {
    echo $key . " = " . $value . "<br />";
}

which outputs:

id = 3972
action = edit
...

So, again, this works just fine on my dev server, but breaks on the live site. I've looked around here and found a lot of examples, but it seems a lot of them are using examples that aren't working quite the same.

What's causing this? Is it some setting? Is it a change between the two versions? I've tried a couple other things but none of them have worked and it's kinda a pain testing on the testing server (uploading files one at a time...yay...). Any easy solution or do I have to rebuild my script?

MDWar
  • 103
  • 13
  • 1
    How does it "break"? Do you get an error? There's nothing syntactically wrong with it for PHP 5.2. You don't use 5.4-specific syntax, like array dereferencing `function_call()['key']` for example... – Michael Berkowski Sep 28 '13 at 01:58
  • Yes, I'm getting the "Cannot use string offset as an array" error – MDWar Sep 28 '13 at 02:03

2 Answers2

2

That error suggests you're using a string as if it were an array. I'll assume it's your for loop. I'm not entirely sure, but $data could be being implicitly initialised to an empty string, which you are then trying to dereference and assign to. Does rewriting it like this help?

$data = array();    
foreach($_POST['formData'] as $kvp) {
    $data[$kvp['name']] = $kvp['value'];
}

This code is also faster, because you're not calling count() in a loop.

George Brighton
  • 5,131
  • 9
  • 27
  • 36
  • Reconfigured it, and it still works in dev but not on the test server. – MDWar Sep 28 '13 at 02:13
  • Well, that's causing a different error: Invalid argument supplied for foreach() – MDWar Sep 28 '13 at 02:16
  • Haha, sorry, tried to drop the line and didn't hit shift Invalid argument supplied for foreach() – MDWar Sep 28 '13 at 02:17
  • 1
    Ok then. `$_POST['formData']` isn't an array. What's the output of `var_dump($_POST['formData']);`? I'm pretty sure it won't be what's in your question... – George Brighton Sep 28 '13 at 02:18
  • I just checked that, the damn test/live server is putting out a string! That's the problem. – MDWar Sep 28 '13 at 02:20
  • Yeah, that was the problem, AJAXing with serializeArray() on dev, and serialize() on test/live – MDWar Sep 28 '13 at 02:21
1

It turns out this is indeed a difference between PHP versions, as demonstrated by this handy comparison tool.

For reference, the somewhat confusing error comes about (prior to PHP 5.4) from the following two steps:

  1. You take a variable that you think is an array, but is actually a string, and you access an "element" of it, e.g. $foo[1] or $foo['bar']. PHP takes this to mean "get the Nth character of the string" - $foo[1] means the 2nd character of $foo, and $foo['bar'] means the first, because the bar gets converted to 0.
  2. You then access that as though it's an array. Newer versions of PHP just repeat step 1 on the 1-character string you ended up with, but until PHP 5.4 this caused the ugly error.

So in some situations, your $_POST["formData"] is not an array, but a string. This is probably happening sometimes on both environments, but the difference in error handling is masking it in one environment and not the other.

IMSoP
  • 89,526
  • 13
  • 117
  • 169
  • Actually just figured it out (I need to get myself a rubber duck). My dev environment was AJAXing the formData with serialize(), test/live server was still AJAXing it with serializeArray(), which caused that to interpret the data as a string and not an array. – MDWar Sep 28 '13 at 02:25
  • Well, I learnt something by researching this, anyway, as I didn't know about that change in 5.4 before. There's an explanation of the change on this answer: http://stackoverflow.com/a/6588806/157957 – IMSoP Sep 28 '13 at 02:28
  • Yeah, I was reading a bunch of posts talking about that error, which is why I bothered even posting this; it didn't make sense to me because my script was actually working where they said it shouldn't work. It wasn't so much being masked as I don't have a mouse at the moment so it's a pain adding in error reporting and scrolling through results on a trackpad on this crazy 8pt font or whatever this thing is displaying. – MDWar Sep 28 '13 at 02:32