I try save integer with value 0 in php to decimal(7,2) in miranda db.
But integer with value 0 save always 99999.99
I cannot find the solution. I think it can transform automatically.
I use PDO in php.
Other values than 0 works well.
My inserted array:
array(":name"=>"3ld",":urlid"=>($url->id),":date"=>"NOW()",":type"=>"renew",":status"=>($url->alias.$url->custom.".".$url->tld),":price"=>$price)
Var dump value from array:
array(6) { [":name"]=> string(3) "3ld" [":urlid"]=> string(1) "1" [":date"]=> string(5) "NOW()" [":type"]=> string(5) "renew" [":status"]=> string(19) "support.url.tld" [":price"]=> int(0) }
The part of code:
$this->db->insert("log_url",array(":name"=>"3ld",":urlid"=>($url->id),":date"=>"NOW()",":type"=>"renew",":status"=>($url->alias.$url->custom.".".$url->tld),":price"=>$price));
DB insert function:
public function insert($table,$parameters=array()){
$param="";
$val="";
$insert= $this->ph($parameters);
//Build Query
$query="INSERT INTO {$this->dbinfo["prefix"]}$table";
if(is_array($insert)){
$count=count($insert);
$i=0;
foreach ($insert as $key => $value) {
if($parameters[$value]=="NOW()"){
$val.= "NOW()";
unset($parameters[$value]);
}else{
$val.=$this->quote($value,$parameters);
}
$param.="`$key`";
if(++$i != $count) {
$param.=",";
$val.=",";
}
}
$query.=" ($param) VALUES ($val)";
}
$result = $this->db->prepare($query);
$result->execute($parameters);
if($this->error_message($result->errorInfo())) {
$this->query=strtr($query,$parameters);
$this->db_error=$this->error_message($result->errorInfo());
exit;
}
++$this->num_queries;
return TRUE;
}
Quote function:
private function quote($string,$param=''){
if(empty($param)){
return "'$string'";
}
return $string;
}
Generate placeholders function:
private function ph(array $a){
$b=array();
foreach ($a as $key => $value) {
$b[str_replace(":", "", $key)]="$key";
}
return $b;
}
Any information helps, thank you.
Updated Code:
public function insert($table,$parameters=array()){
$param="";
$val=array();
$insert= array_keys($parameters); var_dump($parameters);
//Build Query
$query="INSERT INTO {$this->dbinfo["prefix"]}$table";
if(is_array($insert)){
$query.=' (`'.implode($insert,"`,`").'`) VALUES (:'.implode($insert,', :').')';
$result = $this->db->prepare($query);
foreach($parameters as $key=>$param) {
$result->bindParam(":".$key, ($param['value']=='NOW()')?date('Y-m-d H:i:s'):$param['value'], PDO::PARAM_STR);
}
}
$result->execute(); //$result->execute($parameters);
if($this->error_message($result->errorInfo())) {
$this->query=strtr($query,$parameters);
$this->db_error=$this->error_message($result->errorInfo());
exit;
}
++$this->num_queries;
return TRUE;
}
produce as price 2015.00
Replace call to method by removing ":" it has no sense to send ":" and then remove that ":" by ->ph()
$this->db->insert("log_url",
array("name"=>array("value"=>"3ld","type"=>PDO::PARAM_STR), //
"urlid"=>array("value"=>$url->id,"type"=>PDO::PARAM_STR),
"date"=>array("value"=>'NOW()',"type"=>PDO::PARAM_STR),
"type"=>array("value"=>'renew',"type"=>PDO::PARAM_STR),
"status"=>array("value"=>$url->alias.$url->custom.".".$url->tld,"type"=>PDO::PARAM_STR),
"price"=>array("value"=>$price,"type"=>PDO::PARAM_STR))); //
about PDO types params read here:
http://php.net/manual/en/pdo.constants.php
and here
http://php.net/manual/en/pdostatement.bindparam.php
and inside your function you can replace this:
$param="";
$val="";
$insert= $this->ph($parameters);
//Build Query
$query="INSERT INTO {$this->dbinfo["prefix"]}$table";
if(is_array($insert)){
$count=count($insert);
$i=0;
foreach ($insert as $key => $value) {
if($parameters[$value]=="NOW()"){
$val.= "NOW()";
unset($parameters[$value]);
}else{
$val.=$this->quote($value,$parameters);
}
$param.="`$key`";
if(++$i != $count) {
$param.=",";
$val.=",";
}
}
$query.=" ($param) VALUES ($val)";
}
$result = $this->db->prepare($query);
with this:
$val=array();
$insert= array_keys($parameters);
//Build Query
$query="INSERT INTO {$this->dbinfo["prefix"]}$table";
if(is_array($insert)){
$query.=' (`'.implode($insert,"`,`").'`) VALUES (:'.implode($insert,', :').')';
$stmt= $this->db->prepare($query);
foreach($parameters as $key=>$param) {
//$stmt->bindParam(":".$key, ($param['value']=='NOW()')?date('Y-m-d H:i:s'):$param['value']);
if($param['value']=='NOW()') {
$now = date('Y-m-d H:i:s');
$stmt->bindParam(":".$key, $now, $param['type']);
} else {
$stmt->bindParam(":".$key, $param['value'], $param['type']);
}
}
}
so, this must work
by the way, don't forget change:
$result->execute($parameters);
to
$stmt->execute();
downthere...
Related
I have a sql UPDATE query in PDO that should update a name and a permissions string.
But instead it just places the id of that row inside all columns.
Here is my code:
public function saveRole($roleID, $name, $permissions)
{
$sql = "UPDATE roles SET name = :name, permissions = :permissions WHERE id = :id";
//this one sets a string variable in the PDO wrapper class
PDO::setSQL($sql);
//this one sets an array inside the PDO wrapper class
PDO::setData([
'name' => $name,
'permissions' => $permissions,
'id' => $roleID,
]);
PDO::execute();
return PDO::getResponse(true);
}
As you see, I've written a wrapper for PDO, which looks like this:
static function execute($sql = null, $data = null, $fetchmode = \PDO::FETCH_OBJ)
{
//check if data and SQL are set in function call, if so, use function call params, if not use class params ($this->SQL & $this->data)
self::connect();
try
{
$stmnt = self::$con->prepare(self::$sql);
$stmnt->setFetchMode($fetchmode);
if (sizeof(self::$data) > 0)
{
foreach (self::$data as $key => $value)
{
$stmnt->bindParam(':' . $key, $value);
}
}
$stmnt->execute();
self::$stmnt = $stmnt;
self::$data = [];
self::$sql = '';
self::$lastResponse = new pdoReturn(true, $stmnt);
return;
} catch (\PDOException $exception)
{
self::$data = [];
self::$sql = '';
self::$lastResponse = new pdoReturn(false, $exception);
return;
}
}
function setSQL($sql) {
if (!is_string($sql))
return false;
if (strlen($sql) == 0)
return false;
$this->sql = $sql;
return true;
}
function setData($data) {
if (!is_array($data))
return false;
$this->data = $data;
return true;
}
As you see, I've written a wrapper for PDO
For the immediate fix, change
$stmnt = self::$con->prepare(self::$sql);
$stmnt->setFetchMode($fetchmode);
if (sizeof(self::$data) > 0)
{
foreach (self::$data as $key => $value)
{
$stmnt->bindParam(':' . $key, $value);
}
}
$stmnt->execute();
to
$stmnt = self::$con->prepare(self::$sql);
$stmnt->setFetchMode($fetchmode);
$stmnt->execute(self::$data);
Then read about your first database wrapper's childhood diseases and fix other issues such as statefulness and error reporting.
I got a codeigniter custom_result_object with this:
$user = $this->CI->db->get_where('users', array('email' => $email), 1)->custom_row_object(0,'entities\User');
and everything looks fine. I can update values with my setters.
Before I'm going to save i check my values with:
die(print_r($user));
and the values are correct.
I put my object in my update method.
$this->CI->db->update('users', $user, "id = ".$user->getId());
But the db is not updating. Am I missing something?
Thx!
EDIT:
So by using CI native db-method i can use:
public function save($user)
{
if($user->getId() == NULL){
$this->CI->db->insert('users', $user);
}else{
$this->CI->db->update('users', $user, "id = ".$user->getId());
}
}
Edit 2:
After some more checking I can see that it's not setting variables that are protected. CI is able to get the object through getters and setters but not able to save back to DB?
public function saveData($tbl,$data,$update = false,$previewStr = false){
$set_str = "NO_QUOTES()";
if(isset($data[$set_str])){
foreach($data[$set_str] as $set_key => $set_value){
$this->db->set($set_key, $set_value, FALSE);
}
unset($data[$set_str]);
}
if(isset($update[$set_str])){
foreach($update[$set_str] as $whr_key => $whr_value){
$this->db->where($whr_key." ".$whr_value,NULL,false);
}
unset($update[$set_str]);
if(is_array($update) and count($update) <= 0){
$update = true;
}
}
if($update == false){
$this->db->insert($tbl, $data);
if($previewStr){
return $this->db->last_query();
}else{
return $this->db->insert_id();
}
}else{
$result = NULL;
if(!is_array($update)){
if(is_array($data) and count($data) > 0){
foreach($data as $field => $value){
$this->db->set($field, $value);
}
}
$result = $this->db->update($tbl);
}else{
$result = $this->db->update($tbl, $data,$update);
}
if($previewStr){
return $this->db->last_query();
}else{
return $result;
}
}
}
public function delData($tbl = false,$where = array()){
if($tbl !== false){
return $this->db->delete($tbl, $where);
}else{
return false;
}
}
public function simpleQuery($query,$return_array = false,$return_single = false)
{
$ac = $this->db->query($query);
if($return_array === false){
return $ac;
}else{
if($return_single === false){
return $ac->result_array();
}else{
return $ac->row_array();
}
}
}
Use above code in your model and you i am giving you how to update it use below code in your controller you can insert update and delete by above code
$result=$this->Products_model->saveData("customer",array("customer_name"=>$name),array("cust_id"));
I have an issue with my INSERT query, $pdo->execute return false, with error code 00000
Query
string 'INSERT INTO module_test (img_name, description, priority) VALUES(:img_name, :description, :priority)' (length=100)
errorInfo() return:
array (size=3)
0 => string '00000' (length=5)
1 => null
2 => null
Code:
private function Init($query, $parameters = "")
{
# Connect to database
if (!$this->bConnected) {
$this->Connect();
}
try {
# Prepare query
$this->sQuery = $this->pdo->prepare($query);
# Add parameters to the parameter array
$this->bindMore($parameters);
# Bind parameters
if (!empty($this->parameters)) {
foreach ($this->parameters as $param => $value) {
$type = PDO::PARAM_STR;
switch ($value[1]) {
case is_int($value[1]):
$type = PDO::PARAM_INT;
break;
case is_bool($value[1]):
$type = PDO::PARAM_BOOL;
break;
case is_null($value[1]):
$type = PDO::PARAM_NULL;
break;
}
// Add type when binding the values to the column
$this->sQuery->bindValue($value[0], $value[1], $type);
}
}
# Execute SQL
var_dump($query);
var_dump($this->sQuery->execute());
var_dump($this->sQuery->errorInfo());
}
catch (PDOException $e) {
# Write into log and display Exception
echo $this->ExceptionLog($e->getMessage(), $query);
die();
}
# Reset the parameters
$this->parameters = array();
}
public function query($query, $params = null, $fetchmode = PDO::FETCH_ASSOC)
{
$query = trim(str_replace("\r", " ", $query));
$this->Init($query, $params);
$rawStatement = explode(" ", preg_replace("/\s+|\t+|\n+/", " ", $query));
# Which SQL statement is used
$statement = strtolower($rawStatement[0]);
if ($statement === 'select' || $statement === 'show') {
return $this->sQuery->fetchAll($fetchmode);
} elseif ($statement === 'insert' || $statement === 'update' || $statement === 'delete') {
return $this->sQuery->rowCount();
} else {
return NULL;
}
}
public function insert($table, $keyValue)
{
$fieldString = '';
$valueString = '';
$i = 1;
foreach ($keyValue as $key => $currKeyValue)
{
$fieldString .= $key;
$valueString .= ':'.$key;
if($i != count($keyValue))
{
$fieldString .= ', ';
$valueString .= ', ';
}
$i++;
}
$query = 'INSERT INTO '.$table.' ('.$fieldString.') VALUES('.$valueString.')';
$this->query($query, $keyValue);
}
Parameters array
F:\Dev\wamp\wamp64\www\include\class\Database.class.php:216:
array (size=3)
'img_name' => string 'ttt1' (length=4)
'description' => string 'ttt1' (length=4)
'priority' => int 0
I already try this query in phpmyadmin and everything worked well.
If someone know how to solve this?
thanks
PS: sorry for my bad english
PDO is reported not to fill the errorInfo property in certain circumstances.
Instead, you have to make it throw an exception, which is the most reliable way to get the error message. To do so, in your constructor, add this line
$this->pdo->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
Also note that your class is a genuine example of all the mistakes one could make writing a PDO wrapper. I compiled the most popular mistakes in an article, Your first database wrapper's childhood diseases and your class contains every single one of them.
i am working on my own restfull api. I have read many article about, but i come out more confused that before.
fist question:
in PUT request is correct to use question mark (?) ex:
http://myapi.me/testApi/v5/create/places?address=Five&building=old
or i must to use
http://myapi.me/testApi/v5/create/places/address=Five&building=old
if the second is the correct way, how i can explode the query string for create my insert statement? my code work well with (?). But curl command does not want to enter the record. So i need to modify the script to reflect the correct way with(/) instead of (?).
Please help...
my code:
$body = file_get_contents("php://input");
$content_type = false;
if(isset($_SERVER['CONTENT_TYPE'])) {
$content_type = $_SERVER['CONTENT_TYPE'];
// echo $content_type;
}
switch($content_type) {
//other case...
case "application/x-www-form-urlencoded":
parse_str($body, $postvars);
foreach($postvars as $field => $value) {
$parameters[$field] = $value;
}
$this->format = "html";
break;
default:
// we could parse other supported formats here
break;
}
$this->parameters = $parameters;
private function createRecord(){
if($this->get_request_method() != "PUT"){
$this->response('',406);
}
$table = strtolower(trim(str_replace("/", "", $_REQUEST['rquest'])));
/*
$Q = explode("/", $_SERVER["rquest"]);
print_r(array_values($Q));
echo "\n";
*/
$uri = $this->parameters;
if($uri){
array_shift($uri);
foreach( $uri as $k => $v )
{
$aKeyPholder[]= $k;
$aKey[]= ':'.$k;
}
$aKeyPholder= implode(',', $aKeyPholder);
$aKey= implode(',', $aKey);
$insert = "INSERT INTO '$table' ($aKeyPholder) VALUES ($aKey)";
// echo "insert=$insert\n";
$stmt = $this->db->prepare($insert);
foreach($uri as $k => &$v){
$stmt->bindParam(':'.$k, $v, PDO::PARAM_STR);
}
//$stmt->execute();
if ($stmt->execute()) { echo "Record succesfully created!";}
$this->response($this->json($success),200);
}
else{
$this->response('',204); // If no records "No Content" status
}
}
I wrote an global function that getting array with keys and values, and inserting it to mysql db. something like this:
function insert_to_db($table, $data, $is_using_id) {
// I'm connecting to db before this code.
global $mysqli;
// .. Checking for errors ..
// .. if using id, remove the id from the values like this:
$columns = array_keys($data);
$values = array_values($data);
if ($is_using_id == true) {
unset($values[0]);
// Reorder the array after unset()
$values = array_merge($values);
}
// ..
// Generating text for use at the mysqli::prepare
$columns_text = "";
$i = 0;
while ($i < count($columns)) {
$column = $columns[$i];
if ($i == 0) {
$columns_text = $column;
} else {
$columns_text = $columns_text.", ".$column;
}
$i++;
}
unset($i);
unset($column);
$values_text = "";
// b_p_f is the $types string for mysqli-stmt::bind_param
$b_p_f = "";
// Generating text for use at the mysqli::prepare
$i = -1;
while ($i < count($values)) {
echo "\$i equals to {$i}<br>";
if ($is_using_id == true && $i == -1) {
// Null because id is calculated automatically by mysql
$values_text = "NULL";
} else if ($is_using_id == false && $i == 0) {
$value = $values[$i];
$values_text = "?";
if (is_numeric($value))
{
$b_p_f = 'i';
} else {
$b_p_f = 's';
}
} else {
$value = $values[$i];
$values_text = $values_text.", ?";
if (is_numeric($value))
{
echo "Value: {$value} Found as numberic<br>";
$b_p_f = $b_p_f.'i';
} else {
echo "Value: {$value} Found as non-numberic<br>";
$b_p_f = $b_p_f.'s';
}
}
$i++;
}
unset($i);
unset($value);
echo "b_p_f:";
var_dump($b_p_f);
echo " values:";
var_dump($values);
$stmt = $mysqli->prepare("INSERT INTO ".$table." (".$columns_text.") VALUES (".$values_text.")");
if (!$stmt) {
return array("error"=>"true", "error_mysqli"=>$mysqli->error, "MORE"=>"INSERT INTO ".$table." (".$columns_text.") VALUES (".$values_text.")");
}
$stmt->bind_param($b_p_f, $values);
if ($stmt->execute()) {
return array("error"=>"false", "inserted_id"=>$mysqli->insert_id);
} else {
return array("error"=>"true", "error_stmt"=>$stmt->error, "MORE"=>"INSERT INTO ".$table." (".$columns_text.") VALUES (".$values_text.")");
}
}
Then I am calling to the function:
function hash_password($password) {
$options = [ 'cost' => 12 ];
return password_hash($password, PASSWORD_BCRYPT,$options);
}
$data = array(
"ID" => NULL,
"first_name" => "Alexander",
"last_name" => "Margolis",
"email" => "shay24590#gmail.com",
"username" => "smartDonkey",
"password" => "Incorrect",
"birthday" => "12-12",
"date_added" => time(),
"total_points" => 0,
"cafe_added" => 0,
"review_placed"=> 0);
$data["password"] = hash_password($data["password"]);
var_dump ( insert_to_db("user", $data, true) );
And I see on the screen
array(3) {
["error"]=> string(4) "true"
["error_stmt"]=> string(53) "No data supplied for parameters in prepared statement" ["MORE"]=> string(178) "..."
}
Why am I getting this? What is the problem?
Also, If I pass the value instead of ? to the mysql::prepare, it works! So - it means that the problem is with mysqli stmt bind_param..
I know that this question similar to others, but I didn't found one that helps my problem. and sorry for my english and for the long function. thank you!
I've moved to PDO, and instead of calling $stmt->bind_param($b_p_f, $values); you can call $pdo_stmt->execute($values) where $values is an Array.