はじめに
筆者はずぶずぶの素人です。少しlaravelが書けるレベルです。
書けているけど僕自身がフレームワークに使われています。
laravelを使っていく打ちにもっとlaravelを理解したいと思いました。
フレームワークの本質を理解するにはphpを基礎力を向上させるほかないと考えphpの復習+脱初心者を目指します。
class
オブジェクト指向の構成要素の1つ。classはオブジェクトの設計書のようなもの
userの名前をコンストラクトし、user名を出力する簡単なクラスを作成
class Animal {
$name;
//$user_nameの初期化
function __construct($name) {
$this->name = $name;
}
//getterの役割
public function getName() {
return $this->name;
}
}
$animal = new Animal('dog');
echo $user->getName();
-------------------------
結果
dog
継承を行う。フレームワークにおいても、Contorollerなどのclassをextendして使用する。
class Dog extends Animal {
public function call() {
echo 'wan!';
}
}
$dog = new Dog('wanchan');
echo $dog->getName();
echo '<bar>';
echo $dog->call();
-------------------------------
結果
wanchan<bar>wan!
アクセス修飾子
public
どこからでもアクセス可能
private
どこからでもアクセス可能です。アクセス修飾子がない場合は、publicを指定したものと同じになります。
protected
そのクラス自身と継承クラスからアクセス可能です。つまり非公開ですが、継承は可能となります。
ポリモーフィズム
ポリモーフィズムとは同名のメソッドで異なる挙動を実現することをいいます。ポリモーフィズムのメソッドは、同じ目的の機能に同名のメソッドを割り当てる ことができるということです。
同名のメソッドで異なる動きを実現することを言います。
<?php
class Human {
protected $name;
protected $age;
function __construct($name, $age) {
$this->name = $name;
$this->age = $age;
}
protected function getInfo() {}
}
class HumanInfo extends Human {
//オーバーライド
public function getInfo() {
echo $this->name.'は年齢が'.$this->age.'です';
}
}
class Feature extends Human {
protected $job;
function __construct($name, $age, $job) {
$this->name = $name;
$this->age = $age;
$this->job = $job;
}
//オーバーライド
public function getInfo() {
echo $this->name.'は年齢が'.$this->age.'です'.'職業は'.$this->job.'です';
}
}
$user_info = new HumanInfo('たく', 29);
$user_info->getInfo();
$user_feature = new Feature('まみ', 30, '料理人');
$user_feature->getInfo();
------------------------------
結果:
たくは年齢が29です
まみは年齢が30です職業は料理人です
ポリモーフィズムのメリットは、同じ目的の機能に同じ名前のメソッドを指定できる点で、関連するクラスを利用する場合に、異なるメソッド名を覚える必要がなくなります。
但し、この例のように単なる継承とオーバーライドだけでは、それぞれのサブクラスが同名のメソッドを持つことが保証されないので、「抽象メソッド」という仕組みを利用する必要があります。
共通のメソッドを持たせる点であるがそもそも強制力はない。なのでabstractを用いて、表現をする。
抽象class
abstruct(抽象)をclassの前につけることで、抽象クラスを表現でき、またメソッドにもabstructを付与すると定義しているメソッドを使用を強制する。
<?php
//抽象クラス//設定するメソッドを強制できる。
abstract class Human {
protected $name;
protected $age;
function __construct($name, $age) {
$this->name = $name;
$this->age = $age;
}
//抽象メソッドになる。abstractを定義するとメソッド内容はかけない。
abstract protected function getInfo();
}
class HumanInfo extends Human {
//オーバーライド
// public function getInfo() {
// echo $this->name.'は年齢が'.$this->age.'です';
// }
}
--------------------------------------------------------
Class HumanInfo contains 1 abstract method and must therefore be declared abstract or implement the remaining methods
コメントするとメソッド入れなさいと怒られちゃいました。
そもそも柔軟にメソッドだけ、強制的に共通的に使用したい場合はinterfaceを使用する。
Interface
PHP では1つのサブクラスが同時に複数のスーパークラスを継承すること(多重継承)ができません。
これはポリモーフィズムを実現したい場合、すべての機能(メソッド)をひとつの抽象クラスに含めなければいけないことを意味し、サブクラスがスーパークラスの特定の機能(メソッド)を必要としない場合でも、それらの機能をオーバーライドしなければならなくなるためコードが冗長になってしまいます。
PHP ではこのような場合、インターフェースを利用します。
このinterfaceを使用することで共通のメソッドを共有できる様になります。メソッドはそのままに振る舞いは意図して変化できる。
interfaceをするにはinterfaceの宣言とクラスにimplementsを付与すること。
またinterfaceの利点は複数のinterfaceを使用できること。
<?php
interface HumanInterface {
function getInfo();
}
interface JobInterface{
function setJob($params);
}
//抽象クラス//設定するメソッドを強制できる。
abstract class Human {
protected $name;
protected $age;
function __construct($name, $age) {
$this->name = $name;
$this->age = $age;
}
}
class HumanInfo extends Human implements HumanInterface {
//オーバーライド
public function getInfo() {
echo $this->name.'は年齢が'.$this->age.'です';
}
}
class Feature extends Human implements HumanInterface, JobInterface {
protected $job = [];
function __construct($name, $age) {
$this->name = $name;
$this->age = $age;
}
public function getInfo() {
echo $this->name.'は年齢が'.$this->age.'です'.'職業は'.$this->job.'です';
}
public function setJob($params) {
return $this->job = $params;
}
}
$user_info = new HumanInfo('たく', 29);
$user_info->getInfo();
$user_feature = new Feature('まみ', 30);
$user_feature->setJob('料理人');
var_dump($user_feature->job);
$user_feature->getInfo();
?>
________________________________________
結果
たくは年齢が29です
string(9) "料理人"
まみは年齢が30です職業は料理人です
2つのインターフェイスがあり、implementsを定義することで、インターフェイスを使用できる。
もちろんimplementesで定義した、インターフェイスのメソッドを使用しないとエラーになる。
トレイト
コードの再利用性を高めるための機能
定義方法はtraitを宣言し、メソッドを記述していく。
classなどに組み込む際にはuseで宣言する。
traitは任意のクラスの機能(メソッド)を拡張できる仕組。そのため、traitに定義するメソッドは複数のクラスで利用されることを想定して、できるだけ汎用性が高い処理を定義するべきです。
複数のクラスで同様の処理を行うメソッドがある場合は、そのメソッドをtraitに移して各クラスではそのtraitをuseするといったリファクタリングを行うことがベター。
trait NewsTrait {
public function getNews() {
echo 'ニュース';
}
}
trait ProductTrait {
public function getProduct() {
echo 'プロダクト';
}
}
class Product {
//作成したtraitをuseして使用できる。
use ProductTrait;
use NewsTrait;
public function getInfo() {
echo 'クラスです';
}
}
$product = new Product();
$product->getInfo();
$product->getProduct();
$product->getNews();
---------------------------------
結果
クラスです
プロダクト
ニュース
ここからは番外編
型宣言 (タイプヒンティング)
コーディングをより堅牢なものとする!
関数の引数と戻り値に対して定義します → php7.4からは変数宣言にも使用できるようになったそうです。
メリット
本来期待している型と異なる型が引数に格納されることで起こる、思わぬバグを防げる
コードが読みやすくなる。
型の分類
スカラー型
複合型
特殊型
スカラー型
論理値 (boolean)、整数 (integer)、浮動小数点数 (float, double も同じ)
文字列 (string)
function addNuber(int $num1, int $num2) {
echo $num1 + $num2;
}
addNuber(1,2);
function isArray(array $array) {
if(is_array($array)) {
echo 'これはarray';
}
}
$array = [1,2,3];
isArray($array);
戻り値の型宣言もできます。
//戻り値の型宣言。
function sum($num1, $num2):int {
return $num1 + $num2;
}
$a = sum(1,2);
echo $a;
まとめ
laravelを使っていると目にする内容が多いことに気付きました。
これらを理解して、フレームワークをより理解して行きたいです。