PHP | Проблема с namespace
pet.php:
<?php
namespace App;
use App\PetException as PetException;
use App\MinEnergyException as MinEnergyException;
use App\MaxEnergyException as MaxEnergyException;
final class Pet
{
private function checkEnergy()
{
if ($this->energy <= $this->min) {
throw new MinEnergyException;
}
if ($this->energy > $this->max) {
throw new MaxEnergyException;
}
}
}
pet_exception.php:
<?php
namespace App;
class PetException extends \Exception
{
}
class MinEnergyException extends PetException
{
protected $message = 'MinEnergyError: the minimum energy must be at least 1!';
}
class MaxEnergyException extends PetException
{
protected $message = 'MaxEnergyError: the maximum energy should not be more than 100!';
}
index.php:
<?php
use App\Pet as Pet;
use App\PetException as PetException;
require_once 'vendor/autoload.php';
try {
$toby = new Pet('toby', 8, 0);
} catch (PetException $e) {
echo $e->getMessage();
}
Ошибка:
Fatal error: Uncaught Error: Class "App\MinEnergyException" not found in C:\My\Soft\OpenServer\domains\new.loc\MyProjects\pet-bot\app\classes\pet.php:88 Stack trace: #0 C:\My\Soft\OpenServer\domains\new.loc\MyProjects\pet-bot\app\classes\pet.php(20): App\Pet->checkEnergy() #1 C:\My\Soft\OpenServer\domains\new.loc\MyProjects\pet-bot\index.php(11): App\Pet->__construct() #2 {main} thrown in C:\My\Soft\OpenServer\domains\new.loc\MyProjects\pet-bot\app\classes\pet.php on line 88
Это часть кода, где задействовано исключение.
Ответы (1 шт):
Вам надо разобраться как работает автозагрузка. Для начала попробуйте обойтись без автозагрузчика composer'а. Напишите свой автозагрузчик и разберитесь как это работает. Когда вы поймёте принцип, то прочитайте соглашение об автозагрузке, которое использует composer. После этого вам станет ясно как правильно написать composer.json в своём проекте и всё заработает.
Для начала (в целях изучения php) удалите подключение автозагрузчика cpmposer'а (строчку require_once 'vendor/autoload.php';). Вместо неё напишите свою функцию автозагрузки.
Например так:
spl_autoload_register(function($className) {
require_once strtr(ltrim($className, '\\'), '\\', '/').'.php';
});
То есть, когда потребуется подключить класс \App\MinEnergyException, функция подключит файл App/MinEnergyException.php. Чтобы это заработало, класс \App\MinEnergyException должен быть определён в файле App/MinEnergyException.php (а не pet_exception.php).
Конечно внутри автозагрузчика может быть любая логика и вы можете написать и так:
spl_autoload_register(function($className) {
if ($className == '\App\MinEnergyException') {
require_once 'pet_exception.php';
} else {
// ...
}
});
И тогда автозагрузчик подключит именно pet_exception.php. Но подумайте какой будет бардак в автозагрузке, если автор каждой библиотеки (а в большом проекте могут использоваться тысячи сторонних библиотек) будет писать свой хитрый автозагрузчик. Лучше уж что-то вроде первого варианта.
PSR-4 -- это соглашение как писать автозагрузчик и называть файлы с классами. Если вы придерживаетесь этого соглашения, то автозагрузчик композера сможет загрузить классы вашего приложения так же как и классы сторонних библиотек. Вам нужно просто правильно называть файлы с классами.
Теперь можете удалить собственный учебный автозагрузчик и настроить автозагрузчик composer'а. После настройки перегенерируйте автозагрузчик (выполните composer install) и подключите автозагрузку как было раньше (require_once 'vendor/autoload.php';).