在组合项目中实例化 class 时出现问题
Issues instantiating class in composition project
所以我有一个任务是访问外部 api 然后将结果渲染到一个单独的 FE。我制作了一个 ApiClass 和一个 ProductListClass。然后从索引页中我包含了两个 class 文件,然后我试图调用 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();
这是我遇到的错误
Fatal error: Uncaught Error: Class 'ApiClass' not found in /Applications/XAMPP/xamppfiles/htdocs/test/index.php:6 Stack trace: #0 {main} thrown in /Applications/XAMPP/xamppfiles/htdocs/test/index.php on line 6
您需要从正确的命名空间实例化 ApiClass,并且 ApiClass
的完全限定名称 (FQN) 是 app\ApiClass\ApiClass
。您需要拨打
$api = app\ApiClass\ApiClass();
或通过在文件头中导入名称空间仅使用 class 名称:
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 及其自动加载(自动包含 class 文件)- 使用库(和您自己的 classes)会容易得多。
所以我有一个任务是访问外部 api 然后将结果渲染到一个单独的 FE。我制作了一个 ApiClass 和一个 ProductListClass。然后从索引页中我包含了两个 class 文件,然后我试图调用 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();
这是我遇到的错误
Fatal error: Uncaught Error: Class 'ApiClass' not found in /Applications/XAMPP/xamppfiles/htdocs/test/index.php:6 Stack trace: #0 {main} thrown in /Applications/XAMPP/xamppfiles/htdocs/test/index.php on line 6
您需要从正确的命名空间实例化 ApiClass,并且 ApiClass
的完全限定名称 (FQN) 是 app\ApiClass\ApiClass
。您需要拨打
$api = app\ApiClass\ApiClass();
或通过在文件头中导入名称空间仅使用 class 名称:
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 及其自动加载(自动包含 class 文件)- 使用库(和您自己的 classes)会容易得多。