I need to insert array values in php as Columns in a MYSQL table.
$new_user = array(
"Nom" => $_POST['Nom'],
"EmailID" => $_POST['EmailID'],
"localité" => $_POST['localité']
);
$table = "memfis";
$columnNames = implode(", ", array_keys($new_user));
$columnPlaceholders = "'" . implode("', '", array_keys($new_user)) . "'";
$sqld = "INSERT INTO $table ($columnNames) VALUES ($columnPlaceholders);";
var_dump($sqld); exit;
$stmt = $pdo->prepare($sqld);
foreach ($columnNames as $name) {
$placeholder = "'" . $name;
$stmt->bindParam($placeholder, $new_user[$name]);
}
$connection->execute($sqld);
echo "New record created successfully";
It should have displayed " New row added succesfully " and the row should have been added in the table.
I tested the following with the original field names - specifically making note of the acute accent on the e and it failed - when I removed the accent and replaced with a standard letter e it worked fine
<?php
/* PDO dbo */
$dbport = 3306;
$dbhost = 'localhost';
$dbuser = 'root';
$dbpwd = 'xxx';
$dbname = 'xxx';
$options=array(
PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL,
PDO::ATTR_PERSISTENT => false,
PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true,
PDO::ATTR_EMULATE_PREPARES => true,
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'utf8mb4\' COLLATE \'utf8mb4_general_ci\', ##sql_mode = STRICT_ALL_TABLES, ##foreign_key_checks = 1'
);
$dsn = 'mysql:host='.$dbhost.';port='.$dbport.';dbname='.$dbname.';charset=UTF8';
$db = new PDO( $dsn, $dbuser, $dbpwd, $options );
/* Emulate POST form submission */
$_POST=[
'Nom' => 'fred flintstone',
'EmailID' => 'fred#bedrock.com',
'localite' => 'Bedrock'
];
$table='memfis';
/* prepare field names */
$fields = sprintf( '`%s`', implode( '`,`', array_keys( $_POST ) ) );
/* placeholder arrays */
$args = [];
$vals = [];
/* create placeholder variable names */
foreach( $_POST as $field => $value ) {
$args[]=sprintf( ':%s', strtolower( $field ) );
$vals[ sprintf( ':%s', strtolower( $field ) ) ]=$value;
}
/* create the sql statement */
$sql=sprintf(
'insert into `%s` ( %s ) values ( %s );',
$table,
$fields,
implode( ', ', $args )
);
$stmt = $db->prepare( $sql );
if( $stmt ){
# debug info
printf("<pre>%s\n%s</pre>", $sql, print_r( $vals, true ) );
# execute the statement
$res=$stmt->execute( $vals );
# did it or did it not work?
if( $res ){
echo "OK!";
} else {
echo "Bogus!";
}
}
?>
The resultant output to screen of the above is:
insert into `memfis` ( `Nom`,`EmailID`,`localite` ) values ( :nom, :emailid, :localite );
Array
(
[:nom] => fred flintstone
[:emailid] => fred#bedrock.com
[:localite] => Bedrock
)
OK!
When using the original fieldname localité the following error occurs:
Warning: PDOStatement::execute() [pdostatement.execute.html]:
SQLSTATE[HY093]: Invalid parameter number: parameter was not defined
in .....
Related
I can't get SQLite LIKE search to work with PDO. This works fine with
MySQL and MariaDB but I can't get this to work with SQLite3.
I have also tried with different examples from internet.
I'm using sqlite3 version 3.35.3 and version PHP 8.0.3 on Linux 5.9.
echo '<pre>';
$createTable = <<<EOT
CREATE TABLE users (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL
);
INSERT INTO users(name) VALUES
('alpha'),
('beta'),
('gamma'),
('theta');
EOT;
if (!file_exists(__DIR__ . '/test.db'))
{
echo "#CREATING DB# <br>";
$pdo = new \PDO('sqlite:' . __DIR__ . '/test.db');
$pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
$pdo->exec($createTable);
$term = 'et';
$sql = " SELECT * FROM users WHERE name LIKE :term ";
$stmt = $pdo->prepare($sql);
$prepare = [
'term' => "'%". $term ."%'"
];
echo getPdoCompiledSqlString($sql, $prepare) . '<br>';
if($stmt)
{
$stmt->execute($prepare);
//$stmt->debugDumpParams();
debugPdo($stmt);
echo "#FETCHALL# <br>";
print_r( $stmt->fetchAll() );
}
}
else
{
echo "#DELETING DB#";
unlink(__DIR__ . '/test.db');
}
function getPdoCompiledSqlString($sql, $params){
echo "#SQL STRING# <br>";
$keys = [];
foreach ($params as $key => $value){ if (is_string($key)) {$keys[] = '/:'.$key.'/';} else {$keys[] = '/[?]/';}}
return preg_replace($keys, $params, $sql, 1, $count);
}
function debugPdo(&$stmt){
echo "#DEBUG PDO OBJ# <br>";
$stmt->debugDumpParams();
}
echo '<pre>';
You don't need to quote the parameter :
'term' => "%". $term ."%"
Instead of
'term' => "'%". $term ."%'"
Because the parameter will automatically be quoted during execute()
$term = 'et';
$sql = " SELECT * FROM users WHERE name LIKE :term ";
$stmt = $pdo->prepare($sql);
$prepare = [
'term' => "%". $term ."%" //only the search string: `%et%`
];
$stmt->execute($prepare);
print_r($stmt->fetchAll());
Output:
Array
(
[0] => Array
(
[id] => 2
[0] => 2
[name] => beta
[1] => beta
)
[1] => Array
(
[id] => 4
[0] => 4
[name] => theta
[1] => theta
)
)
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.
Fatal error: Call to a member function prepare() on a non-object in
/home/addictiv/public_html/AddictiveRP/Online/lib/katniss/mod.DB.php on line 95
This is mod.DB.php
class DB
{
static $db = null;
static $queries = 0;
static $ms = 0;
//
// Connect to a PDO database
//
static function Connect( $connectstr, $username, $password, $persistant = false, $throwerror = true, $debug = false )
{
DEBUG::Msg( "Connecting to database", 'db' );
$time = microtime( true );
$options = array(
PDO::ATTR_PERSISTENT => $persistant
);
try
{
DB::$db = #new PDO( $connectstr, $username, $password, $options );
if( $debug )
DB::$db->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
}
catch ( exception $e )
{
DEBUG::Msg( "Connection Failed!", 'db' );
if ( $throwerror )
DEBUG::Error( array( 'error' => "Failed to connect", 'message' => $e->getMessage() ), 'DB' );
return false;
}
DB::$ms += microtime( true ) - $time;
DEBUG::Msg( "Connected!", 'db' );
return true;
}
//
// Throws an error if the database isn't ready
//
static function Check()
{
if ( !DB::$db )
DEBUG::Error( array( 'error' => "No Connection" ), 'DB' );
}
//
// Prepared statement wrapper
//
static function Query( $str, $arry = null )
{
DB::Check();
DB::$queries++;
DEBUG::Msg( "Query Start:", 'db' );
DEBUG::Msg( $str, 'db' );
$time = microtime( true );
$st = DB::$db->prepare( $str ); // Line 95 error
if ( !$st )
DEBUG::Error( array( 'error' => "Create Query Failed", 'query' => $str, 'array' => $arry, 'message' => DB::$db->errorInfo() ), 'DB' );
if ( !$st->execute( $arry ) )
DEBUG::Error( array( 'error' => "Query Failed", 'query' => $str, 'array' => $arry, 'message' => $st->errorInfo()), 'DB' );
$result = $st->fetchAll( PDO::FETCH_ASSOC );
DEBUG::Msg( "Done", 'db' );
DB::$ms += microtime( true ) - $time;
return $result;
}
static function QueryRow( $str, $arry = null ) { $ret = DB::Query( $str, $arry ); if ( $ret ) return reset( $ret ); }
static function QueryValue( $str, $arry = null ) { $ret = DB::QueryRow( $str, $arry ); if ( $ret ) return reset( $ret ); }
static function QueryUpdateCheck($str, $arry = null){
DB::Check();
DB::$queries++;
DEBUG::Msg( "Query Start:", 'db' );
DEBUG::Msg( $str, 'db' );
$time = microtime( true );
$st = DB::$db->prepare( $str );
if ( !$st )
DEBUG::Error( array( 'error' => "Create Query Failed", 'query' => $str, 'array' => $arry, 'message' => DB::$db->errorInfo() ), 'DB' );
if ( !$st->execute( $arry ) )
DEBUG::Error( array( 'error' => "Query Failed", 'query' => $str, 'array' => $arry, 'message' => $st->errorInfo()), 'DB' );
$st;
DEBUG::Msg( "Done", 'db' );
DB::$ms += microtime( true ) - $time;
return $st->rowCount();
}
//
// Insert an array into the database. Returns the insert id
//
static function Insert( $table, $arry, $insert = "INSERT" )
{
$keys = array();
$keys_val = array();
$values = array();
foreach ( $arry as $k => $v )
{
$keys[] = $k;
$keys_val[] = ':'.$k;
$values[':'.$k] = $v;
}
$query = $insert . " INTO " . $table . " (".implode( ',', $keys ).") VALUES ( ".implode( ',', $keys_val )." )";
DB::Check();
DB::$queries++;
DEBUG::Msg( "Insert Start: [".$query."]", 'db' );
$time = microtime( true );
$st = DB::$db->prepare( $query );
if ( !$st )
DEBUG::Error( array( 'error' => "Create Insert Failed", 'query' => $query, 'array' => $values, 'message' => DB::$db->errorInfo() ), 'DB' );
if ( !$st->execute( $arry ) )
DEBUG::Error( array( 'error' => "Insert Failed", 'query' => $query, 'array' => $values, 'message' => $st->errorInfo()), 'DB' );
DEBUG::Msg( "Done", 'db' );
DB::$ms += microtime( true ) - $time;
return DB::$db->lastInsertId();
}
//
// Like insert, but replaces the entry if it exists.
//
static function Replace( $table, $arry )
{
return DB::Insert( $table, $arry, 'REPLACE' );
}
//
// Called when shutting down
//
static function OnShutdown()
{
DEBUG::Msg( "Database: ". DB::$queries . " queries (". round( DB::$ms, 3 ) . " seconds)", 'db' );
}
}
What it calls for:
<?php
define('MySQLSet', true); // Change this to true once you've entered your MySQL settings below
define('MySQLHost', ''); // The host of your MySQL database.
define('MySQLDBName', ''); // The name of your MySQL database.
define('MySQLDBUName', ''); // The username of your MySQL database;
define('MySQLDBPassword', ''); // The password of the user.
define('PAGEID', '2003'); // Your VXDonation page id.
define('APIKEY', ''); // Your Steam API Key (For avatars and such)
define('BaseURL', '/Online/'); // Where the system is installed relative to your root.
define('CURSYMBOL', '$'); // The symbol of your real world currency. £ or $ or whatever.
// For example, if you accessed the system by going to yoursite.com/donation/mydonation,
I'm not an expert at this at all so i have no idea what's wrong
I'm storing a JSON array in a mysql TEXT field using PDO. (encoded with json_encode())
Once I get the data, if I do json_decode the result is NULL.
It seems that PDO is replacing every " with ".
I have already use PDO and JSON together multiple times, but this is the first time I got this problem so I don't understand what's happening.
I'm on PHP 5.4.4
Also, the JSON is sent with AJAX for your information
Thanks if you can help.
Example of JSON in the table :
{"type_voie":"BD","indice_repetition":"T","num_voie":"121","nom_voie":"NOM_RUE","infos_voie":"NOM_RUE2","distribution_speciale":"BP789","cp":"34000","ville":"MONTPELLIER","bureau_distributeur":""}
What i really see with var_dump :
{"type_voie":"BD","indice_repetition":"T","num_voie":"121","nom_voie":"NOM_RUE","infos_voie":"NOM_RUE2","distribution_speciale":"BP789","cp":"34000","ville":"MONTPELLIER","bureau_distributeur":""}
This is inserted with a prepared query
Code for retrieve DATA :
$formDataSQL = '
SELECT * FROM '.$this->prefix.'
WHERE formalite_id = '.$this->proc_id.'
';
$formDataReq = self::$db->prepare($formDataSQL);
$formDataReq->execute();
$formData = $formDataReq->fetch(PDO::FETCH_ASSOC);
Then on the JSON field :
$addrData = json_decode(str_replace('"', '"', $champ['value']), true); // WORKING BUT NOT MAINTAINABLE
$addrData = json_decode($champ['value'], true); // NOT WORKING => NULL + JSON ERROR = JSON_ERROR_SYNTAX
Here is a simplified example of my insert code :
foreach($saveData['personne_physique'] as $field => $value){
if(is_array($value)) $value = json_encode($value);
$param = ':'.$field;
$fields .= $field.'='.$param.', ';
$values[$param] = $value;
}
$fields = trim($fields, ', ');
$persPhysSQL = "UPDATE personne_physique SET $fields WHERE personne_id = ".$this->id;
$persPhysReq = self::$db->prepare($persPhysSQL);
$persPhysReq->execute($values);
Here is how I'm connecting :
$host = 'mysql:dbname='.BDD_NAME.';host='.BDD_HOST.';charset=utf8';
$user = BDD_USER;
$pass = BDD_PASS;
$db = new PDO($host, $user, $pass, array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8") );
This is really strange :(
Here is my example script based on your data example:
<?php
try {
$Connection = new PDO('mysql:host=localhost;dbname=testing', USER, PASS);
$Connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}catch(PDOException $e){
echo 'Unable to connect to database' . "\n";
}
$id = $argv[1];
try {
$data = $Connection->prepare('SELECT * FROM `stackoverflow_26399231` WHERE ID = :id');
$data->bindParam(':id', $id, PDO::PARAM_INT);
$data->execute();
while($row = $data->fetch(PDO::FETCH_OBJ)){
print_r($row);
print_r(json_decode($row->data));
}
$Connection = null;
}catch(PDOException $e){
echo 'Error executing query: ' . $e->getMessage() . "\n";
}
?>
The database table looks like this:
*************************** 1. row ***************************
id: 1
data: {"type_voie":"BD","indice_repetition":"T","num_voie":"121","nom_voie":"NOM_RUE","infos_voie":"NOM_RUE2","distribution_speciale":"BP789","cp":"34000","ville":"MONTPELLIER","bureau_distributeur":""}
When you run the script in the CLI, you get this back:
stdClass Object (
[id] => 1
[data] => {"type_voie":"BD","indice_repetition":"T","num_voie":"121","nom_voie":"NOM_RUE","infos_voie":"NOM_RUE2","distribution_speciale":"BP789","cp":"34000","ville":"MONTPELLIER","bureau_distributeur":""}
)
stdClass Object (
[type_voie] => BD
[indice_repetition] => T
[num_voie] => 121
[nom_voie] => NOM_RUE
[infos_voie] => NOM_RUE2
[distribution_speciale] => BP789
[cp] => 34000
[ville] => MONTPELLIER
[bureau_distributeur] =>
)
How does my script differ to yours? I'm not able to reproduce the issue.
UPDATE:
My update script following your example:
try {
$Connection = new PDO('mysql:host=localhost;dbname=testing', USER, PASS);
$Connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}catch(PDOException $e){
echo 'Unable to connect to database' . "\n";
}
$id = $argv[1];
$ary = array(
'foo' => 'bar',
'bar' => 'foo',
'a' => 'b',
'c' => 'd',
'e' => 'f'
);
try {
$fields = 'data=:data';
$values = array('data' => json_encode($ary));
$update = $Connection->prepare("UPDATE `stackoverflow_26399231` SET $fields WHERE ID = $id");
$update->execute($values);
$Connection = null;
}catch(PDOException $e){
echo 'Error executing query: ' . $e->getMessage() . "\n";
}
Using the same script to receive as above but changing from PDO::FETCH_OBJ to PDO::FETCH_ASSOC as that's what you're using, I get this output:
Array
(
[id] => 1
[data] => {"foo":"bar","bar":"foo","a":"b","c":"d","e":"f"}
)
stdClass Object
(
[foo] => bar
[bar] => foo
[a] => b
[c] => d
[e] => f
)
So I can still not reproduce the issue you're having. There must be something different between the two scripts.
I have two table ad_post and ad_img . One ad_post row has many images in ad_img. I am trying to execute 2 queries together and than combine at the end. but
table:ad_images
colums (img_id, ad_id, img_name)
table : ad_post
colums(id, user_id, title, price, cat, condit, description, vid)
Relationship
ad_post (1)------>(many)ad_images
public function read_ads()
{
$this;
$this->sql = 'SELECT ad_post.id,ad_post.user_id,ad_post.title,ad_post.price,
sub_cat.s_cat_name,ad_post.condit,ad_post.description,ad_post.vid FROM ad_post,sub_cat
where sub_cat.id=ad_post.cat';
$sql1 = 'SELECT `img_id`,`img_name` FROM `ad_images` WHERE ad_id=?';
$stmt = $this->con->prepare ( $this->sql );
$stmt1 = $this->con->prepare ( $sql1 );
if ($stmt === false) {
trigger_error ( 'Wrong SQL: ' . $sql . ' Error: ' . $conn->error, E_USER_ERROR );
}
// STMT
$stmt->execute ();
$stmt->store_result ();
$stmt->bind_result ( $id, $uId, $title, $price, $cat, $usage, $desc, $vid );
// STMT1
// $ad =AdPost::__getAll('','','','','','','','');
// $ad = Array();
$img = Array ();
$count = 0;
$count = 0;
$ads_img = Array ();
$a_img = Array ();
while ( $stmt->fetch () != NULL ) {
$stmt1->bind_param ( 'i', $id );
$stmt1->execute ();
$stmt1->store_result ();
$stmt1->bind_result ( $img_id, $img_name );
while ( $stmt1->fetch () != NULL ) {
echo $img_id;
$a_img = Array (
'img_id' => $img_id,
'img_name' => $img_name
);
try {
$ads_img [$count] = $a_img;
} catch ( Exception $exc ) {
echo $exc->getTraceAsString ();
}
}
$count ++;
$ad_set = Array (
'id' => $id,
'uid' => $uId,
'title' => $title,
'price' => $price,
'cat' => $cat,
'usage' => $usage,
'desc' => $desc,
'img_name' => $a_img
);
try {
$ads [$count] = $ad_set;
} catch ( Exception $exc ) {
echo $exc->getTraceAsString ();
}
$count ++;
}
$stmt->free_result ();
$stmt->close ();
return $ads;
}
I have got the ids of ads now i want to save imgs in array of $ad_set
The values of image array are returning null