MySQL function giving wrong value - php

I am creating a search engine whereby I require videos to be displayed according to the keywords input.
So for my codes, I have
$search_exploded = explode (" ", $search);
foreach($search_exploded as $search_each){
$x = 0;
$x++;
if($x>=1){
$construct ="keywords LIKE '%$search_each%'";
}
else{
$construct ="OR keywords LIKE '%$search_each%'";
}
$x = 0;
}
and
$query ="SELECT * FROM test WHERE $construct";
$runquery = mysql_query($query);
$foundnum = mysql_num_rows($runquery);
The problem lies in the $runquery as my the error i get from my browser states that the line $foundnum = mysql_num_rows($runquery); is returning a Boolean value instead of the supposed resource type value.
Can anyone help fix this? I'm stuck on this for quite some time now. Thankful for and appreciate any help!

there is a problem in if condition and every time you set $x to 0 , then why you init it.
$x = 0;
foreach($search_exploded as $search_each){
if($x==0){
$construct =" keywords LIKE '%$search_each%' ";
}else{
$construct .=" OR keywords LIKE '%$search_each%' ";
}
$x++;
}
Try this .

You have a couple of logical errors inside your foreach loop pertaining to the $x variable.
Here is a simple way to achieve what you are trying to do (without using some kind of flags like $x)-
$search_exploded = explode (" ", $search);
// An array for the `LIKE` conditions
$construct_list = [];
// Adding the conditions in the array
foreach($search_exploded as $search_each){
$construct_list[] = "keywords LIKE '%$search_each%'";
}
// Joining them using OR
$construct = implode(" OR ", $construct_list);
// Supposing there are no keywords, the
// WHERE should not exist. So make a separate var for that -
$where_clause = "";
if(trim($construct) != ""){
$where_clause = "WHERE $construct";
}
// Perform your query
$query ="SELECT * FROM test $where_clause";

Try this:
$search_exploded = explode (" ", $search);
$construct = '1';
if (!empty($search_exploded)) {
$construct = '';
foreach($search_exploded as $search_each){
$construct .= $construct == '' ? " keywords LIKE '%$search_each%'" : " OR keywords LIKE '%$search_each%'";
}
}
$query ="SELECT * FROM test WHERE $construct";
$runquery = mysql_query($query);
if ($runquery) {
$foundnum = mysql_num_rows($runquery);
}

You seem to try to omit the OR for the 2nd and subsequent runs around the loop, but keep it for the first. should be the other way round,.
But I would probably avoid using the loop, and just use implode. Something like this (although would need to escape the values before using them in the query).
$search_exploded = explode (" ", $search);
if (count($search_exploded) > 0)
{
$construct = implode("%' OR keywords LIKE '%", $search_exploded);
$query ="SELECT * FROM test WHERE keywords LIKE '%".$construct."%'";
$runquery = mysql_query($query);
$foundnum = mysql_num_rows($runquery);
}

Related

PHP SQL Query for autocomplete

I have a MySqL DB with a table of Properties NAMES(can be more then one word) and I want to run a query to get results for the user text inputs to use for an autocomplete field.
The query I currently use is:
$query = "SELECT * FROM table WHERE LOWER(name) LIKE '%$value%' LIMIT 7";
But it is not good enough.
I tried splitting the input $value but for some reason is not working:
$values = explode(" ", $value);
$str = "";
for($i = 0; $i < count($values); ++$i)
{
if( $i == 0)
$str .= "LOWER(name) LIKE '%&$values[$i]%' ";
else
$str .= "AND LOWER(name) LIKE '%$values[$i]%' ";
}
$query = "SELECT * FROM table WHERE ". $str . " LIMIT 7";
Do you have any suggestions?
TX in advance.
Do OR instead of AND in your query:
$str .= "OR LOWER(name) LIKE '%$values[$i]%' ";

Search more then one MySql table in Mysql Database PHP

I have a database have 20 tables I want to search all of these I got stuck that how can I search this and solve this query help is very appreciated. Like:
table1
table2
table3
table4
and so one. This is my script.
<?php
if(isset($_GET["search"]))
{
$condition = '';
//$query = explode(" ", $_GET["search"]);
$query = explode(" ", $_GET["search"]);
foreach($query as $text)
{
$condition .= "`title` LIKE +'%".mysqli_real_escape_string($connect, $text)."%' OR ";
}
$condition = substr($condition, 0, -4);
$sql_query = "SELECT * FROM countries2 WHERE " . $condition;
$result = mysqli_query($connect, $sql_query);
if(mysqli_num_rows($result) > 0)
{
while($row = mysqli_fetch_array($result))
{
echo '<tr><td>'.$row["title"].'</td></tr>';
}
}
else
{
echo '<label>Data not Found</label>';
}
}
?>
Try with this
sql_query = "SELECT * FROM `countries`,`countries2` WHERE " . $condition;
i have noticed that you are making a search directory or something like this.
you may use FULLTEXT SEARCH with operators and Stemming
after this your query will look like this.
implement as per your requirement ;).
(SELECT * FROM table1 WHERE(col1,col2,clo3) AGAINST(."$search".) IN NATURAL LANGUAGE MODE)

