PHP配列の悪夢、再び

おれって、相当アホ!!! ってな備忘録。

こんなコードを書いた。(実際に書いたコードはもっと複雑ですが・・・)

<?php
/******************************

 配列の中身を出力する。だけ。

******************************/
function array_wrong($files)
{
  $num = count($files);
  for($i=0;$i<$num;$i++)
    {
      printf("%d = %sn",$i,@$files[$i]);
    }
}

もうこの時点で、「お前の書くコードなんて一切使わない」宣言されるだろう。
はい、そうですね。僕もそう思います。(T-T)

こんな基本的な間違いを平気で犯す自分に自己嫌悪して数時間立ち直れませんでした・・・。

たぶん、次のような引数を渡すと期待するように動作するでしょう。

<?php
$files = array('abc.txt',
               'xyz.pdf',
               'def.jpg');

//たぶん上手くいく。オール、オッケー
array_wrong($files);

しかし・・・次のようにしたら・・・

<?php
$files = array('abc.txt',
               'xyz.pdf',
               'def.jpg');

unset($files[1]);

$files[10] = 'zzzz.gif';
$files[7] = 'bbbbb.ai';

array_wrong($files);

僕が期待した出力には当然なりません。とほほ。

こういうバカ・コードが原因だと気づくのに、半日要してしまったよ・・・・。
PHPの配列とcount関数の挙動が全然理解してない証拠っすね。。。恥ずかしい。。。

原因が分かれば・・・foreachもしくは、count関数を使わず・・・ループすればいい。

<?php
function array_right($files)
{
  ksort($files);
  foreach($files as $i => $file)
    {
      printf("%d = %sn",$i,@$files[$i]);
    }
}

//もしくは・・・count()関数でループ回数を決定するのではなく配列キーの最大値を利用する。
function array_right($files)
{
  ksort($files);
  $num = max(array_keys($files));
  for($i=0;$i<$num;$i++)
    {
      if(isset($files[$i]))
        printf("%d = %sn",$i,@$files[$i]);
    }
}

はぁ・・・。いつになったら使える人間になれるんだろう・・・。

PHPの配列は9ソだ!

PHPの仕様に関して文句は別にないんだが・・・、あのPHPの配列だけは、どうにかならないものか・・・。

Perlだと、配列と連想配列は、配列なら、$array[0] 、連想配列なら、$hash{’00’}と、表記と共に明確に区別されているのでわかりやすいし、まぁ、間違えることは、少ない。

が、PHPのコードを書いてると、ホントにイライラする。ま、言語仕様を斜め読みしかしていない、あやふやな知識で書いているオイラが全面的に悪いんだけど。。。

データベースのとあるカラムからフェッチした、数字の文字列を、つい、うっかり、配列に入れて、foreachとかでぶん回していたら、あるはずのデータが未定義になる、という現象の解読に数時間費やしてしまった・・・。

$ar = array();

$ar[1] = 'ほげほげ';
$ar[23] = 'ほむほむ';

//$recordには、以下の値が入っていた。
//$record['date_begin_day'] = '01';

echo $ar[$record['date_begin_day']];

さて、僕は、当然 「ほげほげ」と出力されると信じて疑わなかった。
PHPで仕事している人は、たぶん、こう思うでしょう。

「おまえはアホか!もう一回、リファレンスを読めよ」

と。

echo $ar[intval($record['date_begin_day'])];
//intval関数を通さないといけなかった・・・。

perlなら配列の添字は数字に暗黙的に変換されるので何ら問題無い。

$ar[1] = 'ほげほげ';
$ar[23] = 'ほむほむ';

$record{'date_begin_day'} = '01';

print $ar[$record{'date_begin_day'}];

しかし、別の問題を引き起こすが・・・ま、一長一短ですかな・・・。

気を付けよう。。。