У меня есть таблица базы данных страны (как показано в руководстве ), что я тестирую приложение разработки yii2 . У меня есть population
местах, и я хочу создать публичный метод в модели Country
чтобы вернуть все страны с конкретными пределами населения. т.е. вернуть все страны с населением между x и y.
Я попробовал следующее:
// models/Country.php .... public function getPopulationBetween($lower, $upper) { return Country::findAll(['population' => [">=".$lower, "<=".$upper]]); }
В CountryController:
public function actionGetBetween($lower, $upper) { print_r(Country::getPopulationBetween($lower, $upper)); }
Он возвращает пустой массив i, e Array ()
Теперь мне нужно знать, как установить условие findAll
как условие SQL ... Where population >= 20000 AND population <= 40000000
ie Как добавить сравнение с условием с использованием массива ?!
Другая сторона – или необязательный – вопрос: почему в Country.php при вызове findAll
выглядит следующим образом:
public function getPopulationBetween($lower, $upper) { return $this->findAll(['population' => [">=".$lower, "<=".$upper]]); }
Он возвращает ошибку:
Неизвестный метод – yii \ base \ UnknownMethodException
Вызов неизвестного метода: app \ controllers \ CountryController :: findAll ()
Другими словами, почему он должен статически ставить?
Используйте модуль отладки, чтобы просмотреть сгенерированный SQL-запрос.
В вашем случае это будет:
SELECT * FROM `countries` WHERE `population` IN ('>=20000', '<=40000000')
Как видите, это определенно неправильно.
Проверьте документацию на findAll () , она не подходит для такого условия. Вместо этого используйте find()
.
1)
public static function getPopulationBetween($lower, $upper) { return Country::find() ->where(['and', "population>=$lower", "id<=$upper"]) ->all(); }
Обратите внимание, что в этом случае цитирование и экранирование не будут применяться.
2)
public static function getPopulationBetween($lower, $upper) { return Country::find() ->where(['>=', 'population', $lower]) ->andWhere(['<=', 'population', $upper]) ->all(); }
Также измените объявление метода на static
поскольку оно не зависит от экземпляра объекта.
Прочтите этот и эти разделы официальной документации, чтобы понять, как будет строиться часть запроса.
Может быть, лучше поместить этот метод в настраиваемый класс запросов. Вы можете прочитать об этом здесь .
Ответ на ваш дополнительный вопрос: вы не должны вызывать findAll()
в контексте объекта, потому что это статический метод по дизайну структуры.
Проверьте yii\db\BaseActiveRecord
:
public static function findAll($condition)