I've built a simple search bar for my website, and if my query looks like this, it works great:
$sql = query("SELECT id, firstname, lastname, username, location FROM
users WHERE firstname LIKE '%" . $search_query . "%' LIMIT 20");
but if i write it like that, it echoes a SQL Syntax error :
$sql = query("SELECT id, firstname, lastname, username, location FROM
users WHERE firstname, lastname, username, location LIKE '%" . $search_query . "%'
LIMIT 20");
The difference between the 2 queries is that the 2nd one will search through multiple columns which is what i need since my users can search either for a name or a city.
How should I re-write it ?
You have to repeat the LIKE statement for each field, unfortunately.
SELECT id, firstname, lastname, username, location FROM users
WHERE firstname LIKE '%" . $search_query . "%'
OR lastname LIKE '%" . $search_query . "%'
OR username LIKE '%" . $search_query . "%'
OR location LIKE '%" . $search_query . "%'
LIMIT 20
The keyword LIKE does not work like that. Try this:
$like_string = "'%$search_query%'";
$query = "SELECT id, firstname, lastname, username, location
FROM users
WHERE firstname LIKE $like_string OR
lastname LIKE $like_string OR
username LIKE $like_string OR
location LIKE $like_string
LIMIT 20";
$sql = query($query);
As others will tell you, it is smart to account for SQL injection and perform sanity and validity checks before accepting any user data. Take a look at this question on how to prevent SQL injection.
The PDO extension or the mysqli extension is preferred for MySQL and mysql_ functions have been deprecated (as can be seen throughout the documentation).
You need to specify each column's search condition separately:
$sql = query("SELECT id, firstname, lastname, username, location
FROM users
WHERE firstname LIKE '%$search_query%'
OR lastname LIKE '%$search_query%'
OR username LIKE '%$search_query%'
OR location LIKE '%$search_query%'
LIMIT 20");
As you can see, I've removed the concatenation - since you're using double quotes, variables can go directly into the query.
Also, I hope $search_query has been santised, or you're opening yourself upto SQL injection attacks; really, you should be using parameterised queries by now.
Related
I have an SQL query
qry1 =
"SELECT DISTINCT (forename + ' ' + surname) AS fullname
FROM users
ORDER BY fullname ASC";
This gets forename and surname from a table called users and concatenates them together, putting a space in the middle, and puts in ascending order.
I then put this into an array and loop through it to use in a select drop-down list.
This works, however, what I now want to do is compare the fullname with a column called username in another table called users.
I'm struggling with how to write the query though. So far I have...
$qry2
"SELECT username
FROM users
WHERE (forename + ' ' + surname) AS fullname
=" . $_POST['Visiting'];
Any advice on to what I am doing wrong?
Rather CONCAT the two columns together. Also remember to escape any variables before adding them to your query.
$qry2 =
"SELECT username AS fullname
FROM users
WHERE CONCAT(forename, ' ', surname)
='" . mysqli_real_escape_string($connection, $_POST['Visiting']) . "'";
Where $connection is your current db connection
I'm not sure that the use of the declared word 'AS' after 'WHERE' is correct in principle.
if you use MySQL, query should look like this:
SELECT [columns]
FROM [tables] [AS declareTableName]
WHERE [condition]
GROUP BY [declares|columns]
SORT BY [declares|columns]
But, i think your problem not in the query. Concatenating names in the query is incorrect. You must separate string with names in Back-end and than use it in query:
$names = explode(' ', $_POST['Visiting']);
This might work, assuming you use PDO:
$qry2 = "SELECT username FROM users
WHERE CONCAT(forename, ' ', surname) = '" . $conn->quote($_POST['Visiting']) . "'";
...but you should have a look at the possible vulnerabilities through SQL injections.
Without knowing which library you use for connecting to the MySQL database, it's impossible to give proper advise about which method you should use for escaping the user's input. quote is the PDO method for escaping, real-escape-string is the equivalent for MySQLi
You should really refer to using PDO.
When using PDO you can bind parameters to specified parts of your query. PDO also has built-in SQL-injection prevention, which is a great security measure that you won't have to deal with yourself. I hope this answers your question. See my example below.
Example:
// Create a new PDO object holding the connection details
$pdo = new PDO('mysql:host=localhost;dbname=test', $user, $pass);
// Create a SQL query
$query = "SELECT username FROM users WHERE (forename + ' ' + surname) AS fullname = :visiting;";
// Prepare a PDO Statement with the query
$sth = $pdo->prepare($query);
// Create parameters to pass to the statement
$params = [
':visiting' => $_POST['Visiting']
]
// Execute the statement and pass the parameters
$sth->execute($params);
// Return all results
$results = $sth->fetchAll(PDO::FETCH_ASSOC);
If you have any other questions about PDO, please refer to the following:
Official PDO documentation:
http://php.net/manual/en/book.pdo.php
Documentation on how to bind variables:
http://php.net/manual/en/pdostatement.bindparam.php
You can use this construction (without "AS fullname" and with apostrophes around variable):
$qry2 "SELECT username FROM users WHERE (forename + ' ' + surname) = '" . $_POST['Visiting'] . "'";
But for better security (SQL injection) You should use the escaping of variable. For example this construction, if You use MySQL database:
$qry2 "SELECT username FROM users WHERE (forename + ' ' + surname) = '" . mysql_real_escape_string($_POST['Visiting']) . "'";
This one came close to answering my question: Protect from injections and right syntax for $_GET method
However, my issue is that I am trying to combine the wildcard search %. So my original statement that works is like this which is wrapped in a try catch block.
$sql = "SELECT id, Store_name, address_line_1, city, state FROM pharmacies_weno WHERE Store_name LIKE '%".$_GET['term']."%' AND city LIKE '%".$_GET['city']."%'";
$sql .= " AND address_line_1 LIKE '%".$_GET['address']."%'";
But of course I want to make the statement like this.
$sql = "SELECT id, Store_name, address_line_1, city, state FROM pharmacies_weno WHERE Store_name LIKE ? AND city LIKE ?;
$sql .= " AND address_line_1 LIKE ? ";
With a statement like this
$stm = ('%$term%','%$city%','%$address%');
However, this is not working. I have tried all the variations of double and single quotes that I can think of along with the concatenation but nothing is working for me. I put the $_GET variables into another variable.
Yes there is other code in the program that does the binding. The final statement should look something like.
$sql = "SELECT id, Store_name, address_line_1, city, state FROM pharmacies_weno WHERE Store_name LIKE ? AND city LIKE ?;
$sql .= " AND address_line_1 LIKE ? ";
$stm = ('%$term%','%$city%','%$address%');
sqlStatement($sql,$stm); //This is where the binding takes place in the program
So what I need to know is how to use the wildcard with the variable.
if you are using PDO then i would like to do like-
$sql = "SELECT id, Store_name, address_line_1, city, state FROM pharmacies_weno
WHERE Store_name LIKE :store_name
AND city LIKE :city
AND address_line_1 LIKE :address_line_1 ";
// now prepared statement like-
$stmt = $conn->prepare($sql);
$stmt->execute(array(
':store_name'=>'%'.$_GET['store_name'].'%',
':city'=>'%'.$_GET['city'].'%',
':address_line_1'=>'%'.$_GET['address_line_1'].'%'
));
$result=$stmt->fetchAll();
if you didnot use pdo then have a look over pdo prepared statement via php.net
I'm testing a small search feature:
But I've come across an error that I cannot seem to solve. You can see the PDO query here:
$search = "test1"; //later to be changes to $_POST ['search'];
$sql = "SELECT id, name FROM clients WHEE name like %:name% order by id LIMIT 5";
$stm = $db->prepare ( $sql );
$stm->bindParam ( ":name" , $search);
$result = $stm->execute ();
As you can see, I'm trying to bind the parameter %:name% from my query, but I don't know if that's actually possible?
I receive the error:
Uncaught exception 'PDOException' with message 'SQLSTATE[42000]:.....
And I can see in the error that '' has been put around test1 %'test1'%
Is what I'm trying possible, or do I need to do something like this?
$query = "SELECT id, name FROM clients WHEE name like :name order by id LIMIT 5";
$sql->execute(array(":name" => "%" .$search . "%"));
Use
LIKE CONCAT('%', :name, '%')
I'm new to SQL can't seem to group multiple LIKE statements together. Any idea what I am doing incorrectly?
$query = mysqli_query($mysqli, "SELECT * FROM table_name
WHERE Page LIKE ".$page."
AND Profession LIKE ".$profession.",
AND Age LIKE ".$age."");
Thanks.
Its likely because they are not enclosed correctly
$query = mysqli_query($mysqli, "SELECT * FROM table_name
WHERE Page LIKE ".$page."
AND Profession LIKE ".$profession."
AND Age LIKE ".$age."");
when compiled is something like
SELECT * FROM table_name
WHERE Page LIKE page number 1
AND Profession LIKE my profession
AND Age LIKE 100
which is invalid SQL
You need to use quotes and escape the values
$query = mysqli_query($mysqli, "SELECT * FROM table_name
WHERE Page LIKE '%".$page."%'
AND Profession LIKE '%".$profession."%'
AND Age LIKE '%".$age."%'");
would give
SELECT * FROM table_name
WHERE Page LIKE '%page number 1%'
AND Profession LIKE '%my profession%'
AND Age LIKE '%100%'
Which will likely give a result of what you would expect
Make sure the values are safe though by at bare minimum using http://www.php.net/manual/en/mysqli.real-escape-string.php though looking at prepared statements would be a better option
Edit:
Remove comma after LIKE ". $profession."
This would be a lot easier to get right if you use placeholders and bind_param:
$stmt = mysqli_query($mysqli, "SELECT * FROM table_name
WHERE Page LIKE ?
AND Profession LIKE ?
AND Age=?");
mysqli_stmt_bind_param($stmt, 'ssi', "%" . $page . "%", "%" . $profession. "%", $age);
mysqli_stmt_execute($stmt);
If I execute my PHP code:
$serName = $_GET['username'];
// Code for sanitation here
// [...]
$sql = "SELECT NAME FROM PLAYERS WHERE NAME LIKE '%$serName%'";
I get division error, how do I use a variable in a query with wildcards on both sides?
right query
SELECT NAME FROM PLAYERS WHERE NAME LIKE '%{$serName}%'
And you should use prepared statements
$sql = "SELECT NAME FROM PLAYERS WHERE NAME LIKE '%" .$serName. "%'";