I have put together a for loop for a small search function I am building.
The code is as follows
$keyword = explode("+", $keywords);
for($i=0; $i <= count($keyword); $i++){
//check user table
$q = "SELECT id, username FROM ".TBL_USERS." WHERE username LIKE '%$keyword[$i]%'";
$result = $database->query($q);
while($row=mysql_fetch_assoc($result)){
extract($row);
echo "<a href='/profile.php?id=$id'>$username</a>";
}
}
When this runs, it is somehow retrieving all of the users from the database.
Is there any obvious reason for this?
If $keywords = "gregg"; , would this still work as there wouldn't be a + sign (only one word). Either way, this still doesn't work when it has multiple words involved!
I can confirm the query works perfectly if the term 'gregg' is passed into it.
Thanks for reading, hope you can help.
Your for loop looks like:
for ($i=0; $i <= count($keyword); $i++)
This is going past the end of $keyword by one, so the last query the loop executes is "LIKE '%%'" which would return every row. To fix this, change it to:
for ($i=0; $i < count($keyword); $i++)
Also, you cannot do "$keyword[$id]". It must be "{$keyword[$i]}"
your index has count($keyword) - 1, not count($keyword);
$keyword = explode("+", $keywords);
for($i=0; $i <= count($keyword) - 1; $i++){
//check user table
$q = "SELECT id, username FROM ".TBL_USERS." WHERE username LIKE '%".$keyword[$i]."%'";
$result = $database->query($q);
while($row=mysql_fetch_assoc($result)){
extract($row);
echo "<a href='/profile.php?id=$id'>$username</a>";
}
}
and changed quotes
try this
$q = "SELECT id, username FROM ".TBL_USERS." WHERE username LIKE '%{$keyword[$i]}%'";
or better this
$q = "SELECT id, username FROM ".TBL_USERS." WHERE username LIKE '%" . $keyword[$i] . "%'";
Consider use OR in the sql:
$keyword = explode("+", $keywords);
$keywords = array_map("mysql_real_escape_string", $keywords);
$q = "SELECT id, username FROM user WHERE username LIKE '%" . implode("%' OR username LIKE '%", $keywords) . "%';";
$result = $database->query($q);
while($row = mysql_fetch_assoc($result))
{
extract($row);
echo "<a href='/profile.php?id=$id'>$username</a>";
}
Related
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]%' ";
Apologies if I have the terminology wrong.
I have a for loop in php which operates a mysql query...
for ($i = 0; $i <count($user_id_pc); $i++)
{
$query2 = " SELECT job_title, job_info FROM job_description WHERE postcode_ss = '$user_id_pc[$i]'";
$job_data = mysqli_query($dbc, $query2);
$job_results = array();
while ($row = mysqli_fetch_array($job_data))
{
array_push($job_results, $row);
}
}
The results that are given when I insert a...
print_r ($job_results);
On screen -> Array()
If I change the query from $user_id_pc[$i] to $user_id_pc[14] for example I receive one set of results.
If I include this code after the query and inside the for loop
echo $i;
echo $user_id_pc[$i] . "<br>";
I receive the number the counter $i is on followed by the data inside the array for that counter position.
I am not sure why the array $job_results is empty from the query using the counter $i but not if I enter the number manually?
Is it a special character I need to escape?
The full code
<?php
print_r ($user_id_pc);
//Select all columns to see if user has a profile
$query = "SELECT * FROM user_profile WHERE user_id = '" . $_SESSION['user_id'] . "'";
//If the user has an empty profile direct them to the home page
$data = mysqli_query($dbc, $query);
if (mysqli_num_rows($data) == 0)
{
echo '<br><div class="alert alert-warning" role="alert"><h3>Your appear not to be logged on please visit the home page to log on or register. <em>Thank you.</em></h3></div>';
}
//Select data from user and asign them to variables
else
{
$data = mysqli_query($dbc, $query);
if (mysqli_num_rows($data) == 1)
{
$row = mysqli_fetch_array($data);
$cw_job_name = $row['job_description'];
$cw_rate = $row['hourly_rate'];
$job_mileage = $row['mileage'];
$job_postcode = $row['postcode'];
$response_id = $row['user_profile_id'];
}
}
for ($i = 0; $i <count($user_id_pc); $i++)
{
$query2 = " SELECT job_title, job_info FROM job_description WHERE postcode_ss = '{$user_id_pc[$i]}'";
$job_data = mysqli_query($dbc, $query2);
$job_results = array();
while ($row = mysqli_fetch_array($job_data))
{
array_push($job_results, $row);
}
echo $i;
?>
<br>
<?php
}
print ($query2);
print $user_id_pc[$i];
?>
This is primarily a syntax error, the correct syntax should be:
$query2 = " SELECT job_title, job_info FROM job_description WHERE postcode_ss = '{$user_id_pc[$i]}'";
Note that this is correct syntax but still wrong!! For two reasons the first is that it's almost always better (faster, more efficient, takes less resources) to do a join or a subquery or a simple IN(array) type query rather than to loop and query multiple times.
The second issue is that passing parameters in this manner leave your vulnerable to sql injection. You should use prepared statements.
The correct way
if(count($user_id_pc)) {
$stmt = mysqli_stmt_prepare(" SELECT job_title, job_info FROM job_description WHERE postcode_ss = ?");
mysqli_stmt_bind_param($stmt, "s", "'" . implode("','",$user_id_pc) . "'");
mysqli_stmt_execute($stmt);
}
Note that the for loop has been replaced by a simple if
You have to check the query variable, instead of:
$query2 = " SELECT job_title, job_info FROM job_description WHERE postcode_ss = '$user_id_pc[$i]'"
have you tried this:
$query2 = " SELECT job_title, job_info FROM job_description WHERE postcode_ss = '" . $user_id_pc[$i] . "' ";
And another thing, try something different like this:
while ($row = mysqli_fetch_array($job_data))
{
$job_results[] = array("job_title" => $row["job_title"], "job_info" => $row["job_info");
}
Then try to print the values.
Sorry but I like foreach(), so your working code is:
<?php
// To store the result
$job_results = [];
foreach($user_id_pc as $id ){
// selecting matching rows
$query2 ="SELECT job_title, job_info FROM job_description WHERE postcode_ss = '".$id."'";
$job_data = mysqli_query($dbc, $query2);
// checking if query fetch any result
if(mysqli_num_rows($job_data)){
// fetching the result
while ($row = mysqli_fetch_array($job_data)){
// storing resulting row
$job_results[] = $row;
}
}
}
// to print the result
var_dump($job_results);
I have got database with this structure
Id Country Interests
12 Azerbaijan Acting,Reading
14 Azerbaijan Reading,Writing
16 Azerbaijan Acting,sleeping
And this PHP/MYSQL
$Interests = "Acting,Reading";
$Country = "Azerbaijan";
$query = "SELECT * FROM user_opt WHERE Country='$country' AND Interests='$Interests' ";
$i = substr_count($Interests,',');
for($j = 0; $j <= $i; $j++) {
$a = explode(',', $Interests);
$query2 = "SELECT * FROM user_opt WHERE Country='$country' AND Interests LIKE '%{$a[$j]}%'";
}
So with this code it returns me this ids
12
12
16
12
14
But i want it to return
12
16
14
You probably want to use OR to find all of your interests. To do that, build up your OR statement first, then insert it into the query. NOTE: This is not a secure/preferred way of doing this! Make sure you're using PDO or mysqli and bind your parameters!
$interestArr = [];
foreach($Interests as $Interest) {
$interestArr[] = "Interests LIKE '%{$Interest}%'";
}
$query2 = "SELECT * FROM user_opt WHERE Country='$country' AND (".implode(' OR ',$interestArr).")";
you can avoid the loop using a regexp
SELECT distinct *
FROM user_opt
WHERE Country='$country' AND Interests REGEXP 'Acting|Reading';
I did it using
!=
Like this
$query2=$con->query("SELECT * FROM user_opt WHERE Country='$country' AND Interests!='$Interests' AND Interests LIKE '%{$a[$j]}%'") or die($con->error);
you don't need to loop the result, just using OR comparator
$Interests = "Acting,Reading";
$Country = "Azerbaijan";
$query = "SELECT * FROM user_opt WHERE Country='$country' AND ("
$a = explode(",", $Interests);
$interestQuery = "";
for($j = 0; $j < count($a); $j++) {
if($j+1 == count($a))
$interestQuery = $interestQuery . "Interests LIKE '%". $a[$j] ."%') "
else
$interestQuery = $interestQuery . "Interests LIKE '%". $a[$j] ."%' OR"
}
$query = $query.$interestQuery;
$echo $query;
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];
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();