php7をご存知でしょうか?
php7はphpのメジャーバージョンです。php5.6.x系のバージョンから大幅に強化された新しいphpと言えるでしょう。
一体どれほど強化されたのかは「php7 速度」などでググって頂ければ比較記事が大量に出てくると思います。では速度以外の点ではどのようなことができるようになったのでしょう?
特にphp7を導入することでどのようなことプログラムが書けるようになるのかという疑問はphpエンジニアの誰もが一度は抱くものだと思います。
そこで本記事では、php7でできるようになったphpのタイプヒンティングについて、できるだけ丁寧にphp初心者でもわかるように解説します。
1. タイプヒンティングの強化
まず簡単にタイプヒンティングとは何かついて説明します。
タイプヒンティングとは関数の引数の型を指定する機能です。
下記のようなfunctionに対して配列(array型)以外の値を渡すとエラーになるという感じで機能します。
function hello(array $array)
{
foreach($array as $a) {
echo $a;
}
}
hello(array(1,2,3,4,5)); // 配列なのでok
hello(12345); // 配列ではないのでerror
hello('渋谷'); // 配列ではないのでerror
タイプヒンティングを用いることで、バグを未然に防ぎ、コードを簡潔にすることができます。
上記のような関数であれば「array以外はそもそも関数に渡すことができない」ことが保障されているため、わざわざ関数内で型チェックをする必要がなくなります。
php7ではこのタイプヒンティングの機能がさらに強化され、今まで用いることができなかったスカラ型(intやstring)のタイプヒンティングも書けるようになりました。
さらに関数の引数だけでなく、返り値の型もタイプヒンティングできるようになりました。
1.1 引数のタイプヒンティング
引数のタイプヒンティングは前述したコードのように引数の前に型を書くものです。
php5.6系までは「array(配列)」「Object(クラス名)」「interface(インターフェース)」「callable (任意の関数)」しか受け付けていなかったのですが、php7ではこれに加えて「int」「string」「float」「bool」もサポートするようになりました。
これによって、あるとあらゆる関数の引数にタイプヒンティングを用いることができます。
下記は表示する文字列と文字を表示する回数を渡して文字列の表示を行う関数です。タイプヒンティングによって型が違う値を渡すとエラーになります。
unction hello2(int $count, string $str)
{
for ($i = 0; $i < $count; $i++)
{
echo $str.PHP_EOL;
}
}
hello2(3, 'hello'); // hello が3回表示される
hello('hello', 'hello') // 第1引数がint型でないためエラーになる
引数の型を制限することで堅牢なプログラムを作ることができます。
一人でプログラムを書いているのならばなんとかなるかもしれませんが、複数人で作るプログラムでは自分の作った関数に想定外の値を渡すプログラムを書かれたりするものです。(PHPなどの動的型付け言語だと特に)
堅牢なプログラムを書こうとしたら引数をチェックするプログラムを別に書いたり、アサーションを使ったりする必要がありますが、結構面倒なものです。
このタイプヒンティングがあればある程度はそのような面倒を省くことが可能となるのです。
1.2 返り値のタイプヒンティング
返り値のタイプヒンティングでは関数の後に「:」をつけ、続けて型名を書くことになります。するとその関数では指定した型以外の返り値を返そうとするとエラーになります。
下記は引数として配列を受け取り、その要素数を返す関数です。
function array_count(array $list) : int
{
$count = count($list);
return $count;
}
$count = hello3(array(1,2,3,4,5)); // 返り値としてint型の値が来ることが保障されている。
echo $count.PHP_EOL;
上記の関数を下記のように変えるとエラーになります。
配列を受け付けてカンマ区切りの文字列にして返すようにしてみました。
function array_count(array $list) : int
{
return implode(',', $list);
}
$count = hello3(array(1,2,3,4,5)); // 返り値がstring型なのでエラーになる
echo $count.PHP_EOL;
基本的に関数というものは何か一つのことを実行するように設計するべきですが、プログラム全体が肥大化していくと1つの関数が複数の役割を持つようになりがちです。(時に意図せず、時に自分の甘えなどによって...)
例えば下記のような関数は作った本人ならわかるかもしれませんが、他人から見るとちょっとよくわからないものに見えるはずです。
function mixed(int $count, string $str)
{
if ($count == 0) {
return false;
}
if ($str == 'none') {
return array($count => $str);
}
$res = '';
for ($i = 0; $i < $count; $i++)
{
$res .= $str;
}
return $res;
}
$hoge = mixed(2, 'hoge');
返ってくる型のパターンが多すぎて本当にやめてほしいものですよね。これだけ短ければまだ解読可能ですが、どうしても長くなってしまう関数で上記のようなことをやったに日は多くの人を苦しめることになるはずです。
返り値のタイプヒンティングを導入することで強制的に上記のような事象を防ぐことができます。
自由な形式で値を返せるというphp(というか動的型付け言語)の特性を制限することにはなりますが、やはり複数の役割を持った関数は言語問わずやめたほうが良いでしょう。
まとめ
phpのような言語を使えばいわば「魔法」的な複雑なプログラムを書くことも可能です。
しかし、万人にわかりやすく、使いやすいプログラムを書くことのほうがもっと難しく、それができる人こそが賢いプログラマだと思います。
php7で導入された引数の型指定、返り値の型指定と適切な関数名、引数名を持った関数であれば初めて見た人でも容易にその役割と動作を把握することができます。
タイプヒンティングを上手に利用することによって、より良いプログラムを書くことができるはずです。
ぽんぽこ
PHPの最新バージョン「PHP7」の基本知識を動画で学ぶなら・・・・
なかなかイメージしにくいな、という方には動画学習も効果的です。
- はじめてPHPを勉強する方
- PHP5.6までは経験があるが、PHP7を覚えたい方
にオススメなUdemyの動画です。定期的に割引キャンペーンが行われるのでお得に学習できます。