PHP中級者になるために知っておきたい知識とは?
PHPの基本を一通り学んで中級者以上のスキルを身につけていくためには、PHPのより高度な機能や特性に知っておくことが必要ですが、具体的に何を学んでいけばいいのでしょうか。
脱・PHP初心者を目指すにあたって必要なスキルについて見ていきましょう。
PHP中級者を目指すためのアラカルト
「アラカルト」とは「一品料理」を表す言葉ですが、「一つ一つの独立した知識」を表す際にも用いられることがあります。
今回は、さまざまな「一品料理」的なPHPのより高度な知識を身につけていきましょう。
コピーオンライト
変数に値渡しで値を代入した場合に、すぐにメモリ領域を確保するのではなく、代入した値が変更された際に初めてメモリ領域が確保される仕組みのことを「コピーオンライト」と言います。
そのため、値渡しで変数に値を代入したとしても「参照渡し」で扱われていることもあり、この機能によってメモリを効率的に使えるというメリットが生まれます。
「値渡し」とは、代入された値をそのまま変数に渡し、値を保存するために新たに変数のメモリ領域が確保される仕組みのことです。
一方、「参照渡し」は変数に代入されたデータではなく、「データの参照情報」だけが変数に保存されるため、実際のデータは参照先のメモリアドレスに保存される仕組みのことを言います。
可変変数
可変変数は、変数の中の文字列を変数名として利用することができたり、変数値を変数名にすることができます。
$name = 'name1'; $name1 = 'hogehoge'; print $$name;
「$$name」の「$name」が「name1」となるため、「$name1」に「hogehoge」が入っているため、この値が出力されます。
可変関数
関数名を代入した変数を利用し、関数の呼び出しを行える機能が「可変関数」です。
$name = 'hogehoge'; $name(); function hogehoge() { print 'my name is hoge'; }
「$name」変数には関数名が代入されているため、「$name」内に格納されている関数名の関数が実行されるようになります。
そのため、出力結果は、
my name is hoge
となります。
クロージャ
関数は「必要な値」を引数として受け取り、処理を行う方法が一般的ですが、関数が定義されたスコープにもアクセスできる関数のことを「クロージャ」と言います。
$hp = function(){ $x = 1.5; return function() use ($x){ return (int)(100 * $x); }; }; $func_hp = $hp(); print $func_hp();
無名関数の戻り値にさらに無名関数が作られていますが、内部の無名関数から、外部の無名関数で定義されている「$x」にアクセスするために「use(アクセスした変数名)」を利用します。
print文の出力値は「150」となります。
PHPでは、無名関数を作るためにClosureクラスが用意されています。
タイプヒンティング
関数の引数に渡すデータのデータ型に制限できる仕組みがタイプヒンティングです。
使い方はとても簡単で、関数定義時に引数の直前にデータ型を書くだけで引数の渡すデータ型を指定することができます。
function add(array $numbers){ $sum = 0; foreach($numbers as $num){ $sum += $num ; } return $sum; } $data = [1,2,3,4,5]; print(add($data)); //「15」が出力される
もしこの関数に整数型のデータを渡すと「Catchable fatal error: Argument 1 passed to add() must be of the type array, integer given」が発生してしまいます。
参照による引数の受け取り
関数の引数にデータを直接渡すのではなく、「データの参照」を渡したい場合は、引数名の前に「&」記号を書きます。
$data = [1,2,3,4,5]; function add_plus_one(array $numbers){ foreach($numbers as $num){ $num += 1 ; } } add_plus_one($data); foreach($data as $datum){ print($datum); } //「12345」が出力される。
関数の戻り値も参照で返したい場合は、関数を定義する際に関数名の前に「&」を付けます。
function &add_plus_one($numbers){ foreach($numbers as $num){ $num += 1 ; } return $numbers }
マジックメソッド
ある条件で自動的にコールされるメソッドのことを「マジックメソッド」と言いますが、これらのメソッド名の前には「__(アンダースコア2個)」2つ付いているので、見分けやすいのではないでしょうか。
__construct
クラスからインスタンスを作成した際に自動的に呼び出されるコンストラクタは、マジックメソッドとして定義されています。
class Car{ private $type; private $maker; private $tires; function __construct($type, $maker, $tires){ $this->type = $name; $this->maker = $maker; $this->tires = $tires; } }
__destruct
インスタンスが削除される際に呼ばれるマジックメソッドが「デストラクタ」です。
主にファイル関連など、インスタンスを削除する際にリソースを解放する必要がある機能で利用されています。
__toString
オブジェクトを文字列に変換する際に呼ばれるのが「__toStrong」メソッドです。
このメソッドにはオブジェクトの文字列表現を定義しておくことができます。
class Student{ private $name; private $grade; function __construct($name, $grade){ $this->name = $name; $this ->grade = $grade; } public function __toString(){ return '生徒の名前は、「' . $this->name . '」で、グレードは「' . $this->grade . '」です。'; } } $student1 = new Student('tanaka','A'); echo $student1;
__get・__set
存在しないフィールドにアクセスされた場合に処理を実行することができるマジックメソッドが「__get」「__set」です。
class Car{ private $type; private $maker; private $tires; function __construct($type, $maker, $tires){ $this->type = $name; $this->maker = $maker; $this->tires = $tires; } function __get($propName){ print('あなたが参照した「' . $propName .'」は存在しません。'); } function __set($propName, $setValue){ print('あなたが値「' . $setValue . '」を設定しようとした「' . $propName .'」は存在しません。'); } } $car = new Car('4WD', 'hoge', 4); $dummy = $car->dymmmy_prop; $car->dymmmy_prop = 'dummy data';