Using named parameters with PDO for LIKE - php

I am trying to search the name field in my database using LIKE. If I craft the SQL 'by hand` like this:
$query = "SELECT * \n"
. "FROM `help_article` \n"
. "WHERE `name` LIKE '%how%'\n"
. "";
$sql = $db->prepare($query);
$sql->setFetchMode(PDO::FETCH_ASSOC);
$sql->execute();
Then it will return relevant results for 'how'.
However, when I turn it into a prepared statement:
$query = "SELECT * \n"
. "FROM `help_article` \n"
. "WHERE `name` LIKE '%:term%'\n"
. "";
$sql->execute(array(":term" => $_GET["search"]));
$sql->setFetchMode(PDO::FETCH_ASSOC);
$sql->execute();
I am always getting zero results.
What am I doing wrong? I am using prepared statements in other places in my code and they work fine.

The bound :placeholders are not to be enclosed in single quotes. That way they won't get interpreted, but treated as raw strings.
When you want to use one as LIKE pattern, then pass the % together with the value:
$query = "SELECT *
FROM `help_article`
WHERE `name` LIKE :term ";
$sql->execute(array(":term" => "%" . $_GET["search"] . "%"));
Oh, and actually you need to clean the input string here first (addcslashes). If the user supplies any extraneous % chars within the parameter, then they become part of the LIKE match pattern. Remember that the whole of the :term parameter is passed as string value, and all %s within that string become placeholders for the LIKE clause.

Related

How to insert a PHP variable into an SQL query

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']) . "'";

How to fetch the record when Query string with the single quotes string in Php

I am fetching data from the MySQL Database and database has a table name
wp_evr_event. I am fetching records using event_name from wp_evr_event.
wp_evr_event table has a fiels name event_name that use name of event.
now event name is Women\'s Reading Group into database.
when I used the Query
$sql = "SELECT * FROM `wp_evr_event` WHERE `event_name` LIKE '%".$_REQUEST['events_name']."%' ";
echo $sql;
Query become like
SELECT * FROM `wp_evr_event` WHERE `event_name` LIKE '%Women \'s Reading Group%'
But this is not fetching any record.
For the wordpress wpdb class you should use 2 functions. esc_like & prepare
A small example:
global $wpdb;
// First, escape the link for use in a LIKE statement.
$link = $wpdb->esc_like( $_REQUEST['events_name'] );
// Add wildcards
$link = '%' . $link . '%';
// Create a SQL statement with placeholders for the string input.
$sql = "SELECT * FROM `wp_evr_event` WHERE `event_name` LIKE '%s'";
// Prepare the SQL statement so the string input gets escaped for security.
$sql = $wpdb->prepare( $sql, $link);
If you prepare your query like this you should get the expected result.

oci_bind_by_name() returns error

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);

PDO Prepared Statement Search w/ MySQL [duplicate]

I am trying to search the name field in my database using LIKE. If I craft the SQL 'by hand` like this:
$query = "SELECT * \n"
. "FROM `help_article` \n"
. "WHERE `name` LIKE '%how%'\n"
. "";
$sql = $db->prepare($query);
$sql->setFetchMode(PDO::FETCH_ASSOC);
$sql->execute();
Then it will return relevant results for 'how'.
However, when I turn it into a prepared statement:
$query = "SELECT * \n"
. "FROM `help_article` \n"
. "WHERE `name` LIKE '%:term%'\n"
. "";
$sql->execute(array(":term" => $_GET["search"]));
$sql->setFetchMode(PDO::FETCH_ASSOC);
$sql->execute();
I am always getting zero results.
What am I doing wrong? I am using prepared statements in other places in my code and they work fine.
The bound :placeholders are not to be enclosed in single quotes. That way they won't get interpreted, but treated as raw strings.
When you want to use one as LIKE pattern, then pass the % together with the value:
$query = "SELECT *
FROM `help_article`
WHERE `name` LIKE :term ";
$sql->execute(array(":term" => "%" . $_GET["search"] . "%"));
Oh, and actually you need to clean the input string here first (addcslashes). If the user supplies any extraneous % chars within the parameter, then they become part of the LIKE match pattern. Remember that the whole of the :term parameter is passed as string value, and all %s within that string become placeholders for the LIKE clause.

Grouping multiple like statements

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);

Categories