Chaya Cooper
Chaya Cooper

Reputation: 2530

Unable to fetch db data in proper format for PHP in_array()

I've tried everything imaginable, but when I create an array dynamically from db values I can't seem to get it formatted properly to work with in_array(). I believe that the problem is simply the need to encase each value in quotes, because I have no trouble using in_array() with a hard-coded array as long as it's formatted that way, but I haven't been able to add the quotes with either explode or implode.

What I'm trying to do: This is a very simplified example of what I'm trying to, which is to filter a query's result based on how well a product matches a list of customer preferences (no risk of injection, and I've tried doing it both with and without PDO's).

I know that there are several very similar postings, but after spending more hours than I care to admit trying to implement every tutorial and posting I've seen, I decided it was time to turn to the community for help.

in_array() statement

  $Color='Black';
  if (in_array($Color, $colors_love_Arrays)) {
    echo "Matches: ", $Color;
}

Query which forms array

$colors_love_Array = array(); 
$result = mysql_query("SELECT * FROM style WHERE style.user_id = $user_id") or die(mysql_error());    

while ($row_profile = mysql_fetch_array($result)) {    
// I've tried both of these, both separately and together
$colors_love_Array[] = $row_profile['colors_love'];    
$colors_love_Array = explode('",', $row_profile['colors_love']);  

}

How I need to structure the array

$colors_love_Array = array('Black','Charcoal','Light_Gray','White','Royal_Blue','Dodger_Blue','Red'); 

The result of var_dump ($colors_love_Array); is:

array(1) { [0]=> string(59) "Black,Charcoal,Light_Gray,White,Royal_Blue,Dodger_Blue,Red " } 

Upvotes: 0

Views: 372

Answers (4)

ankur bagla
ankur bagla

Reputation: 61

check this, i think it should work for you

$colors_love_Array = array();
$result = mysql_query("SELECT * FROM style WHERE style.user_id = $user_id") or die(mysql_error());

while ($row_profile = mysql_fetch_array($result)) {
// I've tried both of these, both separately and together
$colors_love_Array[] = $row_profile['colors_love'];
}

$newColorsArray = explode(",", implode($colors_love_Array));

if(in_array($Color, $newColorsArray)){
echo "Matches: ".$Color;
}

Upvotes: 1

tftd
tftd

Reputation: 17062

Your approach is a bit wrong. The code is storing all of the colors as a string, although you receive them as an array. Therefore you need to use strpos to search through the string for a specific occurrence of another string - i.e. does the string contain Black anywhere. Using this approach will make your life quite harder if for example later you need to be able to sort the colors in a specific way.

As @Adam Sinclair suggested, because the data is contained as a string, you can use preg_match to check if the string contains a color. Unfortunately preg_match is quite an expensive function and should be used wisely and as a last resort.

Also, I would suggest you use PDO and prepared statements for your connections to the database - you don't want SQL injections, right?

In my opinion, the better way of achieving your task is using code similar to the one below:

<?php    
// Host
$hostname = 'localhost';

// Database
$database = 'database';

// Username
$username = 'user';

// Password
$password = 'pass';

// Connection DSN.
// http://php.net/manual/en/ref.pdo-mysql.connection.php
$dsn = 'mysql:host='.$hostname.';dbname='.$database;

try {
    // Create a database connection using PDO
    $db = new PDO($dsn, $username, $password);

    // The value of the user_id (i.e. $_SESSION['user_id'])
    $user_id = 1301;

    // Get all colors, liked by a specific user.
    $query = $db->prepare('SELECT * FROM style WHERE style.user_id = :user_id');
    // Bind the value of $user_id to :user_id in the query.
    $query->bindValue(':user_id', $user_id);
    // Execute the query
    $query->execute();

    // Gets all results for a specific database column (i.e. 'color_loves').
    // In my table, I had color_id, user_id, color_loves, therefore the desired index is 2.
    // NOTE: Remember array indexes start counting from 0.
    $colors = $query->fetchAll(PDO::FETCH_COLUMN, 2);

    // The output of the above will be something similar to this:
    // array(5) { [0]=> string(5) "Black" [1]=> string(8) "Charcoal" [2]=> string(10) "Light_Gray" [3]=> string(5) "White" [4]=> string(10) "Royal_Blue" }

    $color='Black';
    if (in_array($color, $colors)) {
        echo "Matches: ", $color;
    }
    // Outputs Matches: Black

    // Disconnect from the database.
    $db = null;
}
catch(PDOException $e)
{
    // Output any exception messages that might occur
    echo $e->getMessage();
}

?>

As you can see - it's simple, clean, secured and extendable. No need of hard-to-read regex, exploding/imploding strings fron/to arrays and etc. And if in future, your task evolves and the colors need to be sorted, you can easily do that by readying the manual.

Upvotes: 0

Adam Sinclair
Adam Sinclair

Reputation: 1649

As the documentation state for in_array:

in_array — Checks if a value exists in an array

But the var_dump clearly tells you that the nested value you want is a string.

array(1) { [0]=> string(59) trim("Black,Charcoal,Light_Gray,White,Royal_Blue,Dodger_Blue,Red ") }
                 ^^^^^^

One possible way is to use strpos instead of in_array:

$Color='Black';
  if (strpos($Color, $colors_love_Arrays[0]) !== false) {
    echo "Matches: ", $Color;

However it will match if you have colors like, lets say, WeirdBlack.

Indeed:

$Color='Black';
  if (strpos($Color, "WeirdBlack") !== false) {
    echo "Matches: ", $Color;

OUTPUT

Matches: WeirdBlack;

Alternatively you want to use preg_match:

$Color='Black';
  if (preg_match('/(?:^|,)('.$Color.')(?:,|$)/', "Black,Charcoal,Light_Gray,White,Royal_Blue,Dodger_Blue,Red ") !== false)
    echo "Matches: ", $Color;

The regex used is '/(?:^|,)('.$Color.')(?:,|$)/':

DEMO


You might want to get an array instead. Then use explode:

$arr = explode(',', trim($colors_love_Array[0]));

And then use it like this:

$Color='Black';
  if (in_array($Color, $arr)) {
    echo "Matches: ", $Color;
}

Or use preg_match again:

$Color = 'Black';
$arr = explode(',', trim("Black,Charcoal,Light_Gray,White,Royal_Blue,Dodger_Blue,Red "));
   if (preg_grep('/('.$Color.')/', $arr))
        echo 'match';

Upvotes: 2

Kohjah Breese
Kohjah Breese

Reputation: 4136

Shouldn't your result be an array, rather than a string separated by commas?

Anyway, with your result as var_dumped above.

$parts = explode( ',', trim( $colors_love_Array ) );
if( in_array( 'Black', $parts ) )
    echo "is here\n";

But I would imagine you actually want to get this:

"Black,Charcoal,Light_Gray,White,Royal_Blue,Dodger_Blue,Red"

as an array. Since I do not know what is in your DB, I cannot offer advice in that area.

Upvotes: 0

Related Questions