Slash Boxes
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

xsawyerx (8978)

  (email not shown publicly)

Journal of xsawyerx (8978)

Monday August 17, 2009
06:17 AM

PHP is stupid, yet again

[ #39477 ]

The developers at my $work already know I hate PHP with a passion (and most of them do too). Here is a nugget of... I'll let you decide, that shows another interesting... err.. uh... feature?

php > $a = array('a','b','c');
php > unset($a[1]);
php > var_dump($a);
array(2) {
  string(1) "a"
  string(1) "c"

What you see here is setting a variable in a PHP REPL shell. The variable is an array. Then we remove the second element in the array (index no. 1) and then dump the array with the indexes.

Do you see the problem? Let me iterate further (excuse the pun). When you remove the second element in an array, you would expect the third to now become the second, the fourth becoming the third, and so on. First of all, because it makes perfect sense. Secondly, when you iterate over the array, you don't have any holes and gaps, causing segfaults or unexpected behavior (at the worst case) or exceptions raised (at the best case). Did I mention possible security problem?

However, apparently in PHP, you can remove an element from an array and the array will act like a hash with the indexes as the keys. It will maintain the old index and not update it.

Perl, on the contrary...

In Perl, the way to do this wouldn't be to undef the variable but to splice it out. Splicing it correctly sets the indexes of every element and makes sure it's done right. It even returns the value if you want it, or just replaces it inline with another. However, suppose that PHP has a way to do this as well, the above result is still fscked up. This is what would happen if I decide to simply undef an array element in Perl (demonstrated in Devel::REPL:

$ my @a = ( qw( a b c ) );
$ARRAY1 = [
$ undef $a[1];
$ @a
$ARRAY1 = [

It keeps the index and the indexed item, but the value is undefed.

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
More | Login | Reply
Loading... please wait.
  • Perl has foibles like this, too:

      DB<1> @a = (1,2,3)
      DB<2> delete $a[1]
      DB<3> x \@a
    0  ARRAY(0x90a6d0)
       0  1
       1  empty slot
       2  3

    ..and PHP has exactly what you suggested.

    <? $x = array(1,2,3); array_splice($x, 1, 1); var_dump($x); ?>
    array(2) {

    Just because PHP is often intolerable doesn't mean that everything it does is wronger than Perl.

    • PHP removes the index, which is the problematic part. Your Perl example shows exactly what my Perl example shows, which is that Perl just puts the value on undef and keeps the index, so you can iterate without a problem. This is far from a foible and is the correct and best result. This is not a Perl "feature", Python and Ruby behave the exact same way. PHP is the different here, and it is indeed stupid.

      $ my @a = (1, 2, 3)
      $ARRAY1 = [

  • ... because in PHP, an array and a hash are the same thing.

    It has its uses. Though often, it'll just bite you in the ass.