I have a custom OOP query object with prepared statements that I use for MySQL queries. The problem is that I have a LIKE statement that will not allow me to insert data using a prepared statement.
How can I escape the data in this scenario? Here's my code:
$search_q = !empty($search) ? "AND `title` LIKE '%?%'" : "";
$items = DB::fetch("SELECT `title` FROM `products` WHERE `active` = 1 $search_q;", array($start));
You need to put the wildcard match characters in the placeholder, not in the query, so instead of doing:
$search = 'find this string';
$db::query("SELECT ... FROM table WHERE col LIKE '%?%' ");
You do:
$search = '%find this string%';
$db::query("SELECT ... FROM table WHERE col LIKE ? ");
First result in Google serp
$query = $database->prepare('SELECT * FROM table WHERE column LIKE ?');
$query->execute(array('value%'));
while ($results = $query->fetch())
{
echo $results['column'];
}
Related
I'm trying to select all the rows from my database, where 'street' is LIKE the contents from an array ($streets).
Here's what I have...
#TEXT AREA INPUT = $streets
$sql = "SELECT * FROM `data` WHERE `street` LIKE '%".implode("%' OR `street` LIKE '%",$streets)."%'";
echo $sql;
$result = mysqli_query($con,$sql) or die(mysql_error());
$totalitems1 = mysqli_num_rows($result);
echo $totalitems1 . "<br>";
while($row = mysqli_fetch_array($result))
{
echo $row['street']. "<br>";
}
the varible $streets is exploded from a text area input, each value on a new line.
When I process this using PHP, only the rows that are LIKE the last 'OR' are returned .. (The last line in the text area). But when I copy and paste the generated SQL into PHPMYADMIN, it returns ALL the data, as expected.
What am I missing here? Thanks.
My guess would be that you aren't stripping the newline from the end of each $street entry, therefore only the last entry looks valid as it probably doesn't have a trailing newline. No doubt your query probably looks like...
SELECT * FROM `data` WHERE `street` LIKE '%foo
%' OR `street` LIKE '%bar
%' OR `street` LIKE '%baz%'
The quick fix would be to use...
implode("%' OR `street` LIKE '%", array_map(function($s) use ($con) {
return $con->escape_string(trim($s));
}, $streets))
Ideally, you should be using a prepared statement with parameter binding.
My application allows searching of articles. So when a user enters the string "articlex" the query works & results are show but when multiple words are entered "articlex articley" the query shows no results.
Cuurently I'm using this query
$querySub = 'SELECT * FROM table WHERE (col1 LIKE "%'.$search_string.'%") OR (col2 LIKE "%'.$search_string.'%") OR (col3 LIKE "%'.$search_string.'%")';
Where $search_string only contains the input by user
How can I make the query applicable for multiple words as well?
Example for PDO
/* Assume $pdo is already prepared as PDO instance. */
// search query split by spaces
$user_input = 'foo bar baz';
// create string for PDO::prepare()
$sql = 'SELECT * FROM testTable WHERE ';
$wheres = $values = array();
foreach (array_filter(explode(' ', $user_input), 'strlen') as $keyword) {
$wheres[] = 'col1 LIKE ?';
$values[] = '%' . addcslashes($keyword, '%_\\') . '%'; // this is escape for LIKE search
}
$sql .= $wheres ? implode(' OR ', $wheres) : '1';
// bind values and execute
$stmt = $pdo->prepare($sql);
$stmt->execute($values);
Example for mysql_** functions (deprecated)
/* Assume $link is already prepared as MySQL resource. */
// search query split by spaces
$user_input = 'foo bar baz';
// create string for mysql_auery()
$sql = 'SELECT * FROM testTable WHERE ';
foreach (array_filter(explode(' ', $user_input), 'strlen') as $keyword) {
$wheres[] = 'col1 LIKE ' . mysql_real_escape_string(
'%' . addcslashes($keyword, '%_\\') . '%',
$link
);
}
$sql .= !empty($wheres) ? implode(' OR ', $wheres) : '1';
// execute
$result = mysql_query($sql, $link);
While using variables for like query, you could use
Select * from table where keyword LIKE '%{$to_be_searched}%'
You can use REGEXP for this perpose .....or if you want multiple word search then you need to explode search string by space and then search this string from table using LIKE
if you search "articlex articley" then it will search whole word in LIKE operator
use only one "%" at the end. like
$querySub = SELECT * FROM table WHERE (col1 LIKE '$search_string%'");
This will search for both "articlex" and "articley"
1: This will be return should record
select * from products where title like "%word1%" or
title LIKE "word2";
note: if you have so many word then use dynamic query generator which generate title like "%word3%" or title like"%word4%" or ........
2: This will be return must records
select * from products where title like "%word1%word2%word3%";
Please help. I need to print result of this query but nothing appears
$fetch_a = "
SELECT
programs.Program_Description
FROM
programs
WHERE
programs.Programid =
('
SELECT
memberprogram.Programid
FROM
memberprogram
WHERE
memberprogram.Memberid = $Memberid &&
memberprogram.Option_No = 'Option A'
')
";
$result_a = mysqli_query($dbc, $fetch_a);
echo $result_a;
You should use fetch_row or fetch_array first
mysqli_fetch_row
example:
while($row=mysqli_fetch_row($result_a))
echo $row[0]."<br/>";
EDIT:
as far as the query is concerned:
use "WHERE programs.Programid IN" instead of "WHERE programs.Programid ="
remove the apostrophes
replace && with AND
Ok, first thing is your query is a mess. Without knowing the details of your schema design, I'd take a guess with this
// note I'm using HEREDOC format
$sql = <<<_SQL
SELECT p.Program_Description
FROM programs p
WHERE EXISTS (
SELECT 1 FROM memberprogram m
WHERE m.Option_No = 'Option A'
AND m.Memberid = ?
AND m.Programid = p.Programid
)
_SQL;
Then, you should really be using parameter binding with a prepared statement. For example
$stmt = $dbc->prepare($sql);
$stmt->bind_param('i', $Memberid); // assuming $Memberid is an integer
$stmt->execute();
$stmt->bind_result($programDescription);
$stmt->fetch();
$stmt->close();
echo $programDescription;
I get error : "Unknown column 'Array' in 'where clause'" perharps from variable $query in my code.
This is my code :
$zzz = mysql_query("SELECT alias FROM table WHERE ColumnA = 'yes'");
while($aaa = mysql_fetch_array($zzz)){
$array[] = $aaa['alias'];
}
$query = mysql_query("SELECT * FROM table2 WHERE alias NOT IN ($array) ORDER BY Column1 DESC, Column2 DESC");
I want to make a SELECT query WHERE 'alias' in table2 not equal to any data in $array which come from fetch array $aaa.
I got a clue to make an array from fetch array from :
Array in SQL Query?
But, i don't know how to add 'quote' for each data in array that made from $aaa.
Could anyone tell me how to do this? :)
Why not use nested queries? Example:
$query = mysql_query("SELECT * FROM table2 WHERE alias NOT IN (SELECT alias FROM table WHERE ColumnA = 'yes') ORDER BY Column1 DESC, Column2 DESC");
As noted in my below comment, however, your interaction appears to be vulnerable to injection attacks. This can be avoided to some degree, as others have stated, but as I have also stated, one of the better ways is to use PDO. Example:
try {
$dbh = new PDO("mysql:host=localhost;dbname=dbname", "user", "password");
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $dbh->prepare("SELECT * FROM table2 WHERE alias NOT IN (SELECT alias FROM table WHERE ColumnA = :bool) ORDER BY Column1 DESC, Column2 DESC");
$stmt->bindValue(":bool","yes");
$stmt->execute();
} catch (\PDOException $e) {
// Something went wrong
}
while ($row = $stmt->fetch()) {
// do stuff with query
}
PDO ships with php 5.1.
You're trying to use $array directly, and it does not print itself the way you need to. Following the advice in the linked question, you could use implode:
$newarray = implode(", ", $array);
$query = mysql_query("SELECT * FROM table2 WHERE alias NOT IN ($newarray) ORDER BY Column1 DESC, Column2 DESC");
As for adding quotes, you can just concatenate them together. However, I'd also escape the values before quoting, to avoid SQL injection vulnerabilities:
while($aaa = mysql_fetch_array($ambilLarikAkunTerlindungi)){
$array[] = "'" . mysqli_real_escape_string($aaa['alias']) . "'";
}
I want to make an category-system CMS. Everything is fine, except a big trouble.
How can I can handle and generate the mysql query depends by some inputs like:
site.com/some-category&sortby=views&from=smt&anotherInput=key
For example, for this input my query should be something like
SELECT * FROM `articles` WHERE from='smt' AND afield='key' ORDER BY VIEWS
But these inputs will be different. How I can write this code? I don't know much things about designs patterns, but, I've heard about Factory pattern, is this a part of my solution?
Than
Factory pattern can help you with e.g. connecting/quering various databases without need to rewrite the entire code. This has nothing to do about query itself.
You can look at PDO extension, I usually use it together with prepared statements.
It will let you write queries like this:
$prepare = $db->prepare('
SELECT
*
FROM
articles
WHERE
from=:from AND afield=:afield
ORDER BY
views
');
$prepare->bindValue(':from', $_GET['from'], PDO::PARAM_STR);
$prepare->bindValue(':afield', $_GET['afield'], PDO::PARAM_STR);
$prepare->execute();
return $prepare;
The good thing about it is that you don't need to protect this from sql injections as PDO makes it for you. Also, the query is cached and you can run it several times with different params.
Very bad practice to use raw GET params in query directly, i.e. you shouldn't make constructions like
SELECT * FROM articles WHERE from=$_GET['from'] AND afield='key' ORDER BY VIEWS
but instead something like
if ($_GET['from'] == 'smt') $from = 'smt'
SELECT * FROM articles WHERE from='$from' AND afield='key' ORDER BY VIEWS
and so on
P.S. keyword is 'sql injection'
You can build the query string as pieces depending on what you need:
$query = "SELECT * FROM `articles` WHERE 1 = 1";
$where = ''
if (isset($_GET['from'])) {
$where .= " AND `from` = '" . mysql_real_escape_string($_GET['from']) . "'"
}
if (isset($_GET['anotherInput'])) {
$where .= " AND `from` = '" . mysql_real_escape_string($_GET['anotherInput']) . "'"
}
if (isset($_GET['sortby'] == 'views') {
$orderby = " ORDER BY `views` DESC"
} else {
$orderby = " ORDER BY `id` DESC"
}
$query = $query . $where . $orderby;
$result = mysql_query($query);
This is sort of the straight PHP/MySQL way, but I actually do suggest that you use prepared statements as in Pavel Dubinin's answer.
This has nothing to do with patterns. Use the $_GET superglobal variable to dynamically generate your query string.
$query = "SELECT * FROM articles WHERE from='".
$_GET['from'].
"' AND afield='".
$_GET['anotherInput'].
"' ORDER BY ".
$_GET['sortby'];
Disclaimer: This is prone to SQL injection. Use input escaping and prepared statements, ex PDO, in a production environment like:
$query = "SELECT * FROM articles WHERE from='?' AND afield='?' ORDER BY ?";
$clean_from = htmlentities($_POST['from'], ENT_QUOTES, 'UTF-8');
$clean_anotherInput = htmlentities($_POST['anotherInput'], ENT_QUOTES, 'UTF-8');
$clean_sortby = htmlentities($_POST['sortby'], ENT_QUOTES, 'UTF-8');
$clean_inputs = array($clean_from, $clean_anotherInput, $clean_sortby);
$sth = $dbh->prepare($query);
$sth->execute($clean_inputs);