Имею достаточно стандартную схему - картинки и теги, связанные между собой связью многие ко многим. На сайте нужно сделать поиск картинок по выбранным тегам, создал я страничку со списком тегов каждому тегу добавил атрибут tag-id который содержит id тега. Сделал добавление класса Active при клике на тег.
Вопрос №1: как мне сделать так, что бы по команде (доустим нажата кнопка) все значения атрибутов tag-id у блоков, которые имеют класс Active, считывались и попадали в (допустим) массив?
Далее допустим я получил массив $tags, который содержит в себе id тегов, выбранных для поиска, допустим их будет три
Array(
[0] => 24
[1] => 12
[2] => 5)
Но что дальше? Как объяснить системе, что нужно искать картинки, которые имеют теги с выбранными id? Искать нужно картинки, а теги это ведь совсем другая таблица в БД. Единственное, что я нашёл, это использование связи как вызова к БД.
public function getArts()
{
return $this->hasMany(Art::className(), ['id' => 'art_id'])->viaTable('art_tag', ['tag_id' => 'id']);
}
public function getTagArts()
{
return $this->getArts()->asArray()->all();
}
Но это работает только если в поиске указан только один тег, поэтому в случае указания трёх тегов, я просто делал поиск для каждого по отдельности и потом соединял всё это в массив.
foreach($tags as $tag)
{
$search = Tag::findOne($tag);
$result[] = $search->getTagArts();
}
и таким образом поиск по трём тегам в отдельности превращается в это (для запроса использовался $_GET. И вроде всё нормально, для получения конечного результата нужно просто найти совпадения (в данном примере - картинка с id = 66).
Вопрос №2: а как совпадения-то искать? Массив-то трёхуровневый получается! Не нашёл я в документации PHP подходящих функций. А что будет, когда на сайте разместятся 12 000 картинок и у каждой по 3-5 тегов? Это же запрос по 3-4 тегам потребует миллионов сравнений! Может мне пересмотреть подход к поиску? Может я что-то упустил?
Определите в модели с картинками отношение, по аналогии с
public function getArts()
{
return $this->hasMany(Art::className(), ['id' => 'art_id'])->viaTable('art_tag', ['tag_id' => 'id']);
}
У вас есть массив id тегов, осталось составить условие
Arts::find()
->joinWith('tags')
->where(['tags.id'=>$tagsIds])
->all();
Документация
P.S. Код писал без проверки, если не работает, придется поправить =)
Виртуальный выделенный сервер (VDS) становится отличным выбором
Есть три сервера в разных местахХотелось бы пользоваться каждым локально
Есть запрос, которой выводит имя службы и отношение сегодняшних заказов к заказам вчерашним
Имеется JSON файл с информацией о более чем 26 тысаэропортов с такими данными:
При попытке отправки запроса на code в ответе нет заголовка "location"Находил рекомендацию отключить следование редиректу