5

So I'm trying to take a search string (could be any number of words) and turn each value into a list to use in the following IN statement) in addition, I need a count of all these values to use with my having count filter

$search_array = explode(" ",$this->search_string);
$tag_count = count($search_array);

$db = Connect::connect();
$query = "select p.id
          from photographs p
          left join photograph_tags c
          on p.id = c.photograph_id
          and c.value IN ($search_array)
          group by p.id
          having count(c.value) >= $tag_count";

This currently returns no results, any ideas?

Solution:

$search_array = explode(" ",$this->search_string);

foreach ($search_array as $key => $value) {

    $new_search_array[] = "'$value'";

}

$search_string = implode(',', $new_search_array);

This gives me a comma separated list

0

8 Answers 8

6
$search_array = implode(",", $search_array);

because IN takes a comma separated list of values. (But you need to ensure $search_array's contents are quoted, if they're words.)

Doing it in one step might look like this:

function quoteAndComma($result, $each) {
  return $result . ', "'.$each.'"';
}

$search_array = array_reduce($search_array, "quoteAndComma", '');
Sign up to request clarification or add additional context in comments.

4 Comments

You can accomplish the same with "'" . implode("','", $search_array) . "'", although it is perhaps not as elegant as your solution :-)
Oh nice, I hadn't even thought of that!
Nice solution, but note that this won't work as expected in PHP before 5.3, because array_reduce() accepts only integer as a third parameter in 5.2 and earlier. As a result the string will be like '0, "one", "two", ...'
Thanks for the additional info, Alexander. I only started using array_reduce() from 5.3 onwards, so I didn't know that!
4

You should build a string from this array first:

// Don't forget to escape the data!
$search_array = array_map('mysql_real_escape_string', $search_array);

// Convert array to a string like "'one', 'two', ..."
$search_values = "'" . implode("', '", $search_array) . "'";

// Build a query
$query = "select ... c.value IN ($search_values) ..."

Comments

0

Use

and c.value IN (implode(', ', $search_array))

$search_array is an array that you are directly concatenating into a string. You need to turn it into a string before doing that.

Also, why are you not echoing your sql statement to see that you're actually feeding to MySQL?

2 Comments

please mysqli_real_escape_string the values in the array first
I haven't added any injection protection first, just getting the basic query working.
0

IN expects a comma-separated list of values, (quoted if they are strings). What does your value of $this->search_string contain? And exploding it into an array will NOT work... try echoing your $query to see exactly what you get.

Comments

0

...

$search_array = explode(" ",$this->search_string);
$search = implode(",", $search_array);
$tag_count = count($search_array);

$db = Connect::connect();
$query = "select p.id
          from photographs p
          left join photograph_tags c
          on p.id = c.photograph_id
          and c.value IN ($search)
          group by p.id
          having count(c.value) >= $tag_count";

Comments

0

I'm not a PHP developer so excuse me if I miss something, but the array values should be sparated by commas and in single quotes:

WHERE c.value IN ('a','b','c')

Comments

0
    $search_array = explode(" ",$this->search_string);

    foreach ($search_array as $key => $value) {

        $new_search_array[] = "'$value'";

    }

    $search_string = implode(',', $new_search_array);

Comments

0

You are not populating your IN statement in the right way, you have two choices, either pass the search string separated by commas, or do it yourself, like in :

$search_array = explode(" ", $this->search_string);

for ($i = 0; $i < count($search_array); $i++)
{
   $search_array[$i] = "'" . $search_array[$i] . "'";
}

$list = implode(",", $search_array);

$tag_count = count($search_array);

$db = Connect::connect();
$query = "select p.id
          from photographs p
          left join photograph_tags c
          on p.id = c.photograph_id
          and c.value IN ($list)
          group by p.id
          having count(c.value) >= $tag_count";

Comments

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.