Friday, September 17, 2010

$GLOBALS or global?

I recently upgraded to Ubuntu 10.04 which includes php 5.3.2. Not long after upgrading, I noticed that transactions in my stock tracking program were no longer sorting correctly. At first, I thought the sort function, uksort, might have subtly changed. But, no, the manual didn't mention anything, and the manual and comment examples appeared to line-up with my code nicely.

Next, I checked the apache error log where I got my first clue as to the madness I was about to uncover:

PHP Warning:  uksort(): Array was modified by the user comparison function in ... on line 195
I double-checked my code. Nope. No modification of the array being sorted. What gives? I was using a global statement so that I could access the array being sorted...

A Google search on the global statement turned up another way to access global variables, the $GLOBALS array. Could php be overzealously assuming that access of a variable via a global statement constitutes modification? Well, maybe using $GLOBALS would solve that problem.

I switched from global to $GLOBALS, and, voila, sorting worked again! Apparently php does equate using a global variable via the global statement to modification of that variable. Geez!

P.S. uksort was returning a false value indicating that the sort had failed.

3 comments:

  1. Thanks a lot!
    Spent time on this...
    It seems to me pretty obvious that the uksort() function may need global to access the array - since uksort only provides the keys!
    Why did they perform that *silent* change :--((

    ReplyDelete
  2. It even seems that $GLOBALS isn't enough:

    function cmpdates($a, $b) {
    $arr = &$GLOBALS["arr"];
    }

    stil results in the warning...

    of course this is possible:

    function cmpdates($a, $b) {
    $arr = $GLOBALS["arr"];
    }

    but this copies the whole array each time cmpdates is called!

    ReplyDelete
  3. Wow. I didn't realize php would be doing something so ridiculous. Thanks for the comment, Dinne. Let us know if you find a better way!

    ReplyDelete