I'm trying to write search function, that gets its parameter from the user and uses an SQL statement to get the result from a MySQL database.
The statement:
$title = $_GET['title'];
$result = mysql_query("SELECT name, phone, email from person where name= '$title'");
The problem with this statement is that it's only taking the exact name; if the user is looking for "David" and just types "Da" then no result will be found.
I need a statement that, when the user enters part of the name, displays all matches with "Da".
You can try a wildcard search, which is not optimal, but should work:
$title = mysql_real_escape_string($_GET['title']);
$result = mysql_query("SELECT name, phone, email from person where name like '$title%'");
use the LIKE condition
SELECT name, phone, email
FROM person
WHERE name LIKE '%$title%'
This searches for $title anywhere in name.
Use PDO to prevent SQL Injection attacks. Read it, learn it, code it, live it.
You'll want to use the wildcard character - %
<?php
$dbh = new PDO('mysql:host=xxx;port=xxx;dbname=xxx', $user, $pass );
$sql = "SELECT name, phone, email from person where name LIKE :username";
$sth = $dbh->prepare( $sql );
$sth->bindValue( ':username', '%' . $_GET['title'] . '%', PDO::PARAM_STR );
$sth->execute();
$result = $sth->fetchAll( PDO::FETCH_OBJ );
print_r( $result );
I recommend you read this, it will be useful to you:
http://www.w3schools.com/sql/sql_wildcards.asp
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']) . "'";
I'm using PHP to query oracle DB and everything works great unless i try to use oci_bind_by_name to replace a variable
$link = oci_connect("user","password","server/service");
$sql = "SELECT name FROM customers WHERE name LIKE '%:name%'";
$query= oci_parse($link, $sql);
$name = "Bruno";
oci_bind_by_name($query, ":name", $name);
$execute = oci_execute($query);
I also tried to escape the quotes like this, but it returns the same error, i assume it's a problem with the wildcards %
$sql = "SELECT name FROM customers WHERE name LIKE \"%:name%\" ";
The error is not specific:
( ! ) Warning: oci_bind_by_name(): in D:\gdrive\www\sites\pulseiras\php\engine.php on line 30
I'd like to use bind by name to avoid sql injection, how can i make it work ?
OCI is inserting the bound variable to your query and ending up with something like this:
SELECT name FROM customers WHERE name LIKE '%'Bruno'%'
Obviously a couple of unnecessary quotes have been added. This happens because a bound variable is treated as a single item.
You need to modify the variable before you bind, so:
$sql = "SELECT name FROM customers WHERE name LIKE :name"; // chars removed.
$query= oci_parse($link, $sql);
$name = "%Bruno%"; // chars added.
oci_bind_by_name($query, ":name", $name);
As usual, the PHP manual has many useful examples.
It's amazing how the brain only seems to start working after posting the question on stackoverflow. It turns out the solution is to isolate the wildcards and concatenating with the variable:
$sql = "SELECT name FROM customers WHERE name LIKE '%' || :name || '%' ";
$name = "Bruno";
oci_bind_by_name($query, ":name", $name);
$execute = oci_execute($query);
I am working on a project which allows me to create a customer database. I have made an Create.php and Delete.php but am having issues with the basic structure for an Edit page.
My initial idea is to create a populated drop down box (Which I can do) which on click will take the user to domain.com/Customer.php?Customer_name="JohnD"
I am having a few issues with regards to this as it is doing 2 things.
It is printing out ALL of the data in my table into the echo.
It isn't taking the values from the URL, However I know that I have missed something but am unsure of what I need to search for.
Here is my snippet so far:
<h2>
<?Php
$sql="SELECT id,customer_name FROM Customers";
$result =mysql_query($sql);
while ($data=mysql_fetch_assoc($result)){
?>
<?Php echo $data['customer_name']; } ?>
</h2>
As of yet I am getting this in the header:
John Doe Jimmy Timmy Test
These are all the values inside my rows for the table Customers.
Sorry if the question seems all over the place. I will correct if it is not easy to understand.
Thanks in advance
use this url
domain.com/Customer.php?CID=1
and the code should look like
<?php
$customer_id = (int) $_GET['CID'];
$query = "SELECT id, customer_name FROM Customers
WHERE id = {$customer_id}";
$result = mysql_query($query) or die('<p>' . $query . '</p><div>' .
mysql_error() . '</div>');
$customer = mysql_fetch_assoc($result);
?>
<h2><?php echo $customer['customer_name'] ?></h2>
You need to use $_GET to get the parameters from the URL.
<?php
//customer.php?Customer_name=JohnD (no quotes)
echo $_GET[Customer_name];
?>
You would then use mysqli_ or PDO to bind $_GET[Customer_name] and execute the query. If you don't bind parameters in your SQL query, you will be vulnerable to SQL injection.
You need to restrict the SQL select to the specific customer with a where clause. And you may be getting that customer id from the request. I would suggest that you use customer id rather than name in the drop down box. That way the URL will be:
domain.com/Customer.php?id=1
On the Customer.php page you can get the value using $id = $_GET['id'];
Now as for your SQL you should use some safer method for querying the database say:
$dsn = 'mysql:host=localhost;dbname=mydb';
$username = 'myun';
$password = 'mypw';
$options = array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',
);
$dbh = new PDO($dsn, $username, $password, $options);
$stmt = $dbh->prepare("select id, Customer_name from customers where id = :id");
$stmt->bindParam(':id', $id);
$stmt->execute();
while($c = $stmt->fetch()){
echo $c['customer_name'];
}
This way only data for the selected customer will be displayed.
Im trying to work with PDO for the first time and I'm just wanting to know how secure what I'm doing is, I'm also new to PHP.
I have a query that when a user is passed ot my page, the page takes a variable using GET and then runs.
With PHP I've always used mysql_real_escape to sanitize my variables.
Can anybody see security flaws with this?
// Get USER ID of person
$userID = $_GET['userID'];
// Get persons
$sql = "SELECT * FROM persons WHERE id =$userID";
$q = $conn->query($sql) or die($conn->error());
while($r = $q->fetch(PDO::FETCH_LAZY)){
echo '<div class="mis-per">';
echo '<span class="date-submitted">' . $r['date_submitted'] . '</span>';
// MORE STUF
echo '</div>';
}
Don't use query, use prepare:
http://php.net/manual/de/pdo.prepare.php
$userID = $_GET['userID'];
$sql = "SELECT * FROM persons WHERE id = :userid";
$q = $conn->prepare($sql)
$q->execute(array(':userid' => $userID ));
while($r = $q->fetch(PDO::FETCH_ASSOC)){
echo '<div class="mis-per">';
echo '<span class="date-submitted">' . $r['date_submitted'] . '</span>';
// MORE STUF
echo '</div>';
}
The SQL statement can contain zero or more named (:name) or question mark (?) parameter markers for which real values will be substituted when the statement is executed.
With anything you use, it's about how you use it rather than what you use. I'd argue that PDO itself is very safe as long as you use it properly.
$sql = "SELECT * FROM persons WHERE id =$userID";
That's bad *. Better :
$sql = "SELECT * FROM persons WHERE id = " . $conn->quote($userID);
Better :
$q = $conn->prepare('SELECT * FROM persons WHERE id = ?')->execute(array($userID));
* This is bad, and that's because if $userID is "1 OR 1", the query becomes SELECT * FROM persons WHERE id =1 OR 1 which will always return all values in the persons table.
As the comments say: Atm there is no security whatsoever against SQLI. PDO offers you (if the database driver supports it (mysql does)) Prepared Statements. Think of it like a query-template that is compiled/passed to the dbms and later filled with values.
here is an example of usage:
$sql = 'SELECT name, colour, calories
FROM fruit
WHERE calories < :calories AND colour = :colour';
//Prepare the Query
$sth = $dbh->prepare($sql);
//Execute the query with values (so no tainted things can happen)
$sth->execute(array(':calories' => 150, ':colour' => 'red'));
$red = $sth->fetchAll();
Adjust as follows (you can use either :userId or simply ? as Tom van der Woerdt suggests, even if I think the first one gives more clearness, especially when there are more than just one parameter):
$sql = "SELECT * FROM persons WHERE id =:userID";
$q = $conn->prepare( $sql );
$q->bindValue( ":userID", $userID, PDO::PARAM_INT ); // or PDO::PARAM_STR, it depends
$q->execute();
$r = $st->fetch();
...
...
I'm just migrating my code from mysql_query style commands to PDO style and I ran into a problem. THe old code looked like this :
$query_list_menu = "SELECT ".$_GET['section_name']." from myl_menu_hide_show WHERE id='".$_GET['id']."'";
And the updated code looks like below. Apparently it's not working. I store in $_GET['section_name'] a string that represents a field name from the database. But I think there is a problem when I pass it as a variable. Is the below code valid ? Thanks.
$query_list_menu = "SELECT :section_name from myl_menu_hide_show WHERE id=:id";
$result_list_menu = $db->prepare($query_list_menu);
$result_list_menu->bindValue(':section_name', $_GET['section_name'] , PDO::PARAM_STR);
$result_list_menu->bindValue(':id', $_GET['id'] , PDO::PARAM_INT);
$result_list_menu->execute();
If $_GET['section_name'] contains a column name, your query should be:
$query_list_menu = "SELECT " . $_GET['section_name'] . " from myl_menu_hide_show WHERE id=:id";
Giving:
$query_list_menu = "SELECT :section_name from myl_menu_hide_show WHERE id=:id";
$result_list_menu = $db->prepare($query_list_menu);
$result_list_menu->bindValue(':id', $_GET['id'] , PDO::PARAM_INT);
$result_list_menu->execute();
The reason is that you want the actual name of the column to be in the query - you'd changed it to be a parameter, which doesn't really make much sense.
I'll also add that using $_GET['section_name'] directly like this is a massive security risk as it allows for SQL injection. I suggest that you validate the value of $_GET['section_name'] by checking it against a list of columns before building and executing the query.
There is no good and safe way to select just one field from the record based on the user's choice. The most sensible solution would be to select the whole row and then return the only field requested
$sql = "SELECT * from myl_menu_hide_show WHERE id=?";
$stmt = $db->prepare($query_list_menu);
$stmt->execute([$_GET['id']]);
$row = $stmt->fetch();
return $row[$_GET['section_name']] ?? false;