limitphp Posted January 13, 2009 Share Posted January 13, 2009 I'm building a simple search feature on my website. if I use the LIKE '%$query%' to do the search.....would I need to use anything more to check the input besides: <?php function check_input($value) { // Stripslashes if (get_magic_quotes_gpc()) { $value = stripslashes($value); } $value = mysql_real_escape_string($value); return $value; } ?> Quote Link to comment Share on other sites More sharing options...
limitphp Posted January 13, 2009 Author Share Posted January 13, 2009 Will that function be enough to stop most script injections and other attacks? Quote Link to comment Share on other sites More sharing options...
premiso Posted January 13, 2009 Share Posted January 13, 2009 For searching, it is usually a good idea to split the query into multiple parts and exclude common words like "the" "and" "or" etc. Your check input function is fine. But for the actual searching part I would do something like this: <?php function parse_query($query, $col) { if (strlen($query) < 3) return false; if (strstr($strng, " ") === false) return " $col LIKE '%" . check_input($string) . "%' "; $words = explode(" ", strtolower($string)); $statement = array(); $notAllowed = array("and", "the", "or"); // add more if you like foreach ($words as $word) { if (strlen($word) > 2 && !in_array($word, $notAllowed)) { $statement[] = " $col LIKE '%" . check_input($word) . "%' "; } } return implode(" OR ", $statement); } ?> Should put you on the right track. That way they are more like keywords and are more for searching. Questions let me know. The above is not tested. Quote Link to comment Share on other sites More sharing options...
limitphp Posted January 13, 2009 Author Share Posted January 13, 2009 For searching, it is usually a good idea to split the query into multiple parts and exclude common words like "the" "and" "or" etc. Your check input function is fine. But for the actual searching part I would do something like this: <?php function parse_query($query, $col) { if (strlen($query) < 3) return false; if (strstr($strng, " ") === false) return " $col LIKE '%" . check_input($string) . "%' "; $words = explode(" ", strtolower($string)); $statement = array(); $notAllowed = array("and", "the", "or"); // add more if you like foreach ($words as $word) { if (strlen($word) > 2 && !in_array($word, $notAllowed)) { $statement[] = " $col LIKE '%" . check_input($word) . "%' "; } } return implode(" OR ", $statement); } ?> Should put you on the right track. That way they are more like keywords and are more for searching. Questions let me know. The above is not tested. Is $col what column they are searching in? Like band, song, and then any would equal band,song? Where do you define $strng? Quote Link to comment Share on other sites More sharing options...
premiso Posted January 13, 2009 Share Posted January 13, 2009 Sorry, I should have looked better, and yes that is what $col should be. Here is updated code: <?php function parse_query($string, $col) { if (strlen($string) < 3) return false; if (strstr($strng, " ") === false) return " $col LIKE '%" . check_input($string) . "%' "; $words = explode(" ", strtolower($string)); $statement = array(); $notAllowed = array("and", "the", "or"); // add more if you like foreach ($words as $word) { if (strlen($word) > 2 && !in_array($word, $notAllowed)) { $statement[] = " $col LIKE '%" . check_input($word) . "%' "; } } return implode(" OR ", $statement); } $query = mysql_query("SELECT xx FROM tablexx WHERE " . parse_query($_POST['query'], "band") . " ORDER BY band"); ?> Would also be the usage. Quote Link to comment Share on other sites More sharing options...
limitphp Posted January 13, 2009 Author Share Posted January 13, 2009 I could assume that some songs might be called "Ax Grinder" or some other short 2 letter word..... in that case, maybe I should let 2 letter words through.... if so, would I exclude: if (strlen($string) < 3) return false; and strlen($word) > 2 ? Also, I see that you change the query to lowercase, but will it match the mysql entry if its not in lowercase? like zeppelin matching Zeppelin? Quote Link to comment Share on other sites More sharing options...
premiso Posted January 13, 2009 Share Posted January 13, 2009 I could assume that some songs might be called "Ax Grinder" or some other short 2 letter word..... in that case, maybe I should let 2 letter words through.... if so, would I exclude: if (strlen($string) < 3) return false; and strlen($word) > 2 ? Also, I see that you change the query to lowercase, but will it match the mysql entry if its not in lowercase? like zeppelin matching Zeppelin? Yes they will match, mysql is case insensitive. If you want to allow any size letters but disallow certain words, remove the strlen checking portions. I set it all to lowercase for the in_array portion. Quote Link to comment Share on other sites More sharing options...
limitphp Posted January 13, 2009 Author Share Posted January 13, 2009 in the: foreach ($words as $word) where is $word defined? Quote Link to comment Share on other sites More sharing options...
premiso Posted January 13, 2009 Share Posted January 13, 2009 in the: foreach ($words as $word) where is $word defined? foreach That loops through the array assigning each index in that array to $word. So it is populated from the $words array. Quote Link to comment Share on other sites More sharing options...
limitphp Posted January 13, 2009 Author Share Posted January 13, 2009 So, if all they type in is "or the", it will never get: $statement[] = " $col LIKE '%" . check_input($word) . "%' "; if statement doesn't get set, will that mess up the query? Quote Link to comment Share on other sites More sharing options...
limitphp Posted January 13, 2009 Author Share Posted January 13, 2009 Also, if I separate the two words and treat them as keywords and lets say they type "red river" search by song. And lets say there is a song called "A River Runs Through It"..... since it will separate them, will that search match that song? Quote Link to comment Share on other sites More sharing options...
premiso Posted January 13, 2009 Share Posted January 13, 2009 So, if all they type in is "or the", it will never get: $statement[] = " $col LIKE '%" . check_input($word) . "%' "; if statement doesn't get set, will that mess up the query? It would return all results. <?php function parse_query($string, $col) { if (strlen($string) < 3) return false; if (strstr($strng, " ") === false) return " $col LIKE '%" . check_input($string) . "%' "; $words = explode(" ", strtolower($string)); $statement = array(); $notAllowed = array("and", "the", "or"); // add more if you like foreach ($words as $word) { if (strlen($word) > 2 && !in_array($word, $notAllowed)) { $statement[] = " $col LIKE '%" . check_input($word) . "%' "; } } if (count($statement) > 0) return implode(" OR ", $statement); else return false; } $where = parse_query($_POST['query'], "band"); if (!$where) die("Invalid search parameters."); $query = mysql_query("SELECT xx FROM tablexx WHERE " . $where . " ORDER BY band"); ?> Should do the error checking properly. To answer the red river, yes. If you want to do exact matches you will need to modify the OR to AND so it will only pull up songs with both keywords in it. You could even add a checkbox option to use AND or OR on that part if you wanted to. Quote Link to comment Share on other sites More sharing options...
limitphp Posted January 13, 2009 Author Share Posted January 13, 2009 thanks for having the patience to answer all my questions! I really appreciate it. I learned a good bit here. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.