@Raheez12

Как подключить класс через use?

Привет, у меня имеется следующая структура файлов:
В корне проекта лежат файлы composer.json и index.php, а также папка App.
Папка App имеет следующую структуру:
\Controllers\ТутФайлыКонтроллера.php
\Models\ТутМоделиИВременноКлассыРоута.php

В composer.json написано следующее:
{
    "require-dev": {
        "phpunit/phpunit": "^9.5"
    },
    "autoload": {
        "psr-4": {
            "App\\": "App/"
        }
    }
}


Файла index.php:
<?php
require_once 'vendor/autoload.php';
use App\Models\Router;

$routes = require 'App/Models/routes.php';
echo ( new Router )->checkRoute($routes);
?>


routes.php:
<?php
use App\Models\Route;

return [
    new Route('/test/uri', 'TestController', 'testFunc')
];

Router.php:
<?php
namespace App\Models;
use App\Controllers\TestController;

class Router
{
    public function checkRoute($routes)
    {
        foreach ($routes as $elem) {
            if ($elem->uri == $_SERVER['REQUEST_URI']) {
                $method = $elem->method;
                $controller = new $elem->controller;

                return $controller->$method();
            }
        }
    }
}

Не смотрите на саму организацию всей этой приблуды(Вывод через эхо и всё такое - всё поменяю).
Проблема вот в чем: Автоподключение срабатывает, Строчка "echo ( new Router )->checkRoute($routes);" срабатывает, также, как и подключение в файле routes.php. Но в файле Router.php происходит ошибка:

Fatal error: Uncaught Error: Class 'TestController' not found in C:\OpenServer\domains\likeavito\App\Models\Router.php:12 Stack trace: #0 C:\OpenServer\domains\likeavito\index.php(10): App\Models\Router->checkRoute(Array) #1 {main} thrown in C:\OpenServer\domains\likeavito\App\Models\Router.php on line 12

12я строчка это
$controller = new $elem->controller;
Получается, что проблема кроется в "use App\Controllers\TestController;". Без использования автозагрузки приведенный код срабатывал, теперь - нет.
Явное указание namespace тоже не решает вопрос. В гугле ничего нет(Все ссылаются на перепроверки путей, которые я копировал и писал вручную - без толку). Помогите, пожалуйста, голову сломал.

P.S. Если писать автозагрузку средствами php и подключать классы по namespace - все окей.

upd:
Совсем забыл указать, что лежит в файле Route.php:
<?php
namespace App\Models;

class Route
{
    private $uri;
    private $controller;
    private $method;

    public function __construct($uri, $controller, $method)
    {
        $this->uri = $uri;
        $this->controller = $controller;
        $this->method = $method;
    }

    public function __get($property)
    {
        return $this->$property;
    }
}
  • Вопрос задан
  • 534 просмотра
Пригласить эксперта
Ответы на вопрос 2
delphinpro
@delphinpro Куратор тега PHP
frontend developer
Могу ошибиться немного, но в целом так:
use App\Models\Route;
use App\Controllers\TestController;

return [
    new Route('/test/uri', TestController::class, 'testFunc')
];


Когда вы делаете new $elem->controller, то получается new TestController, без неймспейса.

Статическое свойство ::class содержит полное имя класса в виде строки.
Поэтому в моем варианте у вас будет получаться как раз
new \App\Controllers\TestController

Ну и можно строкой писать в роутах полное имя класса

return [
    new Route('/test/uri', '\\App\\Controllers\\TestController', 'testFunc')
];


Но это менее удобно, как мне кажется.
Ответ написан
Собсно composer dumpautoload делали?
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы