evgeny_s
evgeny_s

Reputation: 401

DI container can't find a class

I have an existing application with line below

\Yii::$container->invoke([$this, 'injections']);

and this line couses the error

ReflectionException Class Redis does not exist

I have a file Redis.php where defined class Redis in the /common/components directory. But yii looks for it at the /common/components/myAPI/

А class that contains a line

\Yii::$container->invoke([$this, 'injections']);

ia located by the path /common/components/myAPI/

The whole class where I try to call the Redis

abstract class AEntity{

    const API_BE_SOCCER_COUNTER = 'API_BE_SOCCER_COUNTER';
    /**
     * @var Fetcher $_fetcher
     * @var boolean $_isFromCache
     * @var APIConfig $_config
     * @var string $_redisKey
     * @var array $_params
     */
    private $_fetcher,
        $_isFromCache = null,
        $_params = [],
        $_redisKey = null,
        $_mainApi;

    /**
     * @var APIRedisManager $_redis
     */
    private $_redis,
        $_config;

    /**
     * @var Array $_dbTable
     * @var Array $_dbMap
     */
    protected $_dbMap,
              $_dbTable;

    /**
     * 
     * @return array
     */
    protected function setParams(Array $params = []){
        $this->_params = $params;
    }

    protected abstract function keyRelationShip();

    protected abstract function getAttributes();

    protected abstract function jsonArrayMap();

    protected function setRedisKey($redisData){
        $this->_redisKey = $redisData;
    }

    protected function mapArrays(){
        $jsonArrayMap = $this->jsonArrayMap();

        foreach ($jsonArrayMap as $arrayMap){
            $mapPath = $arrayMap['path'] ? explode('.', $arrayMap['path']) : null;
            $key = $arrayMap['key'];
            $arr = $arrayMap['array'];
            $assoc = $arrayMap['assoc'];
            $tmpData = $this->_mainApi;

            if($mapPath){
                foreach($mapPath as $mapper) {
                    if(!isset($tmpData[$mapper])){
                        $this->{$key} = null;

                        return false;
                    }
                    $tmpData = $tmpData[$mapper];
                }
            }
            $this->{$key} = $arr ? $this->jsonArrayMapper($tmpData, $assoc, $mapPath) : $tmpData;
        }
    }

    public function injections(APIConfig $config, Fetcher $fetcher, APIRedisManager $redisManager){
        $this->_config = $config;
        $this->_fetcher = $fetcher;
        $this->_redis = $redisManager;
    }

    protected function initialize(Array $params = []){
        $constant = static::keyRelationShip();
        $redisKey = $this->paramToRedis($params);

        $this->setParams($params);
        $this->setRedisKey($redisKey);

        \Yii::$container->invoke([$this, 'injections']);

        $this->_config->get($constant, $this->_params);
        $this->_redis->setConfig($this->_config);
        $this->_fetcher->setConfig($this->_config);
        $this->_mainApi = $this->getAPIRequest();

        $this->mapArrays();
    }


    /**
     * @return array
     */
    public function getMainApi(){
        return $this->_mainApi;
    }

    /**
     * @return APIRedisManager
     */
    public function getRedis(){
        return $this->_redis;
    }

    /**
     * @return array
     * @throws \Exception
     */
    public function loadYiiData(){
        $arrModel = [];
        if (!$this->_dbTable) new Exception('No Table Specified.');
        if (!$this->_dbMap) new Exception('No DB Map Specified.');

        foreach ($this->_dbMap as $keyApi => $keyDB){
            if(!isset($this->$keyDB)) throw new \Exception("KeyDB: $keyDB, is not Set");
            $arrModel[$this->_dbTable][$keyApi] = $this->$keyDB;
        }

        return $arrModel;
    }

    /**
     * GET API request logic
     *
     * @return array
     */
    public function getAPIRequest(){
        $redisKey = $this->formulateRedisKeyLogic();
        $storedRequest = $this->_redis->getConfig() ? $this->_redis->get($redisKey) : null;
        if(!$storedRequest){
            $this->_isFromCache = false;
            $apiRequestResult = $this->_fetcher->get()->asArray();
            $this->_redis->incrCounter();
            if($apiRequestResult && !$storedRequest){
                $serializedApiRequest = serialize($apiRequestResult);
                $this->_redis->store($serializedApiRequest, $redisKey);
            }
        }else{
            $this->_isFromCache = true;
            $apiRequestResult = unserialize($storedRequest);
        }
        return $apiRequestResult;
    }

    /** @return boolean */
    public function isFromCache(){
        return $this->_isFromCache;
    }

    private function formulateRedisKeyLogic(){
        $config = $this->_redis->getConfig();
        if(isset($config['key']) && strpos($this->_redisKey,'$.')!==false){
            $configKey = $config['key'];
            $redisKey = $configKey . $this->_redisKey;
            $redisKey = str_replace('$.', '', $redisKey);
        }
        else{
            $redisKey = $this->_redisKey;
        }

        return $redisKey;
    }

    protected function paramToRedis($param){
        $className = (new \ReflectionClass($this))->getShortName();
        $buildRedisKey = '$._'.str_replace('=', '_', http_build_query($param, null, ','));
        $paramKey = $buildRedisKey.'_'.$className;

        return $paramKey;
    }
    /**
     * GET API request logic
     *
     * @return array
     */
    protected function jsonArrayMapper(Array $entityItems, $assoc = false, $mapPath= true){

        $aEntityArray = [];
        $attributes = $this->getAttributes();
        $Klass = static::class;
        if($mapPath){
            foreach ($entityItems as $entityItem){
                $aEntity = new $Klass(false);
                foreach ($attributes as $attribute){

                    $aEntity->{$attribute} = $entityItem[$attribute];
                }
                $assoc ? $aEntityArray[$entityItem[$assoc]] = $aEntity : $aEntityArray[] = $aEntity;
            }
        }else{
            $aEntity = new $Klass(false);
            foreach ($attributes as $attribute){
                $aEntity->{$attribute} = $entityItems[$attribute];
            }
           $aEntityArray = $aEntity;
        }

        return $aEntityArray;
    }

    public function __set($key, $value){
        $this->{$key} = $value;
    }

    public function __get($name) {
        return $this->{$key};
    }

}

This is a super class for class those have such constructor

public function __construct($fullInitizalization=true, $params = []) {
    if($fullInitizalization){
        $redisParams = $this->paramToRedis($params);
        parent::initialize($params);
    }
}

When DI container trying to instaniate APIRedisConnection class, it passes parameter with type Redis:

/**  @param Redis $redis */
function __construct(Redis $redis){
   $this->_redis = $redis;
}

Class Redis can't be found in the project, but I can see it in IDE and this class was written on PHP 7 Although the whole project written on PHP 5.6

Upvotes: 1

Views: 289

Answers (0)

Related Questions