Кеш запросов к БД, как передать параметры?

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
w4y
Сообщения: 46
Зарегистрирован: 2016.07.11, 07:10

Кеш запросов к БД, как передать параметры?

Сообщение w4y »

Есть функция выборки городов используется для написания своего правила формирования URL:

Код: Выделить всё

private function getCitiesName($countryId = null, $cityId = null)
    {
        if ( isset($countryId) && isset($cityId) ){
           // $city = City::getDb()->cache(function ($db) {
                if (isset($countryId)){
                    $city = City::find()
                        ->select('id, slug, country_id')
                        ->where(['country_id' => $countryId])
                        ->asArray()
                        ->indexBy('id')
                        ->all();
                }
                 else{
                     return null;
                 }
            //});
            return $city[$cityId]['slug'];
        }
        return null;
    } 
вызывается эта функция в:

Код: Выделить всё

public function createUrl($manager, $route, $params)
    {
        if ($route === 'site/index'){

            if ( isset($params['country']) ){

                $country = $this->getCountryName($params['country']);

                if ( isset($params['city']) ){

                    $city = $this->getCitiesName($params['country'], $params['city']);

                    if ($country !== null && $city !== null){
                        return $country . '/' .  $city;
                    }
                }

                if ($country !== null) {

                    return $country;

                }
            }
        }
        return false;
    } 

Все дело в том что если у определенной страны много городов, то много и соответствующих запросов к БД, вопрос в том как можно закэшировать этот запрос с передачей параметра?
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: Кеш запросов к БД, как передать параметры?

Сообщение zelenin »

w4y писал(а):Все дело в том что если у определенной страны много городов, то много и соответствующих запросов к БД
почему много, если запрос один?
caHek2x
Сообщения: 1242
Зарегистрирован: 2016.04.12, 20:41

Re: Кеш запросов к БД, как передать параметры?

Сообщение caHek2x »

я может чегото не понял ... но зачем запрашивать все города ... если у вас есть cityId ... ради использования в будущем закешированного всего, вытащенного за один раз ?

Код: Выделить всё

if ( isset($countryId) && isset($cityId) ){
   if (isset($countryId)){
   }
} 
хм )
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: Кеш запросов к БД, как передать параметры?

Сообщение zelenin »

а, да, увидел, что передается cityId, но не рассмотрел что он не используется и выбираются все города. Так нехер все города выбирать - выбирай один ьконкретный по cityId
w4y
Сообщения: 46
Зарегистрирован: 2016.07.11, 07:10

Re: Кеш запросов к БД, как передать параметры?

Сообщение w4y »

Это не для контролера функции а для формирования правил - если ссылки выведены (20 ссылок), как понял я и вызывается функция 20 раз...

Например стран у меня 220 и раньше было 220 запросов - потому что вывожу интерактивную карту с ссылками, потом сделал кэш и получился всего 1 запрос:

Код: Выделить всё

 private function getCountryName($countryId = null)
    {
        if (isset($countryId)){
            $country = Country::getDb()->cache(function ($db) {
                return Country::find()
                    ->select('id, slug')
                    ->asArray()
                    ->indexBy('id')
                    ->all();
            });
            return $country[$countryId]['slug'];
        }
        return null;
    } 
А как сделать для городов не знаю, если код раскомментировать города (функция getCitiesName($countryId = null, $cityId = null)) вообще не получаю городов.
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: Кеш запросов к БД, как передать параметры?

Сообщение zelenin »

w4y писал(а):Это не для контролера функции а для формирования правил - если ссылки выведены (20 ссылок), как понял я и вызывается функция 20 раз...
в таком случае верно.

у вас уже кэшируются все города страны. какие параматеры хотите передать?

кэшируйте еще саму карту. Fragment Cache называется вроде бы.
w4y
Сообщения: 46
Зарегистрирован: 2016.07.11, 07:10

Re: Кеш запросов к БД, как передать параметры?

Сообщение w4y »

у вас уже кэшируются все города страны. какие параматеры хотите передать?
У меня кэшируются только страны:

Код: Выделить всё

 private function getCountryName($countryId = null)
    {
        if (isset($countryId)){
            $country = Country::getDb()->cache(function ($db) {
                return Country::find()
                    ->select('id, slug')
                    ->asArray()
                    ->indexBy('id')
                    ->all();
            });
            return $country[$countryId]['slug'];
        }
        return null;
    } 
А вот с городами проблема, потому что параметры передаваемые в функцию ($countryId) не видны из City::getDb()->cache(function ($db) { // из этого блока });
Вот и интересует как сюда можно передать и проверить параметры/переменные?

Код: Выделить всё

private function getCitiesName($countryId = null, $cityId = null)
    {
        if ( isset($countryId) && isset($cityId) ){
           // $city = City::getDb()->cache(function ($db) {
                if (isset($countryId)){
                    $city = City::find()
                        ->select('id, slug, country_id')
                        ->where(['country_id' => $countryId])
                        ->asArray()
                        ->indexBy('id')
                        ->all();
                }
                 else{
                     return null;
                 }
            //});
            return $city[$cityId]['slug'];
        }
        return null;
    } 
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: Кеш запросов к БД, как передать параметры?

Сообщение zelenin »

ну в первом коде у вас кэшируются страны, во втором точно также кэшируйте города.
w4y
Сообщения: 46
Зарегистрирован: 2016.07.11, 07:10

Re: Кеш запросов к БД, как передать параметры?

Сообщение w4y »

Может конечно я просто туплю, но я не понимаю как передать $countryId в запрос который выполняется в анонимной функции?

Код: Выделить всё

private function getCitiesName($countryId = null, $cityId = null)
    {
        if ( isset($countryId) && isset($cityId) ){
           $city = City::getDb()->cache(function ($db) {
              // КАК сюда передать $countryId???
                   return  City::find()
                        ->select('id, slug, country_id')
                        ->where(['country_id' => $countryId])
                        ->asArray()
                        ->indexBy('id')
                        ->all();
                }
           });
            return $city[$cityId]['slug'];
        }
        return null;
    }
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: Кеш запросов к БД, как передать параметры?

Сообщение zelenin »

function(...) use ($countryId) - что тупить, если на это есть документация php..
w4y
Сообщения: 46
Зарегистрирован: 2016.07.11, 07:10

Re: Кеш запросов к БД, как передать параметры?

Сообщение w4y »

zelenin, спасибо огромное

Пропустил как то мимо глаз...
// Наследуем $message
$example = function () use ($message) {
var_dump($message);
};
$example();
Ответить