пытается использовать черту, но продолжает говорить, что не найден - PullRequest
0 голосов
/ 05 ноября 2019

У меня есть свойство API, которое подключается к внешней конечной точке. Я хочу использовать эту черту в классе под названием ProductClass. Черта находится в той же папке, что и класс, но я получаю ошибку, я добавляю использование ApiTrait в классе. Ошибка говорит, что не может найти признак, поэтому, если я включаю файл признака в начало файла класса, я получаю эту ошибку, не могу найти ApiTrait в ProductClass \ ApiTrait. Если я передаю признак в конструктор, я получаю сообщение об ошибке со своей индексной страницы при вызове ProductClass, потому что я не передаю признак. Я не хочу передавать какие-либо параметры конструктору, просто строка top добавляется к конечной точке .env. Любые подсказки очень ценятся, вот мой код ApiTrait

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

это мой код ProductClass

<?php

namespace ProductClass;
include_once("ApiTrait.php");

use DataInterface\DataInterface;

class Product implements DataInterface
{ 
    use ApiTrait\ApiTrait
    private $api;

    public function __construct(ApiTrait\ApiTrait $apiTrait) {
       $this->api = $apiTrait;
    }

    private function getResponse($append, $try) {
        $urlAppend = $append; 
        $good_data = false;

        do{
          try{
            $result = $this->api->getAPIData($urlAppend);
            //check data to see if valid
            if(!array_key_exists( "error",$result)){
                $good_data = true;
                return $result;
            }
          }
          catch(Exception $e){
            //call api upto 10 times
            if($try < 10) {
                sleep(1);
                getData($append, $try++);
            } else { //return a connection  error
                $api_error['error']='unable to connect to api';
                return  $api_error;
            }
        }
      } while($good_data === false);
  }

  public function getData($append, $try = 0)
  {
     return $this->getResponse($append, $try);
  }

}

1 Ответ

2 голосов
/ 05 ноября 2019

Если вы используете автозагрузчик, вам больше не нужно это:

include_once("ApiTrait.php");

Ваша черта определена в пространстве имен ApiTrait:

namespace ApiTrait;
trait ApiTrait { ... }

Т.е. полный путь черты \ApiTrait\ApiTrait. Если вы используете черту в пространстве имен, отличном от того, которое определено, то вам нужно привязать корневое пространство имен при обращении к нему, поставив перед ним обратную косую черту:

namespace ProductClass;
class Product implements DataInterface
{ 
    use \ApiTrait\ApiTrait;

В противном случае, есливы делаете use ApiTrait\ApiTrait; без начального обратного слеша, тогда PHP думает, что вы ссылаетесь на текущее пространство имен, которое ProductClass, что дает \ProductClass\ApiTrait\ApiTrait - которого не существует, следовательно, ваша ошибка.

Вы также можете сделать это с помощью псевдонимов классов:

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;
}
...