2

I have an array of words.

$terms = array('bars', 'bar', 'fun');

I am trying to find all records that contain each word.

TableName::model()->findAll('name LIKE :name, array(':name'=>implode(',', $terms)));

Not sure the right way to find all within the array.

2 Answers 2

1

Manquer's answer is correct for your specific situation. However, due to the implementation of compare (read the source Luke) it will not work for partial searches i.e LIKE '%ADF%'. For this you can loop through the array and add each element using compare:

$c1=new CDbCriteria;

foreach($terms as $txt){ 
    $c1->compare('name',$txt,true,'OR');
}

TableName::model()->findAll($c1);

However should you run into a scenario where you need to add another condition for another group the results may not be as expected due to the way compare creates the query i.e you may end up with

WHERE ((((type=1) OR (name LIKE '%ABC%')) OR (name LIKE '%RET%')) OR (name LIKE '%Anything else%'))

To avoid this you have a couple of options:

  1. Always ensure your "array condition" appears first.
  2. Create another criteria object specifically for your array values and merge this into the other object using CDbCriteria::merge():

    $c1=new CDbCriteria; // original criteria
    $c2=new CDbCriteria; // criteria for handling our search values
    
    foreach($terms as $txt){ 
        $c2->compare('name',$txt,true,'OR');
    }
    
    $c1->mergeWith($c2); // Merge $c2 into $c1
    
  3. Create another criteria object specifically for your array values and manually add this condition into the other object using CDbCriteria::addCondition():

    $c1=new CDbCriteria; // original criteria
    $c2=new CDbCriteria; // criteria for handling our search values
    
    foreach($terms as $txt){ 
        $c2->compare('name',$txt,true,'OR');
    }
    
    $c1->addCondition($c->condition); // Merge $c2 into $c1
    $c1->params+=$c2->params; // Add the params for $c2 into $c1
    

Use (2).


Reference: http://www.yiiframework.com/wiki/610/how-to-create-a-criteria-condition-for-a-multiple-value-text-search-i-e-a-like-in/

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks topher this is actually what I needed, only thing I am worried about are the params sanitized?
1

You can use CDbCriteria class for this sort of Query in findAll like this

$terms = array('bars', 'bar', 'fun');
$criteria = new CDbCriteria 
$criteria->compare('name',$terms,true,"AND",true);

TableName::model()->findAll($criteria);

see compare documentation for details

5 Comments

hmm does this also clean the data incase of injection the way that binding the params does?
yes it does, that is why the third parameter ($escape) is set to true(by default), it will escape your input, it is there in docs
@Manquer you mean the 5th parameter. The 3rd parameter for compare is partialMatch.
@topher yeah, you are right, by mistake I was seeing the previous function in the docs addSearchCondition and in it escape is third!
@Manquer happens to all of us.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.