Perl日記

PerlとかRubyとかPHPとかPythonとか

PHPのつらいところまとめた

半年近くPHP5.3を仕事で使っててつらかったことをまとめた。

キーワードも関数名も大文字と小文字を区別しない

<?php
ClaSs HoGe {
  pUbliC funCtIoN H() {
    EcHO "hoge!\n";
  }
}
$hoge = New hOGE();
$hoge->h(); // hoge!

複数人で作ってるとほんとこういう些細なところで余計な手間がかかる。
チェックするのを自動化するのも手間。
あるいは、これくらい気にしないスタンスがPHPでは必要なのかもしれない。

名前空間をバックスラッシュで区切る

斬新。エスケープしてるみたいで見た目がやさしくない。

<?php
namespace \Foo\Bar;
class Baz {}

実際エスケープ文字なので、ダブルクオートの文字列リテラルでは否応なく二個必要なのも悲しい。

配列も辞書もarrayを使う

そしてarrayではない。辞書である。

<?php
// 5.3
$hoge = array(
  array('foo' => 'bar', 'hoge' => 'fuga');
  array(1, 3, 5, 7, 9),
);

// 5.4以降
$hoge = [
  ['foo' => 'bar', 'hoge' => 'fuga'],
  [1, 3, 5, 7, 9],
];

キーを指定しなければ、添字がキーの辞書なので、array_filterやarray_uniqueを使ってフィルタリングすると、予想と異なる結果になる。

<?php
$a = [10, 20, 30, 40, 50];
print_r($a);
//Array
//(
//    [0] => 10
//    [1] => 20
//    [2] => 30
//    [3] => 40
//    [4] => 50
//)
$b = array_filter($a, function($i){ return $i % 3 === 0; });
print_r($b);
//Array
//(
//    [2] => 30
//)

なので$b[0]とは取り出せない。添字[2]という情報が残っている。

中間変数が必要 (5.4からは不必要になった)

arrayの中身を直接取り出せない。関数の返り値とかも。
5.4から不要になっているので、早く使いたい。

<?php
// arrayから直接
// 5.3
$a = array('hoge' => 'fuga')['fuga'];
// PHP Parse error:  syntax error, unexpected '[' in php shell code on line 1

// 5.4
$a = ['hoge' => 'fuga']['hoge'];
// => fuga


// 関数からの返り値
function foo(){ return array(100, 200, 300); }

// 5.3
$a = foo()[0];
// PHP Parse error:  syntax error, unexpected '[' in php shell code on line 1

// 5.4
$a = foo()[0];
// => 100

あと組み込み関数もだめだった。

<?php
function foo(){ return array(); }

// 5.3
if (empty(foo())) echo "fooo\n";
// PHP Fatal error:  Can't use function return value in write context in php shell code on line 1

else ifもelseifも許される

言語仕様が許すからといって、途中で変えないで><

<?php
$a = true;
$b = false;
if ($a && $b) {
  //
}
elseif ($b) {
  //
}
else if ($a) {
  //
}
else {
  //
}

無名関数内で$thisなどの外側の変数が使えない ($thisだけは5.4から使える)

無名関数の外側にスコープを探索しないので、useを使って渡す必要があって悲しい。
5.4からは$thisだけは使えるようになった。

<?php
class Hoge {
  public $numbers = array();

  public function __construct($numbers) {
    $this->numbers = $numbers;
  }

  public function foo($i) {
    //return array_map(function($n){ return $n + $i; }, $this->numbers);
    return array_map(function($n) use ($i){ return $n + $i; }, $this->numbers);
  }

  public function bar() {
    // 5.3
    // PHP Fatal error:  Using $this when not in object context in /tmp/a.php on line 15
    $f = function(){ return $this->foo(1); };
    return $f();
  }
}
$hoge = new Hoge(array(1,2,3,4,5));
$numbers = $hoge->foo(100);
//Array
//(
//    [0] => 101
//    [1] => 102
//    [2] => 103
//    [3] => 104
//    [4] => 105
//)

$numbers = $hoge->bar();
// 5.4以降
//Array
//(
//    [0] => 201
//    [1] => 202
//    [2] => 203
//    [3] => 204
//    [4] => 205
//)

PECLモジュールはComposerで管理できないの?

peclは、pecl installしかないのかな。これはまだよくわかってない。
pearといっしょにcomposer.jsonでまとめて管理したい。