Using an array like this:
$data = array
(
'host' => 1,
'country' => 'fr',
)
I would like to create a MySQL query that uses the values of the array to form its WHERE clause like:
SELECT *
FROM table
WHERE host = 1 and country = 'fr'
How can I generate this query string to use with MySQL?
Try this
$where = '';
foreach( $data as $k => $v ) {
if( !empty( $where ) )
$where .= ' AND ';
$where .= sprintf( "`%s` = '%s'", mysql_real_escape_string( $k ), mysql_real_escape_string( $v ) );
}
mysql_query( "SELECT * FROM `table` WHERE $where" );
Please please please don't build SQL statements with embedded data. Look here: http://bobby-tables.com/php.html
Related
I have a table on the frontend, where the user can choose what types of columns he wants.
After submitting the form I get the array with selected columns.
For instance the user select following columns:
$columns = ["campaign_start_time", "campiagn_end_time", "campaign_id", "campaign_budget", "adset_name", "ad_name"]
Now I have to make the request to the facebook api, but facebook api only request query in form:
$query = "campaign{start_time, end_time, id, budget}, adset{name}, ad{name}"
Here is my question, what is the best way to convert $columns to $query in PHP language?
If you can construct your submitted data to be in this form:
Array
(
[campaign] => Array
(
[0] => start_time
[1] => end_time
[2] => id
[3] => budget
)
[adset] => Array
(
[0] => name
)
[ad] => Array
(
[0] => name
)
)
Maybe using inputs or other constructs such as:
name="campaign[]" value="start_time"
name="campaign[]" value="end_time"
Then looping and building the query with the keys and values will do it:
foreach($columns as $key => $val) {
$query[] = $key . '{' . implode(',', $val) . '}';
}
$query = implode(',', $query);
Otherwise you'll need to parse it to get what you need first, then execute the loop above using $result instead:
foreach($columns as $val) {
preg_match('/^([^_]+)_(.*)/', $val, $match);
$result[$match[1]][] = $match[2];
}
This solution splits apart the values based on underscores and then joins them back together as nested values based on the category/key. Note that this doesn't check for items that don't have a "prefix".
<?php
$columns = ["campaign_start_time", "campaign_end_time", "campaign_id", "campaign_budget", "adset_name", "ad_name"];
$criteria = [];
foreach( $columns as $column ){
$pieces = explode('_',$column);
$category = array_shift($pieces);
if( !isset($criteria[$category]) ){
$criteria[$category] = [];
}
$criteria[$category][] = implode('_', $pieces);
}
$queryPieces = [];
foreach($criteria as $category => $values){
$queryPieces[] = $category.'{'.implode(', ', $values).'}';
}
$query = implode(', ', $queryPieces);
I am trying to delete Id on SQL not working i got string(87) "DELETE FROM wp_availability WHEREidIN (Array,Array,Array,Array)"
get this kind value
if ( count( $remove ) > 0 ) {
$removeSQL = "DELETE FROM " . $this->table . " WHERE `id` IN (" .
implode( ",", $remove ) . ")";
if ( $wpdb->query( $removeSQL ) ) {
$saved = true;
}
}
Thanks in Advance
To expand on Vince0789's answer...
$remove looks to contain an array of arrays and not just an id string.
For example, $remove may be layed out as below;
[
[
'id' => 1,
'content' => "Foo"
],
[
'id' => 2,
'content' => "Bar"
],
]
What you will want to do is use array_column() on the $remove array to capture just the IDs from the array and then implode that new array and pass it to the query.
$to_remove = array_column($remove, 'id'); //assuming that id is the column you want
http://php.net/manual/en/function.array-column.php
I've been trying to insert multiply items using foreach loop in php and mysql. When i insert its insert null values. any ideas as to what i should fix?
$itemNo = $statement->fetchColumn();
$item_name = ($_POST["item_name"]);
$item_price = ($_POST["item_price"]);
$item_quantity = ($_POST["item_quantity"]);
$item_total = ($_POST["item_total"]);
$statement = $connect->prepare("
INSERT INTO product
( `item_no`,`item_name`, `item_price`, `item_quantity`, `item_total`)
VALUES ('$itemNo','$item_name','$item_price','$item_quantity','$item_total')
");
foreach($_POST["item_name"] as $subscription){
$statement->execute(
array(
':itemNo' => $itemNo,
':item_name ' => trim($_POST["item_name"]),
':item_price' => trim($_POST["item_price"]),
':item_quantity' => trim($_POST["item_quantity"]),
':item_total' => trim($_POST["item_total"])
)
);
}
You need to put placeholders in the query, not variables, to match the parameters in the call to execute().
$statement = $connect->prepare("
INSERT INTO product
( `item_no`,`item_name`, `item_price`, `item_quantity`, `item_total`)
VALUES (:itemNo,:item_name,:item_price,:item_quantity,:item_total)
");
And if $_POST['item_name'] is an array, you can't use trim($_POST['item_name']) as a value. The argument to trim() has to be a string, not an array. If these post variables are all arrays, you need to index them.
foreach ($item_name as $index => $subscription) {
$statement->execute(
array(
':itemNo' => $itemNo,
':item_name ' => trim($subscription),
':item_price' => trim($item_price[$index]),
':item_quantity' => trim($item_quantity[$index]),
':item_total' => trim($item_total[$index])
)
);
}
I have some trouble with $query->bindParam. It doesn't change placeholders into values.
$options is an array:
$options['where'] = [
'id' => [ 1, 2, 3 ],
'title' => [ 'some', 'title' ]
];
$fields = '*';
$where_clauses = []; /* define empty error which could be filled with where clauses */
/* if it is a separte blog, only posts posted by it's admin should be got */
if ( Main::$current_blog_id !== 1 )
$where_clauses[] = '`author_id` IN(' . $this->blog->admin_id . ')';
/* if options have been passed */
if ( ! empty( $options ) ) {
/* if there are "where" options */
if ( ! empty( $options['where'] ) ) {
$placeholder_number = 1; /* define placeholder number */
$placeholders = []; /* create array with placeholders 'placeholder_number' => 'value' */
foreach ( $options['where'] as $field_name => $values ) {
$field_values = []; /* values that will be used to create "IN" statement */
/* fill $fild_values array with values */
foreach ( $values as $value ) {
$placeholder = ':' . $placeholder_number; /* create placeholder */
$field_values[] = $placeholder; /* add placeholder to field values */
$placeholders[ $placeholder ] = $value; /* add placeholer with it's value to common placeholders array */
$placeholder_number++; /* increase placeholder number */
}
/* turn $fields_values array into string */
$field_values = implode( ', ', $field_values );
/* create clause and put it into $where_clauses */
$where_clauses[] = '`' . $field_name . '` IN(' . $field_values . ')';
}
}
}
/* if where statement is empty */
$where_clauses =
! empty( $where_clauses ) ?
implode( ' AND ', $where_clauses ) :
1;
$query = Main::$data_base->pdo->prepare(
'SELECT ' . $fields . ' ' .
'FROM `posts` ' .
'WHERE ' . $where_clauses . ' ' .
'LIMIT ' . $posts_quantity . ';'
);
/* if there are placeholders in the query */
if ( ! empty( $placeholders ) ) {
foreach ( $placeholders as $placeholder => $value )
$query->bindParam( $placeholder, $value, PDO::PARAM_STR );
}
$query->execute();
$posts = $query->fetchAll( PDO::FETCH_ASSOC );
var_dump( $query );
return
! empty( $posts ) ?
$posts :
[];
After all of this my printed query looks like:
SELECT * FROM `posts` WHERE `id` IN(:1, :2, :3) AND `title` IN(:4, :5) LIMIT 15;
You need to define the binds like...
Array ( ':1' => 1, ':2' => 2, ':3' => 3, ':4' => 'some', ':5' => 'title' )
Also your select is incorrect...
"SELECT * FROM posts WHERE id IN(:1, :2, :3) AND title IN(:4, :5) LIMIT 15;"
You have to put AND and not && in there.
PDOStatement::bindParam doesn't modify the query string that you passed to PDO::prepare. It replaces the placeholders with the value of the variable that you bound to it in the moment you execute the statement and the query is sent to the SQL server.
This should be what you want:
$query = "SELECT * FROM posts WHERE id IN (:1, :2, :3) AND title IN (:4, :5) LIMIT 15;";
$statement = $db->prepare($query); // $db contains the connection to the database
$placeholders = array(':1' => 1, ':2' => 2, ':3' => 3, ':4' => 'some', ':5' => 'title');
foreach ($placeholders as $placeholder => $value) {
$statement->bindValue($placeholder, $value, PDO::PARAM_STR);
}
$statement->execute();
Note that I use PDOStatement::bindValue and that I modified your SQL query string (and instead of &&).
You could also do this:
$query = "SELECT * FROM posts WHERE id IN (:1, :2, :3) AND title IN (:4, :5) LIMIT 15;";
$statement = $db->prepare($query);
$placeholders = array(':1' => 1, ':2' => 2, ':3' => 3, ':4' => 'some', ':5' => 'title');
$statement->execute($placeholders);
Read about PDOStatement::execute in the docs.
I'm trying to be able to add parameters to to my prepared statement, query and arrays look right. But the "Number of elements in type definition string doesn't match number of bind variables" error is triggered.
$sql = 'SELECT * FROM `feed` ';
$types = array();
$params = array();
if( isset($_GET['p']) ) {
$page = $_GET['p'];
}
else {
$page = 0;
}
if( isset($_GET['q']) ) {
$sql .= 'WHERE `title` LIKE ? ';
$search = $_GET['q'];
array_push($types, 's');
array_push($params, $search);
}
$sql .= 'ORDER BY `time` DESC LIMIT ?, 6';
array_push($types, 'i');
array_push($params, $page);
$stmt = $mysqli->prepare($sql);
$params = array_merge($types, $params);
$refs = array();
foreach($params as $key => $value)
$refs[$key] = &$params[$key];
call_user_func_array(array($stmt, 'bind_param'), $refs);
(Printed from the server)
Query: SELECT * FROM feed WHERE title LIKE ? ORDER BY time DESC LIMIT ?, 6
Array merge:
Array
(
[0] => s
[1] => i
[2] => word
[3] => 0
)
Thanks.
My understanding is that the first parameter 'types' is a string of the types of the parameters, not an array. so the the parameter list for the example should look like:
Array
(
[0] => si
[1] => word
[2] => 0
)
This is untested code: but implode should do what we want from the '$types' array
$strTypes = implode('', $types);
i will check it later.