How to bind in PDO a string with % - php

I have the following query, (which don't work).
How do I bid strings inside an existing string with % (I believe the % is not the problem, but really not sure).
$sql="SELECT * FROM T WHERE f LIKE '%:bindParamString%'";

You can include % symbols into your value:
$param = '%'.$param.'%';
$query = "SELECT * FROM T WHERE f LIKE ?";
Or use SQL to concatenate string in database:
## if you have mysql
$query = "SELECT * FROM T WHERE f LIKE CONCAT('%', ?, '%')";
It also a good idea to use LIKE instead of = then you're searching by patterns.

Try something like this:
$db = new PDO(...);
$sql = "SELECT * FROM T WHERE f=?";
$stmt = $db->prepare($sql);
$val = "%{$val}%";
$stmt->bindParam(1, $val, PDO::PARAM_STR);
For more info, I suggest to read the related doc page!

Related

How to select 'like' query in php model? [duplicate]

Anyone know how to combine PHP prepared statements with LIKE? i.e.
"SELECT * FROM table WHERE name LIKE %?%";
The % signs need to go in the variable that you assign to the parameter, instead of in the query.
I don't know if you're using mysqli or PDO, but with PDO it would be something like:
$st = $db->prepare("SELECT * FROM table WHERE name LIKE ?");
$st->execute(array('%'.$test_string.'%'));
For mysqli user the following.
$test_string = '%' . $test_string . '%';
$st->bind_param('s', $test_string);
$st->execute();
You can use the concatenation operator of your respective sql database:
# oracle
SELECT * FROM table WHERE name LIKE '%' || :param || '%'
# mysql
SELECT * from table WHERE name LIKE CONCAT('%', :param, '%')
I'm not familar with other databases, but they probably have an equivalent function/operator.
You could try something like this:
"SELECT * FROM table WHERE name LIKE CONCAT(CONCAT('%',?),'%')"
in PHP using MYSQLI you need to define a new parameter which will be declared as:
$stmt = mysqli_prepare($con,"SELECT * FROM table WHERE name LIKE ?");
$newParameter='%'.$query.'%';
mysqli_stmt_bind_param($stmt, "s", $newParameter);
mysqli_stmt_execute($stmt);
this works for me..
For me working great, I've looked for answer hours, thx.
$dbPassword = "pass";
$dbUserName = "dbusr";
$dbServer = "localhost";
$dbName = "mydb";
$connection = new mysqli($dbServer, $dbUserName, $dbPassword, $dbName);
if($connection->connect_errno)
{
exit("Database Connection Failed. Reason: ".$connection->connect_error);
}
$tempFirstName = "reuel";
$sql = "SELECT first_name, last_name, pen_name FROM authors WHERE first_name LIKE CONCAT(CONCAT('%',?),'%')";
//echo $sql;
$stateObj = $connection->prepare($sql);
$stateObj->bind_param("s",$tempFirstName);
$stateObj->execute();
$stateObj->bind_result($first,$last,$pen);
$stateObj->store_result();
if($stateObj->num_rows > 0) {
while($stateObj->fetch()){
echo "$first, $last \"$pen\"";
echo '<br>';
}
}
$stateObj->close();
$connection->close();
I will just adapt Chad Birch's answer for people like me who are used to utilize bindValue(...) for PDO:
$st = $db->prepare("SELECT * FROM table WHERE name LIKE :name");
$st->bindValue(':name','%'.$name.'%',PDO::PARAM_STR);
$st->execute();
In SQL, you can do it like this using prepared statements.
SELECT * FROM TABLE_NAME WHERE (TABLE_COLUMN LIKE CONCAT('%', :SEARCH_TEXT, '%')) OR (ANOTHER_TABLE_COLUMN LIKE CONCAT('%', :SEARCH_TEXT, '%'))
The sprintf can do it. Remember to put another % in front of the original % to escape it.
$ret = sprintf("SELECT * FROM table WHERE name LIKE %%%s%%", $name);

Searching for strings in MySQL WHERE string LIKE string (wrapped in parentheses)

I am trying to return a search term with PDO, some of the strings are wrapped in () and when searching they don't show up.
Take for example Strawberry (Ripe) it shows when I use the (r
But when I don't:
Is there any way to match the string within the parentheses for a fuller more efficient search.
My Current Code:
public function getAllFlavoursSearch($search) {
$query = "SELECT flavour_name, flavour_company_name FROM flavours WHERE flavour_name LIKE :search OR flavour_name LIKE :search2 OR flavour_name LIKE :search3 OR flavour_company_name LIKE :search4 LIMIT 0,100";
$stmt = $this->queryIt($query);
$stmt = $this->bind(':search', $search. '%', PDO::PARAM_STR);
$stmt = $this->bind(':search2', '%' .$search, PDO::PARAM_STR);
$stmt = $this->bind(':search3', '%('.$search.')%', PDO::PARAM_STR);
$stmt = $this->bind(':search4', '%('.$search.')%', PDO::PARAM_STR);
return $this->resultset();
there is a shortcut. MATCH() function. change your query to this.
$query = "SELECT flavour_name, flavour_company_name FROM flavours WHERE MATCH(`flavour_name`, `flavour_name`, `flavour_company_name`) AGAINST (:search) LIMIT 0,100";

Possible to have PHP MYSQL query ignore empty variable in WHERE clause?

Not sure how I can do this. Basically I have variables that are populated with a combobox and then passed on to form the filters for a MQSQL query via the where clause. What I need to do is allow the combo box to be left empty by the user and then have that variable ignored in the where clause. Is this possible?
i.e., from this code. Assume that the combobox that populates $value1 is left empty, is there any way to have this ignored and only the 2nd filter applied.
$query = "SELECT * FROM moth_sightings WHERE user_id = '$username' AND location = '$value1' AND english_name = $value2 ";
$result = mysql_query($query) or die(mysql_error());
$r = mysql_numrows($result);
Thanks for any help.
C
Use
$where = "WHERE user_id = '$username'";
if(!empty($value1)){
$where .= "and location = '$value1'";
}
if(!empty($value2 )){
$where .= "and english_name= '$value2 '";
}
$query = "SELECT * FROM moth_sightings $where";
$result = mysql_query($query) or die(mysql_error());
$r = mysql_numrows($result);
Several other answers mention the risk of SQL injection, and a couple explicitly mention using prepared statements, but none of them explicitly show how you might do that, which might be a big ask for a beginner.
My current preferred method of solving this problem uses a MySQL "IF" statement to check whether the parameter in question is null/empty/0 (depending on type). If it is empty, then it compares the field value against itself ( WHERE field1=field1 always returns true). If the parameter is not empty/null/zero, the field value is compared against the parameter.
So here's an example using MySQLi prepared statements (assuming $mysqli is an already-instantiated mysqli object):
$sql = "SELECT *
FROM moth_sightings
WHERE user_id = ?
AND location = IF(? = '', location, ?)
AND english_name = ?";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param('ssss', $username, $value1, $value1, $value2);
$stmt->execute();
(I'm assuming that $value2 is a string based on the field name, despite the lack of quotes in OP's example SQL.)
There is no way in MySQLi to bind the same parameter to multiple placeholders within the statement, so we have to explicitly bind $value1 twice. The advantage that MySQLi has in this case is the explicit typing of the parameter - if we pass in $value1 as a string, we know that we need to compare it against the empty string ''. If $value1 were an integer value, we could explicitly declare that like so:
$stmt->bind_param('siis', $username, $value1, $value1, $value2);
and compare it against 0 instead.
Here is a PDO example using named parameters, because I think they result in much more readable code with less counting:
$sql = "SELECT *
FROM moth_sightings
WHERE user_id = :user_id
AND location = IF(:location_id = '', location, :location_id)
AND english_name = :name";
$stmt = $pdo->prepare($sql);
$params = [
':user_id' => $username,
':location_id' => $value1,
':name' => $value2
];
$stmt->execute($params);
Note that with PDO named parameters, we can refer to :location_id multiple times in the query while only having to bind it once.
if ( isset($value1) )
$query = "SELECT * FROM moth_sightings WHERE user_id = '$username' AND location = '$value1' AND english_name = $value2 ";
else
$query = "SELECT * FROM moth_sightings WHERE user_id = '$username' AND english_name = $value2 ";
But, you can also make a function to return the query based on the inputs you have.
And also don't forget to escape your $values before generating the query.
1.) don't use the simply mysql php extension, use either the advanced mysqli extension or the much safer PDO / MDB2 wrappers.
2.) don't specify the full statement like that (apart from that you dont even encode and escape the values given...). Instead use something like this:
sprintf("SELECT * FROM moth_sightings WHERE 1=1 AND %s", ...);
Then fill that raw query using an array holding all values you actually get from your form:
$clause=array(
'user_id="'.$username.'"',
'location="'.$value1.'"',
'english_name="'.$value2.'"'
);
You can manipulate this array in any way, for example testing for empty values or whatever. Now just implode the array to complete the raw question from above:
sprintf("SELECT * FROM moth_sightings WHERE 1=1 AND %s",
implode(' AND ', $clause) );
Big advantage: even if the clause array is completely empty the query syntax is valid.
First, please read about SQL Injections.
Second, $r = mysql_numrows($result) should be $r = mysql_num_rows($result);
You can use IF in MySQL, something like this:
SELECT * FROM moth_sightings WHERE user_id = '$username' AND IF('$value1'!='',location = '$value1',1) AND IF('$value2'!='',english_name = '$value2',1); -- BUT PLEASE READ ABOUT SQL Injections. Your code is not safe.
Sure,
$sql = "";
if(!empty($value1))
$sql = "AND location = '{$value1}' ";
if(!empty($value2))
$sql .= "AND english_name = '{$value2}'";
$query = "SELECT * FROM moth_sightings WHERE user_id = '$username' {$sql} ";
$result = mysql_query($query) or die(mysql_error());
$r = mysql_numrows($result);
Be aware of sql injection and deprecation of mysql_*, use mysqli or PDO instead
I thought of two other ways to solve this:
SELECT * FROM moth_sightings
WHERE
user_id = '$username'
AND location = '%$value1%'
AND english_name = $value2 ";
This will return results only for this user_id, where the location field contains $value1. If $value1 is empty, this will still return all rows for this user_id, blank or not.
OR
SELECT * FROM moth_sightings
WHERE
user_id = '$username'
AND (location = '$value1' OR location IS NULL OR location = '')
AND english_name = $value2 ";
This will give you all rows for this user_id that have $value1 for location or have blank values.

implement LIKE query in PDO

I am running problems in implementing LIKE in PDO
I have this query:
$query = "SELECT * FROM tbl WHERE address LIKE '%?%' OR address LIKE '%?%'";
$params = array($var1, $var2);
$stmt = $handle->prepare($query);
$stmt->execute($params);
I checked the $var1 and $var2 they contain both the words I want to search, my PDO is working fine since some of my queries SELECT INSERT they work, it's just that I am not familiar in LIKE here in PDO.
The result is none returned. Do my $query is syntactically correct?
You have to include the % signs in the $params, not in the query:
$query = "SELECT * FROM tbl WHERE address LIKE ? OR address LIKE ?";
$params = array("%$var1%", "%$var2%");
$stmt = $handle->prepare($query);
$stmt->execute($params);
If you'd look at the generated query in your previous code, you'd see something like SELECT * FROM tbl WHERE address LIKE '%"foo"%' OR address LIKE '%"bar"%', because the prepared statement is quoting your values inside of an already quoted string.
Simply use the following:
$query = "SELECT * FROM tbl WHERE address LIKE CONCAT('%', :var1, '%')
OR address LIKE CONCAT('%', :var2, '%')";
$ar_val = array(':var1'=>$var1, ':var2'=>$var2);
if($sqlprep->execute($ar_val)) { ... }
No, you don't need to quote prepare placeholders. Also, include the % marks inside of your variables.
LIKE ?
And in the variable: %string%
$query = "SELECT * FROM tbl WHERE address LIKE ? OR address LIKE ?";
$params = array("%$var1%", "%$var2%");
$stmt = $handle->prepare($query);
$stmt->execute($params);
You can see below example
$title = 'PHP%';
$author = 'Bobi%';
// query
$sql = "SELECT * FROM books WHERE title like ? AND author like ? ";
$q = $conn->prepare($sql);
$q->execute(array($title,$author));
Hope it will work.

Combine PHP prepared statments with LIKE

Anyone know how to combine PHP prepared statements with LIKE? i.e.
"SELECT * FROM table WHERE name LIKE %?%";
The % signs need to go in the variable that you assign to the parameter, instead of in the query.
I don't know if you're using mysqli or PDO, but with PDO it would be something like:
$st = $db->prepare("SELECT * FROM table WHERE name LIKE ?");
$st->execute(array('%'.$test_string.'%'));
For mysqli user the following.
$test_string = '%' . $test_string . '%';
$st->bind_param('s', $test_string);
$st->execute();
You can use the concatenation operator of your respective sql database:
# oracle
SELECT * FROM table WHERE name LIKE '%' || :param || '%'
# mysql
SELECT * from table WHERE name LIKE CONCAT('%', :param, '%')
I'm not familar with other databases, but they probably have an equivalent function/operator.
You could try something like this:
"SELECT * FROM table WHERE name LIKE CONCAT(CONCAT('%',?),'%')"
in PHP using MYSQLI you need to define a new parameter which will be declared as:
$stmt = mysqli_prepare($con,"SELECT * FROM table WHERE name LIKE ?");
$newParameter='%'.$query.'%';
mysqli_stmt_bind_param($stmt, "s", $newParameter);
mysqli_stmt_execute($stmt);
this works for me..
For me working great, I've looked for answer hours, thx.
$dbPassword = "pass";
$dbUserName = "dbusr";
$dbServer = "localhost";
$dbName = "mydb";
$connection = new mysqli($dbServer, $dbUserName, $dbPassword, $dbName);
if($connection->connect_errno)
{
exit("Database Connection Failed. Reason: ".$connection->connect_error);
}
$tempFirstName = "reuel";
$sql = "SELECT first_name, last_name, pen_name FROM authors WHERE first_name LIKE CONCAT(CONCAT('%',?),'%')";
//echo $sql;
$stateObj = $connection->prepare($sql);
$stateObj->bind_param("s",$tempFirstName);
$stateObj->execute();
$stateObj->bind_result($first,$last,$pen);
$stateObj->store_result();
if($stateObj->num_rows > 0) {
while($stateObj->fetch()){
echo "$first, $last \"$pen\"";
echo '<br>';
}
}
$stateObj->close();
$connection->close();
I will just adapt Chad Birch's answer for people like me who are used to utilize bindValue(...) for PDO:
$st = $db->prepare("SELECT * FROM table WHERE name LIKE :name");
$st->bindValue(':name','%'.$name.'%',PDO::PARAM_STR);
$st->execute();
In SQL, you can do it like this using prepared statements.
SELECT * FROM TABLE_NAME WHERE (TABLE_COLUMN LIKE CONCAT('%', :SEARCH_TEXT, '%')) OR (ANOTHER_TABLE_COLUMN LIKE CONCAT('%', :SEARCH_TEXT, '%'))
The sprintf can do it. Remember to put another % in front of the original % to escape it.
$ret = sprintf("SELECT * FROM table WHERE name LIKE %%%s%%", $name);

Categories