Php 试图使用某个特征,但一直说“未找到”

Php 试图使用某个特征,但一直说“未找到”,php,class,oop,traits,Php,Class,Oop,Traits,我有一个连接到外部端点的api特性。我想在一个名为ProductClass的类中使用这个特性。trait与类位于同一文件夹中,但我得到一个错误,即我在类中添加了use ApiTrait。Error表示它找不到trait,所以如果我将trait文件包含在类文件的顶部,我会得到这个错误,在中找不到ApiTrait ProductClass\apitract。 如果我将trait传递给构造函数,那么当我调用ProductClass时,我的索引页会出现一个错误,因为我没有传递trait。我不想将任何参数

我有一个连接到外部端点的api特性。我想在一个名为ProductClass的类中使用这个特性。trait与类位于同一文件夹中,但我得到一个错误,即我在类中添加了use ApiTrait。Error表示它找不到trait,所以如果我将trait文件包含在类文件的顶部,我会得到这个错误,在中找不到ApiTrait ProductClass\apitract。 如果我将trait传递给构造函数,那么当我调用ProductClass时,我的索引页会出现一个错误,因为我没有传递trait。我不想将任何参数传递给构造函数,只想将字符串top附加到.env端点。非常感谢您提供任何线索 这是我的密码

<?php
namespace ApiTrait;

require './vendor/autoload.php';
use GuzzleHttp\Client;

trait ApiTrait
{
    protected $url;
    protected $client;

  public function __construct()
  {
    $this->url =  getenv('API_URL');
    $this->client = new Client();

  }

  private function getResponse(String $uri = null)
  {
    $full_path = $this->url;
    $full_path .=$uri;
    try {
        $response = $this->client->get($full_path);    
    }
    catch (GuzzleHttp\Exception\ClientException $e) {
        $response = $e->getResponse();
    }
    return json_decode($response->getBody()->getContents(), true);

  }
  public function getAPIData($uri)
  {
    return $this->getResponse($uri);
  }
}

如果您使用的是autloader,您不应该需要:

include_once("ApiTrait.php");
您已经在Apitract命名空间中定义了您的trait:

namespace ApiTrait;
trait ApiTrait { ... }
即,特征的完整路径是
\ApiTrait\ApiTrait
。如果您在名称空间中使用的是trait,而不是它所定义的名称空间,那么您需要在引用它时从根名称空间锚定它,方法是在它前面加一个反斜杠:

namespace ProductClass;
class Product implements DataInterface
{ 
    use \ApiTrait\ApiTrait;
否则,如果使用apitract\apitract
没有前导反斜杠,那么PHP认为您引用的是当前名称空间,即
ProductClass
,生成的
\ProductClass\Apitract\Apitract
——该名称空间不存在,因此出现错误

您也可以使用类别名这样做:

namespace ProductClass;
use ApiTrait\ApiTrait;
class Product implements DataInterface
{ 
    use ApiTrait;
而且,看起来您只是将每个类都放在了它自己的名称空间中。不要那样做。使用名称空间对常用项进行分组,例如:

namespace Traits;
trait Api { ... }

namespace Traits;
trait Foo { ... }

namespace Traits;
trait Bar { ... }

namespace App;
class Product {
    use \Traits\Api;
    use \Traits\Foo;
    use \Traits\Bar;
}

如果您使用的是autloader,您不应该需要:

include_once("ApiTrait.php");
您已经在Apitract命名空间中定义了您的trait:

namespace ApiTrait;
trait ApiTrait { ... }
即,特征的完整路径是
\ApiTrait\ApiTrait
。如果您在名称空间中使用的是trait,而不是它所定义的名称空间,那么您需要在引用它时从根名称空间锚定它,方法是在它前面加一个反斜杠:

namespace ProductClass;
class Product implements DataInterface
{ 
    use \ApiTrait\ApiTrait;
否则,如果使用apitract\apitract没有前导反斜杠,那么PHP认为您引用的是当前名称空间,即
ProductClass
,生成的
\ProductClass\Apitract\Apitract
——该名称空间不存在,因此出现错误

您也可以使用类别名这样做:

namespace ProductClass;
use ApiTrait\ApiTrait;
class Product implements DataInterface
{ 
    use ApiTrait;
而且,看起来您只是将每个类都放在了它自己的名称空间中。不要那样做。使用名称空间对常用项进行分组,例如:

namespace Traits;
trait Api { ... }

namespace Traits;
trait Foo { ... }

namespace Traits;
trait Bar { ... }

namespace App;
class Product {
    use \Traits\Api;
    use \Traits\Foo;
    use \Traits\Bar;
}

你不能在构造函数中传递traits,这在语法上是不正确的。你不能在构造函数中传递traits,这在语法上是不正确的。我想我从来没有在use语句中使用过前导斜杠。可能是因为你在类定义之前做了
use Foo\Bar\Trait
别名声明(已定义为根锚定)然后在类内部使用缩写形式
use Trait
?我只在顶部使用过它,是的。第三段似乎建议在使用名称空间的任何地方都使用斜杠。至少我是这样理解的。我认为你把类别名声明与Trait用法声明混淆了。
use
关键字在类定义是一个别名声明,并且从来没有前面的反斜杠。类定义中的
use
关键字是一个trait声明。如果您在那里没有使用前面的反斜杠,则您需要位于定义trait的同一命名空间中,或者通过前面提到的
使用
关键字。如果您在名称空间中使用的不是它定义的特征,那么在引用它时,您需要从根名称空间开始锚定,方法是在它前面加一个反斜杠:阅读本文时,我得到的印象是,如果名称空间中的第一个根与当前根不同,则需要使用前导斜杠。这是真的,除非它是在文件顶部使用标准use语句(导入,解析)导入的,该语句不会指定前导斜杠。我认为我从未在use语句中使用过前导斜杠。可能是因为您在类定义之前执行了
use Foo\Bar\Trait
别名声明(已定义为根锚定)然后在类内部使用缩写形式
use Trait
?我只在顶部使用过它,是的。第三段似乎建议在使用名称空间的任何地方都使用斜杠。至少我是这样理解的。我认为你把类别名声明与Trait用法声明混淆了。
use
关键字在类定义是一个别名声明,并且从来没有前面的反斜杠。类定义中的
use
关键字是一个trait声明。如果您在那里没有使用前面的反斜杠,则您需要位于定义trait的同一命名空间中,或者通过前面提到的
使用
关键字。如果您在名称空间中使用的不是它定义的特征,那么在引用它时,您需要从根名称空间开始锚定,方法是在它前面加一个反斜杠:阅读本文时,我得到的印象是,如果名称空间中的第一个根与当前根不同,则需要使用前导斜杠。这是真的,除非它是在文件顶部使用标准use语句(导入、解析)导入的,该语句不会指定前导斜杠。