Выдает экземпляр класса в составе проекта - PullRequest
1 голос
/ 01 ноября 2019

Итак, у меня есть задача получить доступ к внешнему API, а затем отобразить результаты в отдельном FE. Я сделал ApiClass и ProductListClass. Затем со страницы индекса я включаю два файла классов, а затем пытаюсь вызвать метод ProductListClass, но я получаю ошибку ApiClass not found и не могу понять, почему любая помощь очень ценится

вот мойApiClass

   <?php

namespace app\ApiClass;
use GuzzleHttp\Client;

class ApiClass
{
    protected $url;
    protected $client;

    public function __construct(Client $client)
    {
        $this->url = 'http://external-api';
        $this->client = new $client; //GuzzleHttp\Client
    }

    private function getResponse(string $uri = null)
    {
        $full_path = $this->url;
        $full_path .=$uri;
       $result = $this->client->get($full_path);
        return json_decode($result->getBody()->getContents(), true);
    }
    public function getData($uri)
    {
        return $this->getResponse($uri);
    }
}

Это мой ProductListClass

<?php

include ("ApiClass.php");

class ProductList 
{ 
    private $apiClass;

    public function __construct(ApiClass $apiClass) {
        $this->apiClass = $apiClass;
    }

    public function getList() {
        $urlAppend = 'list';
        $list =  $this->api->getData($urlAppend);
        if(array_key_exists("error", $list)) {
            $this->getList();
        } else {
            return $list;
        }
    }
}

И это индексная страница

<?php

include_once 'app/ProductListClass.php';
include_once 'app/ApiClass.php';

$api = new ApiClass();

$productList = new ProductList($api);
$productList->getList();

, и это ошибка, которую я получаю

Неустранимая ошибка: необученная ошибка: класс 'ApiClass' не найден в /Applications/XAMPP/xamppfiles/htdocs/test/index.php:6 Трассировка стека: # 0 {main} добавлено в / Applications / XAMPP / xamppfiles/htdocs/test/index.php в строке 6

1 Ответ

1 голос
/ 01 ноября 2019

Вам необходимо создать экземпляр ApiClass из правильного пространства имен, и полное имя (FQN) для вашего ApiClass равно app\ApiClass\ApiClass. Вам нужно либо вызвать

$api = app\ApiClass\ApiClass();

, либо использовать только имя класса, импортировав пространство имен в заголовок файла:

use app\ApiClass\ApiClass;

include_once 'app/ProductListClass.php';
include_once 'app/ApiClass.php';

$api = new ApiClass();
...

Пространства имен объявляются для каждого файла, чтобы вы не могли изменитьих путем включения файлов в разных контекстах. Отсутствие пространства имен, определенного в файле, означает, что это глобальное пространство имен (например, ваше ProductListClass).

GuzzleHttp \ Client

Если вы передаете экземпляр Client в свой ApiClass, вам необходимо иметьон уже создан, и нет необходимости снова использовать new. Если вы берете строку FQN в качестве параметра, вы можете сделать это, но это не очень хорошая практика (если вы не делаете подобного рода магию в какой-либо библиотеке внедрения зависимостей).

Так что либо сделайте это (предпочтительно):

class ApiClass
{
    ...
    public function __construct(Client $client)
    {
        $this->url = 'http://external-api';
        $this->client = $client;
    }

с экземплярами API:

$api = new ApiClient(new GuzzleHttp\Client());

Или создать экземпляр внутри конструктора без параметров:

    public function __construct()
    {
        $this->url = 'http://external-api';
        $this->client = new GuzzleHttp\Client();
    }

Ps. Я думаю, вы должны научиться использовать Composer и его автозагрузку (автоматическое включение файлов классов) - работа с библиотеками (и вашими собственными классами) будет намного проще.

...