php 示例化复合项目中的类时出现问题

2ledvvac  于 2023-01-19  发布在  PHP
关注(0)|答案(1)|浏览(83)

我的任务是访问一个外部API,然后将结果呈现给一个单独的FE。我创建了一个ApiClass和一个ProductListClass。然后从索引页中包含这两个类文件,然后尝试调用ProductListClass方法,但我收到一个ApiClass未找到错误,无法完全找出原因。
这是我的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);
    }
}

这是我的产品列表类

<?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();

这就是我得到的错误
致命错误:未捕获的错误:在/applications/XAMPP/xampppfiles/htdocs/test/index.php中没有找到类'ApiClass'。堆栈跟踪:#0 {main}出现在第6行的/应用程序/XAMPP/xamppfiles/htdocs/test/index.php中

hk8txs48

hk8txs481#

您需要从正确的命名空间示例化ApiClass,并且ApiClass的完全限定名(FQN)是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示例传递给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和它的自动加载(自动包含类文件)--使用库(和你自己的类)会容易得多。

相关问题