【PHP】includeの使い方、クラスをincludeした時の動きを検証

前回の「includeとinclude_onceの違い」の記事では、PHPで良く使用されるincludeとinclude_onceの動きの違いについて書きました。

今回はその流れで、include自体の動きをもっと知るために。クラスをincludeしてみたいと思います。

 

クラスのinclude

下記の例はシンプルにクラスをincludeしています。

Humanクラスは「名前($name)」と「hello()」という振る舞いと持っているクラスで、メソッドが何回呼ばれたかわかるように「カウンター($counter)」を持っています。

Human1.php

<?php_
 echo "[Humam1クラス] start\r\n";

 class Human1 {
   public $name;
   public $counter=0;

   function __construct($name) {
     echo "{$name}がコンストラクタ実行\r\n";
     $this->name = $name;
   }

   function hello() {
     $this->counter += 1;
     echo "こんにちは{$this->name}です。({".$this->counter."回目)\r\n";
   }
 }

 echo "[Humam1クラス] end";

test1-1.php

<?php
 include('Human1.php');


 $h = new Human1('テスト1');
 $h->hello();

実行結果

$ php test1-1.php

# 出力結果
#[Humam1クラス] start
#[Humam1クラス] end
#テスト1がコンストラクタ実行
#こんにちはテスト1です。({1回目)

純粋なPHPのスクリプトをincludeした際は、そのタイミングでソースが読み込まれechoなどのコンソールに出力する処理もすべて処理されていました。

しかしクラスの場合は、上から順番に読み込まれますがクラスの中の処理は実行されません

インスタンスを作成してメソッドを呼ぶことで初めて実行されます

 

次に、途中で複数インスタンスを作って実行してみます。

test1-2.php

<?php
 include('Human1.php');

 $h = new Human1('テスト1');
 $h->hello();

 // 別のインスタンスを作成
 $h1 = new Human1('テスト2');
 $h1->hello();
 $h->hello();

実行結果

$ php test-1-2.php

# 出力結果
#[Humam1クラス] start
#[Humam1クラス] end
#テスト1がコンストラクタ実行
#こんにちはテスト1です。({1回目)
#テスト2がコンストラクタ実行
#こんにちはテスト2です。({1回目)
#こんにちはテスト1です。({2回目)

$hと$h1はそれぞれ別のインスタンスであるため、その中に保持しているカウンター($counter)も別々でカウントされていきます

 

それでは処理の途中で同じクラスファイルを再度includeしたらどうなるのでしょうか。検証してみます。
test1-3.php
<?php
 include('Human1.php');

 $h = new Human1('テスト1');
 $h->hello();
 echo $h->counter."\r\n";

 // 再度includek
 include('Human1.php');

 $h1 = new Human1('テスト2');
 $h1->hello();
 $h->hello();

実行結果

$ php test1-3.php

# 出力結果
#[Humam1クラス] start
#[Humam1クラス] end
#テスト1がコンストラクタ実行
#こんにちはテスト1です。({1回目)
#1
#[Humam1クラス] start
#
#Fatal error: Cannot declare class Human1, because the name is already in use in Human1.php on line 4

Human1.phpの4行目、「class Human1 {」のところでエラーになりました。

つまりincludeして同じクラスファイル名が登場したタイミングでエラーになります。

同じクラスは複数includeできないということですね。

 

staticを含むクラスのinclude

staticを含むクラスのincldeを試してみます。

static変数とは、簡単いうと以下のような性質を持ちます。

  • インスタンスを作成しなくても、includeした段階から使用できる
  • PHPの1つの処理の中で、1つしか存在できない

使用用途とはいろいろあるかと思いますが、よくシングルトンパターンを使う際に見かけます。

Human2.php

<?php_
 echo "[Humam2クラス] start\r\n";

 class Human2 {
   public $name;
   public static $counter=0; // static変数

   function __construct($name) {
     echo "{$name}がコンストラクタ実行\r\n";
     $this->name = $name;
   }

   function hello() {
     Human2::$counter += 1;
     echo "こんにちは{$this->name}です。({".Human2::$counter."回目)\r\n";
   }
 }

 echo "[Humam2クラス] end\r\n";

test2-1.php

<?php
 include('Human2.php');

 // ↓staticはインスタンスを作成しなくても使用できる
 echo Human2::$counter."\r\n";
 $h = new Human2('テスト1');
 $h->hello();
 echo Human2::$counter."\r\n";

実行結果

$ php test2-1.php

# 出力結果
#[Humam2クラス] start
#[Humam2クラス] end
#0
#テスト1がコンストラクタ実行
#こんにちはテスト1です。({1回目)
#1

「Human2::$counter」はstatic変数にアクセスする方法です。

インスタンスを作成される前に$counterをコンソールに出力して、「0」が取得できているかと思います。

 

次に、処理途中で別インスタンスを作成してみます。

test2-2.php
<?php
 include('Human2.php');

 // ↓staticはインスタンスを作成しなくても使用できる
 echo Human2::$counter."\r\n";
 $h = new Human2('テスト1');
 $h->hello();
 echo Human2::$counter."\r\n";

 // 別のインスタンスを作成
 $h1 = new Human2('テスト2');
 $h1->hello();
 $h->hello();

実行結果

$ php test2-2.php

# 出力結果
#[Humam2クラス] start
#[Humam2クラス] end
#0
#テスト1がコンストラクタ実行
#こんにちはテスト1です。({1回目)
#1
#テスト2がコンストラクタ実行
#こんにちはテスト2です。({2回目)
#こんにちはテスト1です。({3回目)

上記結果の通り、$hと$h1は別インスタンスですが、static変数である$counterは共通してカウントされているのが分かるかと思います

 

まとめ

今回includeの動きを掘り下げるために、クラスを読み込んだ時の動きを検証してみました。

概ね自分の予想通りな動きをしていたので、これからは自信を持って使っていけると思います。

 

がしかし、周りからの噂で聞いたのですが、最近のは流行はincludeやreqireを使わず、namespace(名前空間)なるものを使うらしいです。^^;

ちょっと気になるので、次はnamespaceについて勉強して記事にしたいと思います。



投稿日:2019-05-05    更新日:2019-08-04

[スポンサーリンク]

[スポンサーリンク]

  
関連記事
勉強した内容を緩くメモする|JBの技術メモ
勉強した内容を緩くメモする|JBの技術メモ
勉強した内容を緩くメモする|JBの技術メモ
勉強した内容を緩くメモする|JBの技術メモ
勉強した内容を緩くメモする|JBの技術メモ
勉強した内容を緩くメモする|JBの技術メモ
サイト内検索
プロフィール

プロフィール

[Name : POCO(@PocoIt2019)]
都内で社内SEをしているおじさん。
仕事で得られる知識だけでは限界を感じ、 WEBの勉強がてらITブログを開始。
サーバからWEBサイトまでフルスクラッチで開発しました。
現在は勉強のモチベーションを保つために活用中。
興味があることを雑記的に書いていきます。

[スポンサーリンク]

カテゴリ


タグ

[スポンサーリンク]

最近の記事