PHP備忘録を読んで

PHP備忘録 - QiitaというQiitaの記事をを読んだので、自分なりに分かったことをまとめてみようと思う。

PHP備忘録について

忘れないよう備えた記録という事だが、今年phpを始めたばかりの私にとっては覚えておくべき事が分かってとてもありがたい。

//配列にキーとバリューを指定
$array = array(
    "foo" => "bar",
    "bar" => "foo",
);

添え字は数字というのが私の中での基本だったのだが、phpを始めてから添え字に文字列を使うことが増えた。
確かに後で読み返した時、非常に分かりやすい。

配列に何か値を入れようとしているけど、何の値を入れているんだろう?

そんな事が減った。

添え字が数字じゃないのに、どうやってループを回すんだろう?
と思ったこともあったが、それはforeachという存在により解決した。

//配列の数だけ繰り返し (配列 as $配列の要素)
$array = array(1, 2, 3, 4);
foreach ($array as &$value) {
    $value = $value * 2;
}
unset($value);

上記のforeachの使い方しか知らない時は、まだ「添え字は数字」という考えを持っていたが、

// これならキーも取得できる
foreach ($array as $key => $value) {
}

この存在を知ってからは、「数字にこだわる必要も無いか」と思えるようになった。
おかげで、コードが少し見やすくなった。

最初、この記事のforeachのコードが少しおかしいと思ったのだが、参照渡しという方法を使っているらしい。

そこで、参照渡しに興味を持ったので少し調べてみた。
これまでC言語を使っていたので、ポインタと同じものだと思っていたが、phpの場合はC言語のポインタと少し違う挙動をするらしい。

これからphpを使っていくので、こちらにメモしておこうと思う。

phpの参照渡しについて

配列の要素のポインタを他の変数に代入すると、その要素の方はポインタ型に変換される

初めて見た時、何を言っているのか分からなかった。
理由は以下の通りである。

<?php
 
$array = array(1,2,3);
 
var_dump( $array );
$ref = &$array[1];
var_dump( $array );
 
?>

これを実行してみると

$ php -r '$array = array(1,2,3); var_dump( $array ); $ref = &$array[1]; var_dump( $array );'
array(3) {
  [0]=>
  int(1)
  [1]=>
  int(2)
  [2]=>
  int(3)
}
array(3) {
  [0]=>
  int(1)
  [1]=>
  &int(2)
  [2]=>
  int(3)
}

となる。
array[1]の型が変わっている。

普通の変数の場合でも試してみる。

<?php
$v = 1;
$ref = &$v;
var_dump( $v );
?>

出力結果は以下の通り

$php -r '$v = 1; $ref = &$v; var_dump( $v );'
int(1)

型は変換されていない。

以下のコードも試してみる。

<?php
$a = 1;   // $a は 1
$b = &$a; // $b は $a の参照
$c = $b;  // $c はどうなる?
$c = 2;
 
print "${a}\n"; // これが1なら$cは参照、2なら$cは値ということになる
?>

出力結果は

$ php -r '$a = 1;$b = &$a;$c = $b;$c = 2;print "${a}\n";'  
1  

不思議な事に$aの参照が$cに渡されていない。
この場合は値が渡されるようである。

見やすさという観点だけでなく、phpで参照渡しは積極的に使うべきでは無いのかもしれない。

これを紹介していたブログには、「初心者はPHPをやるべきでは無い」と書かれていた。


きっちり書きたいときはC、JAVAPython
ゆるく使いたいときはC#RubyPerl
プログラミングという行為自体で遊びたいときはHaskellScalaClojure


分からなかった部分

分からない部分があったので、書かれていたものをそのまま記述しておこうと思う

$hoge = "this is hoge";

function &fuga() {
    return $this->value;
}

$fuga =& fuga();
$fuga = "this is fuga";
var_dump($hoge);//"this is fuga";

この辺は動的プログラミングとかで地味に効いてくる。
関数名と返り値取得の両方に&が必要、との事。クラスで可変となるプロパティ部にアクセサつけたりとかそういう感じの時何かと便利。

受け取るときに&抜いたら参照じゃなくなる辺りとかも便利だと思う。


  • 動的にプログラミングとかで地味に効いてくる
     →具体的にどんなところに効いてくるのだろう
  • クラスで可変となるプロパティ部にアクセサ付けたりとかそういう感じの時何かと便利
     →どんな状況なのだろうか、どんな感じに便利なのだろう 
  • 受け取るときに$抜いたら参照じゃなくなるあたりとかも便利だと思う
     →それができると何ができるようになるのだろう

上の3点が分からなかったので、今後も調べてみようと思う

参考文献

PHP備忘録 - Qiita

PHPとかいう糞言語|いんまのブログ