There is likely a few other ways to do this but this is more or less the method I have used on the odd occasion - you will need to study this and adapt/adopt to fit your needs.
/* Some source data - field name to value */
$data=array(
'child_id' => 23,
'parent_id' => 1,
'path' => 'banana',
'page' => 1,
'menuitem' => 1,
'menutext' => 'some text',
'active' => 1
);
$keys = array_keys( $data );
/* temp arrays */
$tmp=array();
$params=array();
$types=array();
$placeholders=array();
/*
There are 4 types of placeholders but this does only 2
You can probably do some testing of data values using gettype
to make this more dynamic and allow for the other placeholder
types.
*/
foreach( $data as $item ){
$types[] = is_string( $item ) ? 's' : 'i';
$placeholders[]='?';
}
$params[]=implode( '', &$types ); #ie: ississi etc as 1st element
/* create params array - fields */
foreach( $data as $item ){
$params[]=$item;
}
/* create the actual values to be passed by ref */
foreach( $params as $key => $value )$tmp[ $key ]=&$params[ $key ];
/* construct sql statement */
$sql=sprintf('insert into `customers` ( `%s` ) values ( %s )', implode( '`,`', $keys ), implode( ',', $placeholders ) );
/* to debug/preview */
echo $sql.BR;
$dbhost = 'localhost';
$dbuser = 'root';
$dbpwd = 'xxx';
$dbname = 'xxx';
$db = new mysqli( $dbhost, $dbuser, $dbpwd, $dbname );
$stmt=$db->prepare( $sql );
if( $stmt ){
call_user_func_array( array( $stmt, 'bind_param' ), $tmp );
$result = $stmt->execute();
echo $result ? 'ok' : 'not ok';
}
Quickly hashing that together into a couple of functions
function prepareparams( $options=array() ){
try{
if( !empty( $options ) ){
$values=array();
$params=array();
$types=array();
$placeholders=array();
$keys = array_keys( $options );
foreach( $options as $item ){
$types[] = is_string( $item ) ? 's' : 'i';
$placeholders[]='?';
}
$params[]=implode( '', &$types ); #ie: ississi etc as 1st element
/* create params array - fields */
foreach( $options as $item ){
$params[]=$item;
}
/* create the actual values to be passed by ref */
foreach( $params as $key => $value )$values[ $key ]=&$params[ $key ];
return (object)array(
'params' => $params,
'values' => $values,
'placeholders' => $placeholders,
'keys' => $keys
);
} else {
throw new Exception('Bad Foo');
}
}catch( Exception $e ){
echo $e->getMessage();
}
}
function preparesql( $table=false, $obj=object ){
return sprintf('insert into `%s` ( `%s` ) values ( %s )', $table, implode( '`,`', $obj->keys ), implode( ',', $obj->placeholders ) );
}
You could then call it like this
$obj=prepareparams( $data );
$sql=preparesql( 'customers', $obj );
$stmt=$db->prepare( $sql );
if( $stmt ){
call_user_func_array( array( $stmt, 'bind_param' ), $obj->values );
$result = $stmt->execute();
echo $result ? 'ok' : 'not ok';
}
As a fully working demo of using dynamic query building in mysqli consider the following
/*
A table of some sort for testing porpoises
create the table as the first stage!!
*/
create table `testtable` (
`id` int(10) unsigned not null auto_increment,
`login` varchar(50) not null default '0',
`db` varchar(50) not null default '0',
`dr` varchar(50) not null default '0',
`status` tinyint(3) unsigned not null default '0',
`admin_ishop` int(10) unsigned not null default '0',
`lasteditdate` datetime null default null,
primary key (`id`)
)
collate='utf8_general_ci'
engine=innodb;
/* From commandline */
mysql> create table `testtable` (
-> `id` int(10) unsigned not null auto_increment,
-> `login` varchar(50) not null default '0',
-> `db` varchar(50) not null default '0',
-> `dr` varchar(50) not null default '0',
-> `status` tinyint(3) unsigned not null default '0',
-> `admin_ishop` int(10) unsigned not null default '0',
-> `lasteditdate` datetime null default null,
-> primary key (`id`)
-> )
-> collate='utf8_general_ci'
-> engine=innodb;
mysql> describe `testtable`;
+--------------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+---------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| login | varchar(50) | NO | | 0 | |
| db | varchar(50) | NO | | 0 | |
| dr | varchar(50) | NO | | 0 | |
| status | tinyint(3) unsigned | NO | | 0 | |
| admin_ishop | int(10) unsigned | NO | | 0 | |
| lasteditdate | datetime | YES | | NULL | |
+--------------+---------------------+------+-----+---------+----------------+
On the PHP side of things
/* a mysqli connection to whatever database */
$dbhost = 'localhost';
$dbuser = 'root';
$dbpwd = 'xxx';
$dbname = 'xxx';
$db = new mysqli( $dbhost, $dbuser, $dbpwd, $dbname );
/* Some pseudo-random source data - `field` name to `value` */
$data=array(
'login' => uniqid('user_'),
'db' => uniqid('db_'),
'dr' => rand(10,99),
'status' => rand(0,1),
'admin_ishop' => rand(0,1),
'lastEditDate' => date('Y-m-d H:i:s')
);
function type( $value ){
switch( gettype( $value ) ){
case 'string':return 's';
case 'integer':return 'i';
case 'double':
case 'float':return 'd';
case 'object':return 'b';
default:return false;
}
}
function prepareparams( $options=array() ){
try{
if( !empty( $options ) ){
$values=array();
$params=array();
$types=array();
$placeholders=array();
$keys = array_keys( $options );
foreach( $options as $item ){
$types[] = type( $item ) ? type( $item ) : 's';
$placeholders[]='?';
}
$params[]=implode( '', &$types ); #ie: ississi etc as 1st element
/* create params array - fields */
foreach( $options as $item ){
$params[]=$item;
}
/* create the actual values to be passed by ref */
foreach( $params as $key => $value )$values[ $key ]=&$params[ $key ];
return (object)array(
'params' => $params,
'values' => $values,
'placeholders' => $placeholders,
'keys' => $keys
);
} else {
throw new Exception('Bad Foo');
}
}catch( Exception $e ){
echo $e->getMessage();
}
}
function preparesql( $table=false, $obj=object ){
return sprintf('insert into `%s` ( `%s` ) values ( %s )', $table, implode( '`,`', $obj->keys ), implode( ',', $obj->placeholders ) );
}
/* calling the functions to build and execute the sql */
$obj=prepareparams( $data );
$sql=preparesql( 'testtable', $obj );
$stmt=$db->prepare( $sql );
if( $stmt ){
call_user_func_array( array( $stmt, 'bind_param' ), $obj->values );
$result = $stmt->execute();
echo $result ? sprintf( 'Record Inserted: %d', $db->insert_id ) : sprintf( 'Bad Foo! %s', $db->error );
}
After a few runs of the script, a quick cmdline query
mysql> select * from testtable;
+----+--------------------+------------------+----+--------+-------------+---------------------+
| id | login | db | dr | status | admin_ishop | lasteditdate |
+----+--------------------+------------------+----+--------+-------------+---------------------+
| 1 | user_5a5e5e2a23dcd | db_5a5e5e2a23dd1 | 44 | 1 | 1 | 2018-01-16 20:18:50 |
| 2 | user_5a5e5e2c072b4 | db_5a5e5e2c072b8 | 33 | 1 | 0 | 2018-01-16 20:18:52 |
| 3 | user_5a5e605a0b224 | db_5a5e605a0b229 | 32 | 0 | 0 | 2018-01-16 20:28:10 |
| 4 | user_5a5e605b0ef33 | db_5a5e605b0ef38 | 87 | 1 | 1 | 2018-01-16 20:28:11 |
| 5 | user_5a5e605b8bf4f | db_5a5e605b8bf54 | 85 | 1 | 1 | 2018-01-16 20:28:11 |
+----+--------------------+------------------+----+--------+-------------+---------------------+