Reputation: 21
I build SQL with a dynamic value from an array. How can I use placeholder or that dynamic condition?
I'm calling that function like this:
get_all_results("TABLE_NAME", ["column" => "VALUE"])
public static function get_all_results(string $table_name, array $where = []): array
{
global $wpdb;
/**
* Prepare condition
*
* @var string
*/
$condition = "";
$index = 0;
foreach ($where as $key => $value) {
if ($index > 0) {
$condition .= "AND ";
}
$condition .= "`$key` = '$value' ";
$index += 1;
}
if (!empty($condition)) {
$condition = " WHERE $condition ";
}
$results = $wpdb->get_results($wpdb->prepare("SELECT * FROM %i {$condition} ", $table_name));
return $results;
}
How can I use $wpdb->prepare with my function or what should I do in this case ?
This line is the main problem for me, "Plugin Check" - plugin giving me error for this.
$results = $wpdb->get_results($wpdb->prepare("SELECT * FROM %i {$condition} ", $table_name));
WordPress.DB.PreparedSQL.InterpolatedNotPrepared Line 238 of file includes/classes/DB.php.
Use placeholders and $wpdb->prepare(); found interpolated variable $condition at "SELECT * FROM %i WHERE $condition".
SELECT * FROM %i WHERE $condition
Upvotes: 1
Views: 659
Reputation: 47991
For a basic query builder function that receives an associative array of where conditions joined by AND
, here is a modern implementation with %i
for identifier placeholders.
public static function get_all_results(string $table_name, array $where = []): array
{
global $wpdb;
$sql = 'SELECT * FROM %i';
$clauses = [];
$params = [$table_name];
foreach ($where as $key => $value) {
$clauses[] = '%i = %s';
array_push($params, $key, $value);
}
if ($clauses) {
$sql .= ' WHERE ' . implode(' AND ', $clauses);
}
return $wpdb->get_results($wpdb->prepare($sql, $params));
}
This might be enough for the most basic scenarios but it won't be long before you realize the need for:
=
comparisonOR
between conditions$where
keys which are not column names$where
values which should not be wrapped in quotes (as a string)Here are some topically related (non-Wordpress) posts:
WHERE .. IN(..)
queryUpvotes: 0
Reputation: 5397
I will use placeholders for each value in the $where
array, in the below code that includes dynamically constructing the SQL query with placeholders for each condition, instead of directly inserting the condition string into the query. The actual values of these placeholders are then safely passed through $wpdb->prepare()
, which effectively prevents SQL injection vulnerabilities, hope this helps
public static function get_all_results(string $table_name, array $where = []): array
{
global $wpdb;
//Prepare a condition
$condition = "";
$values = [];
foreach ($where as $key => $value) {
if (!empty($condition)) {
$condition .= " AND ";
}
$condition .= $wpdb->prepare("`$key` = %s", $value);
}
if (!empty($condition)) {
$condition = " WHERE $condition ";
}
$query = "SELECT * FROM `$table_name` $condition";
$results = $wpdb->get_results($query);
return $results;
}
Upvotes: 1