Top > MyPage
 

perlとPHPの違い

変数の型

PHPでは変数のプリフィクスとして型によらず常に$を使い、配列はarray()で作成する。

また配列と連想配列(ハッシュ)の区別はなく、連想配列は配列としてもアクセスできる。

表のサンプル
perl php
ローカル変数 my $string = 'string'; $string = 'string';(関数内で定義)
配列 @array = qw(this is an array); $array = array('this', 'is', 'an', 'array');
ハッシュ %hash = ('key' => 'value'); $hash = array('key' => 'value');
リファレンス $bar=\$foo($$barで使用) $bar=&$foo($barで使用)
配列の数 $count = scalar(@array); # == ($#array + 1) $count = count($array);
リスト ($x, $y,) = ($a, $b,); list($x, $y,) = array($a, $b,);

 

二次元配列

PHPではリファレンスを使わずに多次元配列を作成できる。

# perl
$multi = [['a1', 'a2'], 'b', ['c1', {'c2i' => 'value'}, 'c3']]; # cf. \
    @multi = ([...print length($multi->[2]->[1]->{'c2i'});

// PHP
$multi = array(array('a1', 'a2'), 'b', array('c1', array('c2i' => 'value'), \
    'c3'));
echo strlen($multi[2][1]['c2i']);

変数のスコープ

変数のスコープが関数単位でしか発生しない。

これによりif条件の場合のみとかループ中でしか使わない変数などを定義できない。

クラス

クラスは、変数およびこれらの変数で動作する関数の集まりである。クラスは次のような構文により定義される。

<?php
class Cart
{
    /* 以下のコードはPHP 4では動作しません。 */
    var $todays_date = date("Y-m-d");
    var $name = $firstname;
    var $owner = 'Fred ' . 'Jones';
    /* Arrays containing constant values will, though. */
    var $items = array("VCR", "TV");
}

/* 以下に正しい方法を示します。 */
class Cart
{
    var $todays_date;
    var $name;
    var $owner;
    var $items = array("VCR", "TV");

    function Cart()
    {
        $this->todays_date = date("Y-m-d");
        $this->name = $GLOBALS['firstname'];
        /* 等など. . . */
    }
}
?> 

varはクラスのメンバ変数の宣言であり、PHP 4では、変数varについては定数による初期化のみが可能。定数以外で初期化を行う場合には初期化関数が必要となる。この初期化関数は、オブジェクトがクラスから構築される際に自動的にコールされる。このような関数はコンストラクタと呼ばれます。

メソッド呼び出しとメンバ変数

Perlの場合、メソッドを呼び出す際括弧をつけてもつけなくてもいいが、PHPの場合は括弧がついてたらメソッド、ついてなかったらメンバ変数なのでPHPでメソッド呼び出しするときは慎重に。

 # Perl 
 $obj->hoge(); # メソッド呼び出し
 $obj->hoge;   # メソッド呼び出し
  
 // PHP
 $obj->hoge(); // メソッド呼び出し
 $obj->hoge;   // メンバ変数
    

メソッドの引数

Perlではメソッドの引数を省略してもよかったが、PHPでは設定されている引数を無視すると警告がでます。2つの引数をとるメソッドはちゃんと値を2つわたさなければいけません。

class Cart
{
    var $todays_date;
    var $name;

    function Cart($foo, $bar)
    {
        $this->todays_date = $foo;
        $this->name = $bar[name];    
    }
}
-------------------------------------
$date = '12:30'; $hash = array('name' => 'taro');

$cart = new Cart();               #エラー
$cart = new Cart($hash);     #エラー
$cart = new Cart($date, 'name'); #OK

      

制御構造

forとwhileはperlとPHPで違いはないが、foreachは次のように少し書き方が違う。 

foreach( 配列 as $value ){
    ループ処理;
}
        

また次のような書き方もでき、各ループでの現在の要素の値が変数$valに、要素のキーが変数$keyに代入される。

foreach( 配列 as $key => $val ){
  ループ処理;
}

perlでのnext、lastがPHPではcontinue、breakにあたる。

デフォルト値

     # Perl
     my $a = $hoge || $muge || 'default';
    

PHPの場合||で評価されたものは全てboolean型を返す仕様。

よって上記のように書くと$hogeや$mugeにどんな値が入っていようとTRUEが返り、print $aとやっても表示されるのは「1」になる。

もし、PHPで同じような処理を書きたければ、

    // PHP
    ( $a = $hoge ) || ( $a = $muge ) || ( $a = 'default' );
    

のように書く。

ハッシュ(連想配列)のキーの罠

Perlでは

 $hash{key_name} = 10;
 print $hash{key_name};   # 10
 print $hash{'key_name'}; # 10
    

とこのようにハッシュのキー名をシングルクォートで括らなくてもよいがPHPは必ずシングルクォートで括らないといけないとマニュアルに書いてある。それはなぜか。

定数を定義するにはdefine()関数を使う。

 define('HOGE','Hellow!!'); // HOGEという定数の定義
 print HOGE; // Hellow!!
    

PHPにおける裸の文字列は全て定数と見なされる。

だがその時にその裸の文字列がdefine()で定義されていない場合、デフォルトの挙動として自身と同じ文字列を返すような仕様になっている。

 // define()せずに裸文字列を表示すると・・・
 print HOGE; // HOGE
    

と、言うことは$array[key_name]とは結局のところkey_nameという定数を参照していることになる。

つまりもしシングルクォートで括っていなかった場合、どうなるかというと・・・。

 define('key_name','hogehoge');
 $array[key_name] = 10;
 print $array[key_name];   // 10
 print $array['key_name']; // 何も表示されない
 print $array['hogehoge']; // 10
    

ということになってしまう。

条件演算子の違い

PHPでは条件演算子の結合がperlとは異なる。

printf('%s ', 1 ? 1 ? 'A' : 'B' : 'C');
A # perl
A // PHP
    

ifの入れ子に相当する書き方はOK。しかし、

printf('%s ', 1 ? 'A' : 1 ? 'B' : 'C');
A # perl
B // PHP
    

このようにelse ifに相当する書き方をするとperl(Cもそうだが)とは異なった結果になってしまう。

普通の感覚では、

printf('%s ', 1 ? 'A' : (1 ? 'B' : 'C'));
    

という結合を期待すると思うが、結果から

printf('%s ', (1 ? 'A' : 1) ? 'B' : 'C');
    

と評価されていることが分かる。(左結合?)

PHPでは条件演算子はifの代わりではなく、あくまでも演算子である。