2012年12月18日火曜日

似てるけど似てないシリーズ #phpadvent2012

この記事はPHP Advent Calendar 2012の18日目です。
昨日はkiou oubaさんのフレームワークとは一体何だったのかでした。

私はオレオレFWとまではいきませんがずっと素書きでPHPを書いてきてましたが、今年からフレームワークも使ってみようと思ってFuelPHP、CakePHPとFWの勉強をしていました。
そこで勉強になったことやFWの良いところFWによる違い何かを書こうと意気込んでたんですが業務に追われてしまい、何も準備できずに今日になってしまいました。
Advent Calendarの流れ的にもよかったのかなと思って後悔してます。
来年またチャンスがあれば書けるように頑張ります!


準備してたネタとは違いますが、PHPの初歩的な部分を書いてみました。
7日目にはじかみさんがIntegerの上限を超えてゆけでも書かれてましたが、PHP.net。PHPのマニュアル的なサイトですがたまにはこれ見て勉強するのもいいですよね。
私も夏ごろにこのスライド見てPHP.netいろいろ見てみました。
https://t.co/e4nGnfAe
これはFukuoka.PHPという福岡でやってるPHPの勉強会で@akase244さんが発表されたスライドです。とても面白いスライドなので是非これも見て下さい!!

私が調べてみたのはPHPには似てるけど動きは全く別物だったり、似てるけど・・やっぱり一緒、みたいな関数。

PHP.netにも関数エイリアスというページがあって is_int()is_integer() の例のように is_integer() のページには「is_int()のエイリアス」とだけ書かれてます。
http://php.net/manual/ja/aliases.php

どっちがいいのかはわかりませんが、基本的にここに書いてあるのは同じ動作をします。

しかし、前述したように似てるけど全く別物というのもあります。
初心にもどった気分で読んでもらえれば嬉しいです。


まず

echo と print の違い


同じ文字列を出力する関数(ドキュメントには関数ではないと書かれてますが)
PHP始めたころはどっちで書けばいいんだろうとか気になってたこともあります。
<?php
    echo 'Hello, World!";
    print 'Hello, World!';
?>
出力される結果に違いはありませんが、echo では複数の文字列をカンマ区切りで記述することができます。
<?php
    echo 'Hello', 'World';    // OK
    print 'Hello', 'World';   // NG
?>
また、echo では返り値がないのに対し print は返り値で常に1を返します。
echo の方が返り値がない分、早いらしいです。
これだけ見ると echo のほうが良いのかなって思います。
けっこうどのサンプルも echo で書かれたりしてるのでやっぱり echo なのかな。


2つ目に

print_r と var_dump の違い


変数の値を確認したい場合に使う関数(何かとお世話になってます)
<?php
    $a = array(1, "2", true, array("a", "b"));

    print_r($a);
    var_dump($a);
?>

これは出力結果がかなり違ってます。
print_r の場合
Array
(
    [0] => 1
    [1] => 2
    [2] => 1
    [3] => Array
        (
            [0] => a
            [1] => b
        )

)

var_dump の場合
array
  0 => int 1
  1 => string '2' (length=1)
  2 => boolean true
  3 =>
    array
      0 => string 'a' (length=1)
      1 => string 'b' (length=1)

print_r では内容をただ出力している感がありますが、var_dump では型まで出力してくれます。
PHPでは明示的な型指定がない分、条件式とかでハマることが多々あるので個人的には var_dump のほうが好きです。
ちなみに var_dump のほうは変数を複数指定して出力することができます。
<?php
    var_dump($a, $b);
?>


3つ目に

シングルクォーテーションとダブルクォーテーションの違い


関数ではありませんが変数に文字列を格納する場合、どちらで囲むか。
一般的に使い分けをしているのかどうかわかりませんがこれも違うもので
<?php
    $name = 'Hayashida';

    $single = '私は $name です。';
    $double = "私は $name です。";

    echo $single;
    echo $double;
?>

出力結果は
シングルクォーテーションの場合
私は $name です。
ダブルクォーテーションの場合
私は Hayashida です。

シングルクォーテーションはそのまま出力するのに対し、ダブルクォーテーションは変数を展開してくれます。
上記の例では半角スペースをいれてますが、{ } で囲むことで確実に変数と認識させることができます。
ということはこんなこともできる。
<?php
    $closure = function($val) {
        return str_replace('a', '@', $val);
    };

    echo "私は {$closure($name)} です。";
?>

出力結果は
私は H@y@shid@ です。

文字列の変数に置換する場合などは sprintf とか使うことが多いと思いますが
知っておくと便利かもしれません。


4つ目に

and と && の違い


元々VBをやってたおかげ?で、PHPを始めたころハマったことあります。
条件式などを書く場合ですが、PHPの演算子には優先順位があってそれを知らないと意外なところでバグがでるかも。
http://php.net/manual/ja/language.operators.precedence.php
<?php
    $x = true and false;
    $y = true && false;

    var_dump($x, $y);
?>
二つの評価値(true or false)を比較して変数に代入。
なんてことをする場合、上記のように書くと結果が違います。というか意味が違います。

結果は
boolean (true)
boolean (false)

$x がなぜ true ??
理由はマニュアルに書いていますが、なぜかというと and より = のほうが優先度が高いからです。
$x の場合、$x という変数に true を代入し、その結果を and false としても意味がないものになってしまいます。
and と使う場合は $x = (true and false) とするのが正。
$y のほうは、 && のほうが = より優先度が高いからこのままでも良いのです。

or と || も同じようなことが言えます。


まとめ

取り留めも無い記事になってしまいましたが、今年は勉強会にも参加させてもらったりしてフレームワークやらPSRやらいろいろ勉強になりました。
来年はもう少しましな記事をかけるように頑張ろう。



明日はTakayuki Miwaさんです。よろしくお願いします。