[PHP] requore_onceはどういう動きをしているのかを確認する

2019年7月25日

PHP テクノロジー プログラミング

エンジニアとして企業して、自分の会社を持った時に、非常に得をしたと感じたことは、自分でプログラミングができて、商材構築を行えるという事です。 多くの企業が開発エンジニアの採用に苦しんでいたり、アイデアはあるのに技術的な担保ができずに困っているのを見聞きしていると、そうした心配が自己責任ですが、自ら行えるというのは、非常に得であり、自給自足ができる自分のこれまでのスキルに感謝することが多いです。 もちろん他社のそうした開発業務を手伝うこともあるのですが、そうした作業はやればやるだけ、また自分のスキルとして溜まってくれるので、この仕事を楽しんで行える自分のモチベーションに感謝する毎日です。 そんな中、エンジニア連中では、比較的嫌われている系のPHP言語を使うことが多いのですが、WEBサービスを作るのにおいてはこれほど便利な言語は他には無いというのが今のところも揺るがない現状です。 そして、そんなPHPで自己フレームワークを作ってより開発を効率的に行えるようにしているのですが、サーバーメモリを考慮したライブラリ読込を実現するために、require機能を使いますが、同じモジュールを読み込むとエラーが出るため、require_onceを使うほうが一般的です。 これまで、何気なしに使っていたのですが、ちょっと気になったのでこの「require_once」について、色々と調査してみたと思います。

同じモジュールをrequire_onceした時の挙動

今回使うのは、読み込み元の親phpと、読み込み先のPHPライブラリです。 非常に簡易に書いているので、下記にソースを表示しておきます。 <?php echo "@"; <?php echo "1:"; require_once "once_lib/load.php"; echo PHP_EOL; echo "2:"; require_once "once_lib/load.php"; echo PHP_EOL; これをCLIで実行すると、以下のようになります。 $ php once.php 1:@ 2: ライブラリモジュールを1回目に読み込んだ場合は、ちゃんと内容が実行されていて"@"が表示されていますが、2回目に同じモジュールを読み込んだ際には、実行されないことが分かります。 この時点で、classや関数などが重複上書きされるのではなく、ファイル事態が実行されないようになっていることが分かります。

相対パスと絶対パスの比較調査

ファイル名(階層パス)をキャッシュして行っているのだとしたら、今回のような相対パスから、サーバー内の絶対パスにしたらどうなるのでしょう? <?php echo "1:"; require_once "once_lib/load.php"; echo PHP_EOL; echo "2:"; require_once "once_lib/load.php"; echo PHP_EOL; echo "3:"; require_once "/var/www/html/labo/php/require/once_lib/load.php"; echo PHP_EOL; 上記を実行してみると、 $ php once.php 1:@ 2: 3: ちゃんと絶対パスでも、読み込みを防止してくれました。 おそらくPHP内部で、"__FILE__"でキャッシングしてくれているんでしょうね。 試しにそれが分かるように以下の読み込みモジュールを用意してみました。 <?php echo __FILE__; これを先ほどと同じように、require_onceしてみます。 <?php echo "1:"; require_once "once_lib/path.php"; echo PHP_EOL; echo "2:"; require_once "once_lib/path.php"; echo PHP_EOL; echo "3:"; require_once "/var/www/html/labo/php/require/once_lib/path.php"; echo PHP_EOL; $ php once_path.php 1:/var/www/html/labo/php/require/once_lib/path.php 2: 3: おそらくこれでしょうね・・・

全く同じモジュールを読み込んだらどうなるのか?

それでは、読み込み内容が同じファイル名が違うモジュールをrequire_onceしたらどうなるのでしょう? 先程のload.phpを同一階層にコピーしてload2.phpを作成して実験します。 <?php echo "1:"; require_once "once_lib/load.php"; echo PHP_EOL; echo "2:"; require_once "once_lib/load2.php"; php once2.php 1:@ 2:@ そらそうですよね。 別ファイル名ですから読み込まれます。 同一クラス名や関数名などをrequireする際は、気をつけないければいけないので、ちゃんと構造設計しましょうね!という事を改めて心に刻みました。

このブログを検索

ごあいさつ

このWebサイトは、独自思考で我が道を行くユゲタの少し尖った思考のTechブログです。 毎日興味がどんどん切り替わるので、テーマはマルチになっています。 もしかしたらアイデアに困っている人の助けになるかもしれません。