ディレクトリ構造
learner@debian:~$ tree ~/bin
/home/learner/bin
└── php
├── Body
│ ├── Brain.php
│ └── Cell
│ └── Neuron.php
└── main.php
3 directories, 3 files
最初のコード例
~/bin/php/main.php:
<?php
spl_autoload_register(function ($class) {
$path = str_replace('\\', DIRECTORY_SEPARATOR, $class) . '.php';
echo "----- Autoload $class from $path -----\n";
include $path;
});
use Body\Brain;
$brain = new Brain();
?>
~/bin/php/Body/Brain.php:
<?php
namespace Body;
use Body\Cell\Neuron;
class Brain
{
public function __construct()
{
$this->brain = new Neuron();
$this->brain->talk();
}
}
?>
~/bin/php/Body/Cell/Neuron.php:
<?php
namespace Body\Cell;
class Neuron
{
public function talk()
{
echo "I am Neuron!\n";
}
}
?>
次の方法でホームディレクトリから main.php を実行でき、正常に動作します。
learner@debian:~$ php ~/bin/php/main.php
----- Autoload Body\Brain from Body/Brain.php -----
----- Autoload Body\Cell\Neuron from Body/Cell/Neuron.php -----
I am Neuron!
これが機能することに驚いています。$this->brain = new Neuron();
で実行
すると失敗すると思い
~/bin/php/Body/Brain.php
ます。この行が検出されると、オートローダーは実行を試みますが、内部にinclude 'Body/Cell/Neuron.php'
呼び出されるサブディレクトリはありません。Body
~/bin/php/Body
2 番目のコード例
include
オートローダーの代わりにステートメントを使用している別のコード例を示して、最初のコード例が失敗すると予想する理由を説明しましょう。
~/bin/php/main.php を次のように変更:
<?php
include 'Body/Brain.php';
use Body\Brain;
$brain = new Brain();
?>
上記のコードからオートローダーが欠落しており、以前にオートローダーによって実行されていたものと同じ include ステートメントが現在使用されていることを確認してください。
~/bin/php/Body/Brain.php を次のように変更:
<?php
namespace Body;
include 'Body/Cell/Neuron.php';
use Body\Cell\Neuron;
class Brain
{
public function __construct()
{
$this->brain = new Neuron();
$this->brain->talk();
}
}
?>
ロードする前にオートローダーによって実行されていたこのコードに、同じ include ステートメントが追加されていることに注意してくださいBody\Cell\Neuron
。
このコードを実行しようとすると失敗します。
learner@debian:~$ php ~/bin/php/main.php
PHP Warning: include(Body/Cell/Neuron.php): failed to open stream: No such file or directory in /home/learner/bin/php/Body/Brain.php on line 4
PHP Warning: include(): Failed opening 'Body/Cell/Neuron.php' for inclusion (include_path='.:/usr/share/php:/usr/share/pear') in /home/learner/bin/php/Body/Brain.php on line 4
PHP Fatal error: Class 'Body\Cell\Neuron' not found in /home/learner/bin/php/Body/Brain.php on line 12
include 'Body/Cell/Neuron.php';
での実行中に、 で呼び出され~/bin/php/Body/Brain.php
たサブディレクトリが見つからないため、この失敗は予期され
たものです。Body
~/bin/php/Body
質問
の代わりに
~/bin/php/Body/Brain.php
使用する
ように編集することで、2 番目のコード例を簡単に修正できることがわかっています
。ただし、私の質問は、2 番目のコード例が機能しない理由ではなく、最初のコード例が機能する理由についてです。include 'Cell/Neuron.php';
include 'Body/Cell/Neuron.php';
- PHP インタープリターが2 番目のコード例で
include 'Body/Cell/Neuron.php'
from~/bin/php/Body/Brain.php
を実行できない場合、オートローダーが最初のコード例で同じ PHP ファイルから同じインクルードを実行するにはどうすればよいでしょうか? - それとも私は間違っていますか?最初のコード例
~/bin/php/main.php
では、クラスが最初に使用された場所に関係なく、オートローダーは常にincludeステートメントを実行しているのでinclude 'Body/Cell/Neuron.php'
はない でしょうか。この場合、公式ドキュメントのどこでそれについて読むことができますか?~/bin/php/main.php
Body
~/bin/php
- 私たちの理解を要約すると、一般的に、登録されたオートローダー機能がどこから実行されるのか教えていただけますか? 関数が定義されているスクリプトから?関数が登録されているスクリプトから?それとも、新しいクラスが発生するスクリプトからですか?