I am currently going through a nettuts.com tutorial on building a twitter clone and there they have a function for deleting rows from a database and they are using the query method but i tried converting the function to a prepared statement.However I get the Invalid parameter number: parameter was not defined error.Here is the code for the function
public function delete($table, $arr){
$query = "DELETE FROM " . $table;
$pref = "WHERE ";
foreach ($arr as $key => $value) {
$query .= $pref. $key . " = " . ":" . $key;
$pref = "AND ";
}
$query .= ";";
$result = $this->db->prepare($query);
$result->execute($arr);
}
$connect = new Model();
$connect->delete("ribbits", array("user_id" => 2,
"ribbit" => "trial ribbit"
));
can someone please tell me what I am doing wrong?Thank you!
When you pass your array to ->execute(), the keys need to have the : character before them (just like they appear in the SQL query).
So, in your delete function, build the SQL query like this:
public function delete($table, $arr){
$keys = array();
$values = array();
foreach($arr as $key => $value){
$keys[] = $key . " = :" . $key;
$values[":".$key] = $value;
}
$query = "DELETE FROM " . $table . " WHERE " . implode(" AND ", $keys);
$result = $this->db->prepare($query);
$result->execute($values);
}
Related
I am new to PDO PHP. I have created a post data function in order to achieve the insertion functionality. Here is my code.
public function PostData($conn, $table, $data)
{
try {
$query = "INSERT INTO " . $table . "(";
$arraylen = count($data);
$keyloopcount = 0;
foreach ($data as $key => $values) {
$query .= $key;
if ($keyloopcount != $arraylen - 1) {
$query .= ",";
}
$keyloopcount++;
}
$valloopcount = 0;
$query .= ") VALUES (";
foreach ($data as $key => $values) {
$query .= "':" . $key . "'";
if ($valloopcount != $arraylen - 1) {
$query .= ",";
}
$valloopcount++;
}
$query .= ")";
$stmt = $conn->prepare($query);
foreach ($data as $key => &$values) {
$stmt->bindParam(':'.$key, $values, PDO::PARAM_STR);
}
if ($stmt->execute()) {
$stmt->debugDumpParams();
echo "me";
} else {
echo "die";
}
} catch (PDOException $ex) {
echo $ex->getMessage();
}
}
When I execute this query. It doesn't show any exceptions. but when I look into my Database. It shows inserted records as follows.
I am wondering if there is a way I can debug what are the values in the binded params. I have also looked for $stmt->debugDumpParams(); as shown in the code. But it doesn't shows the values of params.
Need Guidance. TIA.
I sorted it out. I was making a silly mistake. The solution was so simple and easy.
Solution
The problem was lying in the part of the code.
foreach ($data as $key => $values) {
$query .= "':" . $key . "'";
if ($valloopcount != $arraylen - 1) {
$query .= ",";
}
$valloopcount++;
}
Changed the code to:
foreach ($data as $key => $values) {
$query .= ":" . $key;
if ($valloopcount != $arraylen - 1) {
$query .= ",";
}
$valloopcount++;
}
Resultant Query Before Amendment:
INSERT INTO cmp_categories(cat_name,cat_slug,cat_desc) VALUES (':cat_name',':cat_slug',':cat_desc')
Resultant Query AfterAmendment:
INSERT INTO cmp_categories(cat_name,cat_slug,cat_desc) VALUES (:cat_name,:cat_slug,:cat_desc)
More Clearly,
Removed ' from VALUES clause. ':cat_desc' => :cat_desc
I'm coding my web app in PHP and when I run my script, I've got this error :
array to string conversion
Here is the script where the error fires.
public function insert($table, array $columns, array $values) {
$sql = "INSERT INTO " . $table .
" (" . implode(',' , $columns) . " )
VALUES (" . implode(',',
$values) . ")";
$this->request($sql);
}
Here is the request function :
public function request($sql, $param = null) {
if ($param == null) {
$query = Database::getInstance()->getDb()->query($sql);
}
else {
$query = Database::getInstance()->getDb()->prepare($sql);
$query->execute(array($param));
}
return $query;
}
N.B : I'm using my own MVC framework.
So, any advise or help would be apreciated ?
Regards
YT
I advice to modify your class methods for using parameterized queries:
class Test {
public function insert($table, array $columns, array $values) {
$sql = "INSERT INTO " . $table . " (" . implode(',' , $columns) . ")
VALUES (?" . str_repeat(",?", count($columns) - 1) . ");";
echo $sql;
$this->request($sql, $values);
}
public function request($sql, $param = null) {
if ($param == null) {
$query = Database::getInstance()->getDb()->query($sql);
}
else {
$query = Database::getInstance()->getDb()->prepare($sql);
$query->execute($param);
}
return $query;
}
};
$test = new Test();
$test->insert('tbl', ['id', 'name'], [1, 'first row']);
Online PHP test
I am looking for a way to make dynamic queries to my MySQL server. At the moment this is the code I use to update data on the server:
$deskAttr = json_decode($_POST["desk_attributes"]);
foreach($deskAttr as $key => $value) {
$sql = "UPDATE desk_attributes SET iw_standard=".$value->iw_standard.", avaya_standard=".$value->avaya_standard.", avaya_withcallid=".$value->avaya_withcallid.", avaya_withtransfer=".$value->avaya_withtransfer.", dual_screen=".$value->dual_screen.", air_conditioning=".$value->air_conditioning.", iw_obdialler=".$value->iw_obdialler." WHERE id=".$value->id;
$conn->query($sql);
}
As you can see, the SQL column names are the same as thedeskAttrkeys. I'm looking for a way to make this line a loop so, that I don't need to change this line if I were to add more columns to the MySQL table.
It would look something like this:
$deskAttr = json_decode($_POST["desk_attributes"]);
foreach($deskAttr as $key => $value) {
$sql = "UPDATE desk_attributes SET";
foreach($value as $k => $v) {
$sql .= " $k = $value->$k ,";
}
$sql .= "WHERE id=".$value->id";
}
How would I write the code above so it will actually work?
**EDIT**
Maybe it will be helpful to know that$deskAttr is an array of objects, and the name of the columns are the same as the name of the objects keys.
Here is what I mean in pseudo code:
foreach($object in $deskAttr) {
$sql = "UPDATE table SET ";
foreach($key in $object) {
if($key != "id")
$sql .= "$key = $object->$key, ";
}
$sql .= "WHERE id = $object->id;
$conn->query($sql);
}
Obviously this would add an extra comma at the end of the query before the WHERE part, but hopefully you get what I'm trying to achieve.
You can do it with slight change in your code by using PHP's implode() function.
Take a blank array, concatenate the update parameters to it.
And then if is not empty(), implode() to get string.
Updated Code:
$sql = "UPDATE desk_attributes SET ";
foreach ($deskAttr as $key => $value) {
$value = mysqli_real_escape_string($link, $value); // $links is database connection string.
$key = mysqli_real_escape_string($link, $key); // $links is database connection string.
$updtAttrs[] = $key ." = '" . $value . "'";
}
$sql .= ! empty($updtAttrs) ? implode(', ', $updtAttrs) : '';
$sql .= " WHERE id=" . $value->id;
I would like to add " AND " in between the key and value pair arguments for my sql query but I don't know how. I have tried search the net but unable to find a solution.
$cdatahome = fetchCategory(array("status"=>"1","home"=>"1"));
function fetchCategory(array $conditions){
$db = Core::getInstance();
$sql = "SELECT id, title FROM ruj_category WHERE ";
$params = array();
foreach ($conditions as $column => $value) {
if (preg_match('/^[a-z-.]+$/', $column)) {
$sql .= "$column = ?";
$params[] = $value;
}
}
$sql .= " order by title asc";
$res = $db->dbh->prepare($sql);
$res->execute(array_values($params));
$res = $res->fetchAll(PDO::FETCH_ASSOC);
return $res;
$where = array();
foreach ($conditions as $column => $value) {
if (preg_match('/^[a-z-.]+$/', $column)) {
$where[] = "$column = ?";
$params[] = $value;
}
}
$sql .= implode(' AND ', $where);
$cdatahome = fetchCategory(array("status"=>"1","home"=>"1"));
function fetchCategory(array $conditions){
$db = Core::getInstance();
$sql = "SELECT id, title FROM ruj_category WHERE ";
$params = array();
$i = 0;
foreach ($conditions as $column => $value) {
if (preg_match('/^[a-z-.]+$/', $column)) {
if($i != 0){
$sql .= ' AND ';
}
$sql .= "$column = ?";
$params[] = $value;
$i++;
}
}
$sql .= " order by title asc";
$res = $db->dbh->prepare($sql);
$res->execute(array_values($params));
$res = $res->fetchAll(PDO::FETCH_ASSOC);
return $res;
Usually, when I want to put something like AND or & (in the case of URLs), I create an array and implode it on the string I want in the middle. For example:
$items = array("a", "b", "c");
$output = implode(" AND ", $items);
Outputs:
"a AND b AND c"
In your case, you can do your foreach loop to build the string pieces and then use AND as glue in the implode() function as listed out by the second answer.
First, you could put the conditions into an array, as you do with the values to $params. Like $cond[]="$column = ?" and then $sql.=implode(' AND ',$cond);
To have it solved in your foreach: before the loop set $first=false; and in the loop do $sql.=($first?'':' AND ')."$column = ?"; $first=false;
I have this function
function updateDbRecord($db, $table, $carry, $carryUrl) {
mysql_select_db($db) or die("Could not select database. " . mysql_error());
$resultInsert = mysql_query("SHOW COLUMNS FROM " . $table . " WHERE Field NOT IN ('id')");
$fieldnames=array();
if (mysql_num_rows($resultInsert) > 0) {
while ($row = mysql_fetch_array($resultInsert)) {
$fieldnames[] = $row['Field'];
$arr = array_intersect_key( $_POST, array_flip($fieldnames) ); #check if value is null otherwise do not INSERT
}
}
$set = "";
foreach($arr as $key => $v) {
$val = is_numeric($v) ? $v : "'" . $v . "'";
$set .= $key . '=' . $val . ', ';
}
$sql = sprintf("UPDATE %s SET %s WHERE id='%s'", $table, $set, $_POST['id']);
mysql_query($sql);
if ($carry == 'yes') {
redirect($carryUrl.'?id='.$_REQUEST['id']);
} else { echo "Done!"; }
echo $sql;
}
It outputs for example: UPDATE projects SET project_name='123', project_bold='123', project_content='123', WHERE id='12'
The last comma before where is preventing it from working. Is there a way of avoiding this? Im aware of the function implode, however I am not sure how to employ it in this situation.
Yes,
$sql = substr($sql,'',-1);
I would use
$sql = rtrim($sql, ',');
Either that or instead of appending to a string, append to an array and use implode.
function updateDbRecord($db, $table, $carry, $carryUrl) {
mysql_select_db($db) or die("Could not select database. " . mysql_error());
$resultInsert = mysql_query("SHOW COLUMNS FROM " . $table . " WHERE Field NOT IN ('id')");
$fieldnames=array();
if (mysql_num_rows($resultInsert) > 0) {
while ($row = mysql_fetch_array($resultInsert)) {
$fieldnames[] = $row['Field'];
$array = array_intersect_key( $_POST, array_flip($fieldnames) ); #check if value is null otherwise do not INSERT
}
}
foreach ($array as $key => $value) {
$value = mysql_real_escape_string($value); // this is dedicated to #Jon
$value = "'$value'";
$updates[] = "$key = $value";
}
$implodeArray = implode(', ', $updates);
$sql = sprintf("UPDATE %s SET %s WHERE id='%s'", $table, $implodeArray, $_POST['id']);
mysql_query($sql);