How to eliminate duplicate search results in MySQL?

I am having some trouble displaying text from database using PHP and SQL. Below is a script similar to what I have.
$search_split = explode(" ", $search); //$search is what user entered
foreach ($search_split as $searcharray) {
$searched = mysqli_query($connect, "SELECT * FROM people WHERE `description` LIKE '%$searcharray%'");
while($info = mysqli_fetch_array($searched)) {
echo $info['description'];
}
}
So, for example the user enter 'He is male'. I split the word into three part 'He', 'is' and 'male' using 'explode' function. After that, I search the database for words that is similar to those three word. However, if a row have all the three words, it would display the row three times. How can I make it to display only once?
You could do something like this:
$search = 'test search me';
$search_split = array_map(function($piece) use ($mysqli_connection){
return "'%" . $mysqli_connection->real_escape_string($piece) . "%'";
}, explode(' ', $search)); //$search is what user entered
$search_split = implode(' OR `description` LIKE ', $search_split);
$sql = "SELECT * FROM people WHERE `description` LIKE $search_split";
echo $sql; // SELECT * FROM people WHERE `description` LIKE '%test%' OR `description` LIKE '%search%' OR `description` LIKE '%me%'
$searched = mysqli_query($connect, $sql);
Can you use full text search?
Add a full text index to the table
ALTER TABLE people ADD FULLTEXT(description);
Then you can use a query like this
SELECT *
FROM people
WHERE
MATCH ( description )
AGAINST ('+He +is +male' IN BOOLEAN MODE)
First store your results into one array then display it. Refer below code.
$search_split = explode(" ", $search); //$search is what user entered
foreach ($search_split as $searcharray) {
$searched = mysqli_query($connect, "SELECT * FROM people WHERE `description` LIKE '%$searcharray%'");
while($info = mysqli_fetch_array($searched)) {
$results[$info['YOUR_PRIMARY_KEY']] = $info['description']; // this will over write your previous record
}
}
foreach($results as $result){
echo $result;
}
Now every records display only once.
You have put your db query in a foreach loop, which loops 3 times (with the current data: he, is and male). What you want to do is put all the search variables in one query, something like:
$search_split = explode(" ", $search); //$search is what user entered
$querypart = "'%" . implode("%' AND '%", $search_split) . "%'"; // use OR or AND, to your liking
$searched = mysqli_query($connect, "SELECT * FROM people WHERE `description` LIKE " . $querypart);
while($info = mysqli_fetch_array($searched)) {
echo $info['description'];
}
This does not take any escaping/sanitizing of the query input, be aware...
$result = array();
$search_split = explode(" ", $search); //$search is what user entered
foreach ($search_split as $searcharray) {
$searched = mysqli_query($connect, "SELECT * FROM people WHERE `description` LIKE '%$searcharray%'");
while($info = mysqli_fetch_array($searched)) {
$result[] = $info['description'];
}
}
$finalres = array_unique($result);
so, finalres contains unique results
for($i = 0; $i < count($finalres); $i++)
echo $finalres[$i];

PDO - Search is querying terms as whole rather than each term separately

I currently have a simple search engine which searches a column in my database based on input from a user:
$search = $_GET['search'];
$terms = explode(" ", $search);
$sql = "SELECT * FROM people WHERE lname LIKE :search";
$q = $conn->prepare($sql) or die("failed!");
$q->bindValue(':search',"%".$search."%",PDO::PARAM_STR);
$q->execute();
if ($q){
//
do something
}
Currently it is searching for terms as a whole, for example "red desk" returns a result BUT "desk red" does not return anything
Any ideas? Any help much appreciated!
EDIT:
I have since changed it to this...
$search = $_GET['search'];
$terms = explode(" ", $search);
$sql = "SELECT * FROM people WHERE MATCH (lname,fname) AGAINST (:search IN BOOLEAN MODE)";
$q = $conn->prepare($sql) or die("failed!");
$q->bindValue(':search',"%".$search."%",PDO::PARAM_STR);
$q->execute();
it seems to be working okay for now, if anyone could suggest a better solution i would be very thankful!
This might not be the best way but I think something like this might do the job. I would myself love to know if there's a smarter way to do this!
$search = $_GET['search'];
$terms = explode(" ", $search);
$sql = "SELECT * FROM people"
if(count($terms) > 0) {
$sql .= " WHERE (lname LIKE '%:term_0%' OR fname LIKE '%:term_0%')";
for($i = 1; $i < count($terms); $i++)
$sql .= " AND (lname LIKE '%:term_" . $i . "%' OR fname LIKE '%:term_" . $i . "%')";
}
$q = $conn->prepare($sql) or die("failed!");
for($i = 0; $i < count($terms); $i++)
$q->bindValue(':term_' . $i, $terms[$i]);
$q->execute();

