This question already has answers here:
How do I create a PDO parameterized query with a LIKE statement?
(9 answers)
Closed 4 months ago.
I've read multiple examples on how these queries should be written but I'm struggling to get this specific like to run when using bindParam
Would this be the correct way to match usernames that begin with a?
$term = "a";
$term = "'$term%'";
$sql = "SELECT username
FROM `user`
WHERE username LIKE :term
LIMIT 10";
$core = Connect::getInstance();
$stmt = $core->dbh->prepare($sql);
$stmt->bindParam(':term', $term, PDO::PARAM_STR);
$stmt->execute();
$data = $stmt->fetchAll();
No, you don't need the inner single quotes so just $term = "$term%";
The statement you're running now would try to match 'a%' instead of a%
bindParam will make sure that all string data is automatically properly quoted when given to the SQL statement.
You can use bindValue , suppose you are having a $query = "search string"
$stmt->bindValue(':term', $query.'%'); // this will do like search for "search term XXXXX"
similarly
$stmt->bindValue(':term', '%'.$query.'%');
or
$stmt->bindValue(':term', '%'.$query);
Related
I use PDO in PHP on a MariaDB to filter rows where text field contains $search_terms. However, I only retrieve the rows which contain a question mark. It seems that the content of $search_terms is not replaced in the prepared statement.
$query = $db->prepare('SELECT * FROM notes WHERE text LIKE \'%?%\'');
$query->execute(array($search_terms));
$data['notes'] = $query->fetchAll(PDO::FETCH_ASSOC);
Why ?
Not sure if $search_terms is intended to hold one or more than one search term. Your query implies the former, and if so, then use:
$search_term = "%apple%";
$query = $db->prepare('SELECT * FROM notes WHERE text LIKE ?');
$query->execute($search_term);
$data['notes'] = $query->fetchAll(PDO::FETCH_ASSOC);
Note that we bind the search term with the % wildcards to the statement. The statement just holds a single ? placeholder.
This question already has answers here:
pdo prepared statements with wildcards
(2 answers)
Closed 5 years ago.
I'm trying to query posts using PDO where the database column 'tags' = something.
My problem is: I want my query to work even if there's no $_GET['tag'] request is set and here's my code.
if (!isset($_GET['tag'])) {
$tags = '%';
} else {
$tags = $_GET['tag'];
}
$get_recipes = $con->prepare ("SELECT * FROM recipes WHERE tags = ?");
$get_recipes->execute(array($tags));
$recipes = $get_recipes->fetchAll();
Is it valid to set the PHP variable $tags to the MySQL wildcard %? if not possible then what should I do to make my query work?
When I run that code and there's not $_GET['tag'] is written the query will not fetch any posts from the database.
Using Wildcards in Prepared Statements With PDO
When using a wildcard in MySQL you must use the LIKE operator. It is correct to bind the wildcard with parameters in PDO.
You would prepare your statement like so.
$get_recipes = $con->prepare ("SELECT * FROM recipes WHERE tags LIKE ?");
And then you would bind your parameter using the % character, like so.
$get_recipes->execute(array('%'));
While that is the correct way to use a wildcard in the way you've proposed, that is not the correct solution to do what you're trying to do.
How to achieve what you're trying to achieve
In your code it looks like you want to select all rows if $_POST['tags'] is not set, and if it is set you want to select all rows that have the tags column set to the value of $_POST['tags']. To do this, you would want to prepare your statement inside the conditional, like so.
if (!isset($_GET['tag'])) {
$get_recipes = $con->prepare ("SELECT * FROM recipes");
$get_recipes->execute();
} else {
$get_recipes = $con->prepare ("SELECT * FROM recipes WHERE tags = ?");
$get_recipes->execute(array($_GET['tag']));
}
$recipes = $get_recipes->fetchAll();
This question already has answers here:
PHP - Using PDO with IN clause array
(9 answers)
Closed 9 months ago.
My code:
$myArray = implode($myArray, ',');
$sth = $dbh->prepare('SELECT foo FROM bar WHERE ids IN (:ids)');
$sth->bindParam(':ids', $myArray);
$sth->execute();
$result = $sth->fetch();
echo $sth->rowCount();
Always shows a count of 1, but when I skip the parametrization and just add the variable itself in it's place, I get an accurate count. What's going on here?
You can't bind a parameter for the IN clause like that. The $myArray string will only count as one value, like if you did this:
SELECT foo FROM bar WHERE ids IN ('1,2,3')
Even though there are three comma delimited values, the database reads them as only one string value.
You need to manually insert the IN list into the query, the old-school way.
'SELECT foo FROM bar WHERE ids IN (' . $myArray .')'
There is unfortunately no other way. At least for now.
I know this question is old, but this works for me:
$arrayOfValues = array(1,2,3,4,5);
$questionMarks = join(",", array_pad(array(), count($arrayOfValues), "?"));
$stmt = $dbh->prepare("update some_table set end_date = today where value_no in ($questionMarks)");
$stmt->execute($arrayOfValues);
You simply need a string with as many question marks as you have parameters for your in clause... easily possible
<?php
$sql = "select * from something where id in (".implode(",", array_fill(0, count($parameters), "?")).")";
$sth = $db->prepare($sql);
$sth->execute( $parameters);
?>
This question already has answers here:
Can PHP PDO Statements accept the table or column name as parameter?
(8 answers)
Closed 9 years ago.
I want to fetch results from a MySQL database with PDO. The user should be able to order them by tablerow by which type (ascending or descending). This seems to only work when you hardcode it.
Does work:
$query = "SELECT * FROM ".$config->dbPrefix."content
WHERE cat_id = 2
ORDER BY id DESC
";
$query = $pdo->prepare($query);
$query->execute();
$result = $query->fetchAll();
Doesn't work:
$orderRow = 'id'; //from $_POST
$orderType = 'DESC' //from $_POST
$query = "SELECT * FROM ".$config->dbPrefix."content
WHERE cat_id = 2
ORDER BY :orderRow :orderType
";
$query = $pdo->prepare($query);
$query->bindValue(':orderRow', $orderRow);
$query->bindValue(':orderType', $orderType);
$query->execute();
$result = $query->fetchAll();
So my question is: what is the best way to do this and why isn't this implemented?
The best way I can think of is using a switch statement and writing the query for every different option which would have like 14 different available cases.
You can only provide placeholders for values in an SQL statement, not for column names or other kind of identifiers.
So instead of using bindValue, put the values in like you do for #config->dbPrefix, directly into the string. Make sure however that no SQL injection is possible.
This question already has an answer here:
Can I use a PDO prepared statement to bind an identifier (a table or field name) or a syntax keyword?
(1 answer)
Closed 3 years ago.
Is it possible pass a column name as parameter in a prepared MySQL statement? Take the following example:
UPDATE Images
SET :placement = :imageURL
WHERE ID = :titleID;
PDO adds ' around each parameter, so the middle line above becomes:
SET 'Homepage' = '1.jpg'
Which MySQL doesn't like. Is there a way to include parameters for fieldnames in PDO statements and have them accepted?
Otherwise I guess I'll have to write several different PDO statements, depending on what's been chosen(?).
You would need to do something like this:
$column = 'someColumn';
$stmt = $db->prepare("UPDATE tableName SET {$column} = :columnValue WHERE ID = :recordId");
Parameterized placeholders are only for values.
I would suggest you read the comment #YourCommonSense posted on your question.
In situations such as this, I use a different sort of replacement parameters, like so:
$unitLabel = 'store_number';
$sql = 'select * from users where [unitLabel] = :unit and level = :level;';
$sql = str_replace('[unitLabel]', $unitLabel, $sql);
$params = array(
':unit' => 300,
':level' => 'admin',
);
$stmt = $dbh->prepare($sql);
$stmt->execute($params);
The prepared SQL query ends up being processed (more or less) as:
SELECT * FROM USERS WHERE store_number = 300 AND level = 'admin';
Which works for my situation. I hope this helps. :)