Хорошо, давайте рассмотрим их. Первое отличие в том, что addFilter()
оно более общее, а не специфичное для базы данных. Он также используется Varien_Directory_Collection
для фильтрации по имени файла. Но для этого ответа я собираюсь сосредоточиться на Varien_Data_Collection_Db
.
Эти методы имеют другую сигнатуру, которая addFilter
кажется менее гибкой, но вы увидите, что она также имеет свои преимущества:
1. addFieldToFilter ()
/**
* Add field filter to collection
*
* @see self::_getConditionSql for $condition
*
* @param string|array $field
* @param null|string|array $condition
*
* @return Mage_Eav_Model_Entity_Collection_Abstract
*/
public function addFieldToFilter($field, $condition = null)
параметры
addFieldToFilter () может принимать массив полей с массивом условий или одно поле с одним условием:
addFieldToFilter('field', 'value')
Результаты в: field=value
addFieldToFilter(['field1', 'field2'], ['value1', 'value2']);
Результаты в: field1=value1 OR field2=value2
Каждое условие может быть:
- одно скалярное значение (как
'value1'
и 'value2'
выше)
- массив в виде
[ operator => value ]
Zend_Db_Expr
объект
- массив условий, которые объединяются с "ИЛИ" (да, это рекурсивно)
Этот, особенно синтаксис «operator => value», задокументирован в коде Varien_Db_Adapter_Pdo_Mysql::prepareSqlCondition()
- запомните, я довольно часто их ищу:
* If $condition integer or string - exact value will be filtered ('eq' condition)
*
* If $condition is array - one of the following structures is expected:
* - array("from" => $fromValue, "to" => $toValue)
* - array("eq" => $equalValue)
* - array("neq" => $notEqualValue)
* - array("like" => $likeValue)
* - array("in" => array($inValues))
* - array("nin" => array($notInValues))
* - array("notnull" => $valueIsNotNull)
* - array("null" => $valueIsNull)
* - array("moreq" => $moreOrEqualValue)
* - array("gt" => $greaterValue)
* - array("lt" => $lessValue)
* - array("gteq" => $greaterOrEqualValue)
* - array("lteq" => $lessOrEqualValue)
* - array("finset" => $valueInSet)
* - array("regexp" => $regularExpression)
* - array("seq" => $stringValue)
* - array("sneq" => $stringValue)
*
* If non matched - sequential array is expected and OR conditions
* will be built using above mentioned structure
В операторе from
/ есть дополнительная недокументированная функция to
:
- с
['from' => $dateFrom, 'to' => $dateTo, 'date' => true]
то $dateFrom
и $dateTo
значения будут обрабатываться как даты. Они могут быть в любой форме, которая принятаVarien_Date::formatDate()
- если вам нужна функция разбора даты, но только для сравнения одного из
<=
или >=
, вы можете опустить либо 'from'
или 'to'
.
'datetime' => true
также должен работать и включать время, а не только день, но есть ошибка в Varien_Db_Adapter_Pdo_Mysql :: _ prepareSqlDateCondition () (отсутствует $includeTimestamp
параметр), которая заставляет datetime
работать так же, как и date
. Оба включают время. Так что если вам нужно сравнить только по дате, добавьте 00:00:00
к from
дате и 23:59:59
к to
дате.
Полевое картографирование
Метод использует отображение поля. Отображения полей могут быть определены в конкретных классах коллекций для создания псевдонимов полей. Вот пример из коллекции продуктов:
protected $_map = array('fields' => array(
'price' => 'price_index.price',
'final_price' => 'price_index.final_price',
'min_price' => 'price_index.min_price',
'max_price' => 'price_index.max_price',
'tier_price' => 'price_index.tier_price',
'special_price' => 'price_index.special_price',
));
2. addFilter ()
/**
* Add collection filter
*s
* @param string $field
* @param string $value
* @param string $type and|or|string
*/
public function addFilter($field, $value, $type = 'and')
параметры
addFilter()
позволяет фильтровать только одно поле по одному значению и типу . $type
может быть любым из:
- «и» (по умолчанию) - добавляет
AND $field=$value
к предложению WHERE (конечно, с правильным цитированием)
- «или» - добавляет
"OR $field=$value
к предложению WHERE (то же самое)
- «строка» - добавляет
AND $value
к предложению WHERE (т. е. $ value может быть произвольным выражением SQL)
- «public» - использует отображение поля и
_getConditionSql()
, аналогично addFieldToFilter()
. Это делает его почти таким же мощным, отсутствует только возможность добавить несколько фильтров для разных полей в сочетании с ИЛИ.
В Varien_Data_Collection_Db::_renderFilters()
вы можете увидеть, как они обрабатываются.
растяжимость
Есть одно важное отличие, которое является преимуществом addFilter()
. Он собирает фильтры для применения $this->_filters()
и добавляет их только к Zend_Db_Select
объекту запроса непосредственно перед загрузкой коллекции. addFieldToFilter()
с другой стороны, немедленно манипулирует объектом запроса.
Это позволяет вам манипулировать или удалять фильтры, которые уже были добавлены. Коллекция Varien не имеет интерфейса для этого, вы должны реализовать это в своей пользовательской коллекции. Существует метод перехвата, _renderFiltersBefore()
который вы можете переопределить.
addFilter
сattributes
?В коллекции Magento есть два метода фильтрации:
addFieldToFilter ($ field, $ condition = null)
Первый параметр
addFieldToFilter
- это атрибут, по которому вы хотите фильтровать. Второе - это значение, которое вы ищете. Вот мы добавляемsku
фильтр для значенияn2610
.Второй параметр также можно использовать для указания типа фильтрации, которую вы хотите выполнить. Здесь все становится немного сложнее, и стоит углубиться в него немного глубже.
Так что по умолчанию следующее
(по существу) эквивалентно
Взгляните на себя. Запуск следующего
будет давать
Имейте в виду, это может быстро усложниться, если вы используете атрибут EAV. Добавить атрибут
и запрос становится грубым.
Не задумываюсь над этим, но стараюсь не слишком задумываться о SQL, если вы находитесь в крайнем сроке.
Другие операторы сравнения Я уверен, что вы задаетесь вопросом «а что, если я хочу что-то, кроме равенства по запросу»? Не равно, больше, меньше, и т. Д. Второй параметр метода addFieldToFilter также охватил вас. Он поддерживает альтернативный синтаксис, в котором вместо передачи строки вы передаете один элемент Array.
Ключ этого массива - это тип сравнения, который вы хотите сделать. Значение, связанное с этим ключом, является значением, по которому вы хотите фильтровать. Давайте повторим вышеупомянутый фильтр, но с этим явным синтаксисом
Вызов нашего фильтра
Как видите, вторым параметром является массив PHP. Его ключ - eq, что означает «равно». Значение этого ключа - n2610, то есть значение, по которому мы фильтруем.
В Magento есть несколько таких английских языковых фильтров, которые принесут слезу памяти (и, возможно, боль) любым старым разработчикам Perl в аудитории.
Ниже перечислены все фильтры, а также пример их SQL-эквивалентов.
Большинство из них говорят сами за себя, но некоторые заслуживают особого
in, nin, find_in_set Условные выражения in и nin позволяют передавать массив значений. То есть порция значения вашего массива фильтра сама по себе может быть массивом.
notnull, null Ключевое слово NULL является особенным в большинстве разновидностей SQL. Как правило, это не будет хорошо работать со стандартным оператором равенства (=). Если в качестве типа фильтра указать notnull или null, вы получите правильный синтаксис для сравнения NULL, игнорируя при этом любое передаваемое вами значение.
from - to filter Это еще один специальный формат, который нарушает стандартное правило. Вместо одного элемента массива вы указываете массив из двух элементов. Один элемент имеет ключ от, другой элемент имеет ключ. Как указали клавиши, этот фильтр позволяет вам строить диапазон от / до, не беспокоясь о символах больше или меньше
Вышеуказанные урожаи
И или ИЛИ, или это ИЛИ и И? Наконец, мы подошли к логическим операторам. Это редкий момент, когда мы фильтруем только по одному атрибуту. К счастью, в коллекциях Magento есть информация. Вы можете объединить несколько вызовов в addFieldToFilter, чтобы получить несколько запросов «И».
Объединяя несколько вызовов, как описано выше, мы создадим предложение where, которое выглядит примерно так:
Тем из вас, кто только что поднял руку, да, приведенный выше пример всегда будет возвращать 0 записей. Никакое sku не может начинаться с ОБА a и a b. То, что мы, вероятно, хотим здесь, это запрос OR. Это подводит нас к еще одному запутанному аспекту второго параметра addFieldToFilter.
Если вы хотите построить запрос ИЛИ, вам нужно передать массив массивов фильтров в качестве второго параметра. Я считаю, что лучше назначить ваши отдельные массивы фильтров для переменных
а затем назначить массив всех моих переменных фильтра
В целях ясности, вот вышеупомянутый массив массивов фильтров.
Это даст нам предложение WHERE, которое выглядит примерно так:
addFilter()
позволяет фильтровать только одно поле по одному значению и типу.$type
может быть любым из:Посмотреть подробнее
источник