MySQL LIMIT question

I'm using pagination for my search results but for some reason my pagination is not working correctly with my search script. I can't seem to find the correct place to put the LIMIT $start, $display in my search query code where ever I put it in my code it displays the pagination all wrong. Can some one please help me?
Here is the part of my PHP & MySQL search code.
$mysqli = mysqli_connect("localhost", "root", "", "sitename");
mysqli_select_db($mysqli, "sitename");
$search_explode = explode(" ", $search);
foreach($search_explode as $search_each) {
$x++;
if($x == 1){
$construct .= "article_content LIKE '%$search_each%' OR title LIKE '%$search_each%' OR summary LIKE '%$search_each%'";
} else {
$construct .= "OR article_content LIKE '%$search_each%' OR title LIKE '%$search_each%' OR summary LIKE '%$search_each%'";
}
}
$construct = "SELECT users.*, users_articles.* FROM users_articles
INNER JOIN users ON users_articles.user_id = users.user_id
WHERE $construct";
$run = mysqli_query($mysqli, $construct);
$foundnum = mysqli_num_rows($run);
SQL statement.
SELECT users.*, users_articles.* FROM users_articles INNER JOIN users ON users_articles.user_id = users.user_id WHERE article_content LIKE '%find%' OR title LIKE '%find%' OR summary LIKE '%find%'OR article_content LIKE '%this%' OR title LIKE '%this%' OR summary LIKE '%this%'OR article_content LIKE '%article%' OR title LIKE '%article%' OR summary LIKE '%article%' LIMIT 0, 10
The basic syntax of SELECT is:
SELECT [fields]
FROM [tables [JOIN tables]]
WHERE [conditions]
GROUP BY [fields]
HAVING [conditions]
ORDER BY [fields]
LIMIT [limit]
So, right at the end after the WHERE conditions.
Here's the documentation which shows the full syntax.
Are you remembering to insert spaces into your string snippets as you build the query? Remember that PHP doesn't put anything into a string that you don't put there yourself.
$x = 'a';
$x .= 'b';
gives you ab, not a[space]b. Your $construct will be full of syntax errors if more than one search term is entered, as the subsequent OR will be attached directly to the end of any previous added search terms. You'll end up with something like:
[...snip...] OR summary LIKE '%$search_each%OR article_content LIKE[...snip...]
^^--syntax error here.
The same applies if you append the limit clause without making sure there's a space between the end of your query and the "LIMIT X,Y" text you append.
This should show the first 10 rows:
SELECT users.*, users_articles.* FROM users_articles
INNER JOIN users ON users_articles.user_id = users.user_id
WHERE article_content LIKE '%something%'
LIMIT 0, 10
Changing the LIMIT clause to the following should display rows from 11 to 20:
LIMIT 10, 10
Also note that you should probably escape your $construct string as #Col. Shrapnel suggested in a comment above. This is to avoid SQL injection.
In addition, you may want to investigate using Full Text Indexing instead.
$mysqli = mysqli_connect("localhost", "root", "", "sitename");
mysqli_select_db($mysqli, "sitename");
$search_explode = explode(" ", $search);
foreach($search_explode as $search_each) {
$x++;
if($x == 1){
$construct .= " article_content LIKE '%$search_each%' OR title LIKE '%$search_each%' OR summary LIKE '%$search_each%'";
} else {
$construct .= " OR article_content LIKE '%$search_each%' OR title LIKE '%$search_each%' OR summary LIKE '%$search_each%'";
}
}
$construct = "SELECT users.*, users_articles.* FROM users_articles
INNER JOIN users ON users_articles.user_id = users.user_id
WHERE $construct";
$construct .= " LIMIT 0, 10" ; // replace 0, 10 with your variables
$run = mysqli_query($mysqli, $construct);
$foundnum = mysqli_num_rows($run);

Categories