简体   繁体   中英

PHP, MySQL: Making a better search?

I've made a search box feature that allows me to type in a word and then it finds any matches of the word in my database. However, it only finds EXACT matches. I'm looking for suggestions on how to make the search better.

The code below is what i currently use for searching the databases for users that might be matches for the user searching.

    $search_keys = array('fname', 'lname', 'email' );

    foreach ( $search_keys as $key )
    {
        $result = mysql_query( "SELECT id FROM users WHERE " . $key . " LIKE " . "\"{$str}\"" ) or die(mysql_error());

        while ( $row = mysql_fetch_array( $result ) )
        {

            // Get the User
            $tmp_user = new User();
            $tmp_user->getUserById( $row['id'] );

            // Add User to list of potential candidates
            array_push($users, $tmp_user);
        }
    }

I see two points where you can improve your code fragment. But first of all take care that $str is properly formatted to be safely used in your SQL query. Otherwise you will run into a problem called SQL Injection . I assume that now for your code.

  1. Use wildcards with the LIKE SQL function .
  2. Search across the three fields with one SQL query.

Please see the example code which contains both suggestions. First the SQL query is build. There is only need to run one query for all (three) fields instead of one query per field. That's useful if you extend your search later.

/* build SQL query */
$conditions = array();
$search_keys = array('fname', 'lname', 'email' );
foreach ( $search_keys as $key )
{
    $conditions[] = "{$key} LIKE \"%{$str}%\""; # Wildcard (%); [] works like array_push()
}
$query = sprintf('SELECT id FROM users WHERE (%s)', implode(' OR ', $conditions));

/* run SQL query */
$result = mysql_query($query) or die(mysql_error());
while ( $row = mysql_fetch_array( $result ) )
{
    // Get the User
    $tmp_user = new User();
    $tmp_user->getUserById( $row['id'] );

    // Add User to list of potential candidates
    array_push($users, $tmp_user);
}

Well there is always the simplest method of adding the wildcard operator, so if they enter 'Jam' it would be

SELECT id FROM users WHERE fname LIKE '%Jam%'
etc...

EDIT: The point being it would return a match on JAMIE or JAMES or LogJam or (you get the idea), which means they don't need to remember the whole name, just some part of it.

I would suggest to use a fulltext database as solr or sphinx for this kind of behaviour. If you can't or don't want to install it, you should add % to your code. $result = mysql_query( "SELECT id FROM users WHERE ". $key. " LIKE ". "\"%{$str}%\"" ) or die(mysql_error());

you should try

$result = mysql_query( "SELECT id FROM users WHERE " . $key . " LIKE " . "%" . $str . "%" ) or die(mysql_error());

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM