OK, vamos examiná-los. A primeira diferença é que addFilter()
é mais genérico e não específico do banco de dados. Também é usado Varien_Directory_Collection
para filtrar por nome de arquivo. Mas para esta resposta eu vou focar Varien_Data_Collection_Db
.
Eles têm uma assinatura diferente, onde addFilter
parece ser menos flexível, mas você verá que também tem suas vantagens:
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)
Parâmetros
addFieldToFilter () pode usar uma matriz de campos com uma matriz de condições ou um único campo com uma única condição:
addFieldToFilter('field', 'value')
Resulta em: field=value
addFieldToFilter(['field1', 'field2'], ['value1', 'value2']);
Resulta em: field1=value1 OR field2=value2
Cada condição pode ser:
- um único valor escalar (como
'value1'
e 'value2'
acima)
- uma matriz no formulário
[ operator => value ]
- um
Zend_Db_Expr
objeto
- uma matriz de condições combinadas com "OR" (sim, isso é recursivo)
Isso, especialmente a sintaxe "operator => value", está documentada no código em Varien_Db_Adapter_Pdo_Mysql::prepareSqlCondition()
- lembre-se disso, eu as busco com frequência:
* 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
Há um recurso não documentado adicional no operador from
/ to
:
- com
['from' => $dateFrom, 'to' => $dateTo, 'date' => true]
os valores $dateFrom
e $dateTo
serão analisados como datas. Eles podem ter qualquer forma que seja aceita porVarien_Date::formatDate()
- se você precisar do recurso de análise de data, mas apenas para comparar um de
<=
ou >=
, poderá omitir um 'from'
ou 'to'
.
'datetime' => true
também deve funcionar e incluir a hora, não apenas o dia, mas há um erro no Varien_Db_Adapter_Pdo_Mysql :: _ prepareSqlDateCondition () ( $includeTimestamp
parâmetro ausente ) que faz o datetime
trabalho da mesma maneira que date
. Ambos incluem o tempo. Portanto, se você precisar comparar apenas por data, adicione 00:00:00
à from
data e 23:59:59
à to
data.
Mapeamento de campo
O método usa mapeamento de campo. Os mapeamentos de campo podem ser definidos em classes de coleta concretas para criar nomes de campos alternativos. Aqui está um exemplo da coleção de produtos:
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')
Parâmetros
addFilter()
permite apenas filtrar um único campo por um único valor e um tipo . $type
pode ser qualquer um de:
- "e" (padrão) - adiciona
AND $field=$value
à cláusula WHERE (é claro, com citações apropriadas)
- "or" - adiciona
"OR $field=$value
à cláusula WHERE (idem)
- "string" - adiciona
AND $value
à cláusula WHERE (ou seja, $ value pode ser uma expressão SQL arbitrária)
- "público" - usa mapeamento de campo e
_getConditionSql()
, semelhante a addFieldToFilter()
. Isso o torna quase tão poderoso quanto, apenas falta o recurso de adicionar vários filtros para campos diferentes combinados com OU.
Em Varien_Data_Collection_Db::_renderFilters()
você pode ver como eles são processados.
Extensibilidade
Há uma diferença importante que é uma vantagem addFilter()
. Ele coleta os filtros a serem aplicados $this->_filters()
e os adiciona apenas ao Zend_Db_Select
objeto de consulta antes de carregar a coleção. addFieldToFilter()
por outro lado, manipula o objeto de consulta imediatamente.
Isso permite manipular ou remover filtros que já foram adicionados. A coleção Varien não possui uma interface, você deve implementá-la em sua coleção personalizada. Existe um método de gancho _renderFiltersBefore()
que você pode substituir.
addFilter
comattributes
?A coleção Magento tem dois métodos para filtrar abaixo diferentes
addFieldToFilter ($ field, $ condition = null)
O primeiro parâmetro de
addFieldToFilter
é o atributo pelo qual você deseja filtrar. O segundo é o valor que você está procurando. Aqui estamos adicionando umsku
filtro para o valorn2610
.O segundo parâmetro também pode ser usado para especificar o tipo de filtragem que você deseja fazer. É aqui que as coisas ficam um pouco complicadas e vale a pena aprofundar um pouco mais.
Então, por padrão, o seguinte
é (essencialmente) equivalente a
Dê uma olhada por si mesmo. Executando o seguinte
vai render
Lembre-se de que isso pode ficar complicado rapidamente se você estiver usando um atributo EAV. Adicionar um atributo
e a consulta fica complicada.
Para não insistir no assunto, tente não pensar muito no SQL se estiver dentro do prazo.
Outros operadores de comparação Tenho certeza de que você está se perguntando "e se eu quiser algo diferente de igual por consulta"? Diferente, maior que, menor que etc. O segundo parâmetro do método addFieldToFilter também o abordou. Ele suporta uma sintaxe alternativa, onde, em vez de passar uma string, você passa um único elemento Array.
A chave dessa matriz é o tipo de comparação que você deseja fazer. O valor associado a essa chave é o valor pelo qual você deseja filtrar. Vamos refazer o filtro acima, mas com esta sintaxe explícita
Chamando nosso filtro
Como você pode ver, o segundo parâmetro é uma matriz PHP. Sua chave é eq, que significa igual. O valor dessa chave é n2610, que é o valor que estamos filtrando.
O Magento possui vários filtros semelhantes ao idioma inglês que trarão uma lágrima de lembrança (e talvez dor) a qualquer desenvolvedor de perl antigo na platéia.
Listados abaixo estão todos os filtros, juntamente com um exemplo de seus equivalentes SQL.
A maioria delas é auto-explicativa, mas algumas merecem destaque especial
in, nin, find_in_set Os condicionais in e nin permitem passar uma matriz de valores. Ou seja, é permitido que a parte do valor da sua matriz de filtros seja uma matriz.
notnull, null A palavra-chave NULL é especial na maioria dos tipos de SQL. Normalmente, não funciona bem com o operador de igualdade padrão (=). A especificação de nulo ou nulo como seu tipo de filtro fornecerá a sintaxe correta para uma comparação NULL, ignorando o valor que você passar
de - para filtrar Esse é outro formato especial que quebra a regra padrão. Em vez de uma matriz de elemento único, você especifica uma matriz de dois elementos. Um elemento tem a chave de, o outro elemento tem a chave de. Conforme as teclas indicadas, esse filtro permite criar um intervalo de / para sem ter que se preocupar com símbolos maiores e menores que
Os rendimentos acima
AND ou OR, ou são OR e AND? Finalmente, chegamos aos operadores booleanos. É o raro momento em que estamos filtrando apenas um atributo. Felizmente, as coleções do Magento nos cobrem. Você pode encadear várias chamadas para addFieldToFilter para obter um número de consultas "AND".
Ao encadear várias chamadas como acima, produziremos uma cláusula where que se parece com a seguinte
Para aqueles que levantaram sua mão, sim, o exemplo acima sempre retornaria 0 registros. Nenhum sku pode começar com AMB e a e b. O que provavelmente queremos aqui é uma consulta OR. Isso nos leva a outro aspecto confuso do segundo parâmetro do addFieldToFilter.
Se você deseja criar uma consulta OR, precisa passar uma Matriz de filtro Matrizes como o segundo parâmetro. Acho melhor atribuir seu filtro individual Arrays a variáveis
e depois atribuir uma matriz de todas as minhas variáveis de filtro
No interesse de ser explícito, aqui está a matriz acima mencionada de matrizes de filtro.
Isso nos dará uma cláusula WHERE que se parece com a seguinte
addFilter()
permite apenas filtrar um único campo por um único valor e um tipo.$type
pode ser qualquer um de:Veja mais detalhes
fonte