hi guys here is my update function it takes some parameters and eveluates them if they are integer or string after that process the values and throws for query sentence...
public function update ($table, $cols, $values, $addition) {
$db = $this->connect();
$i = 0;
$update = '';
if ((is_array($cols)) && (is_array($values))) {
foreach ($cols as $a) {
if (!is_int($values[$i])) {
$update = $a.'="'.$values[$i].'",';
} else {
$update = $a.'='.$values[$i].',';
}
$i++;
}
$update = substr($update, 0, -1);
} else {
if (!is_int($values)) {
$update = $cols.'="'.$values.'",';
} else {
$update = $cols.'='.$values.',';
}
}
echo "update ".$table." set ".$update." ".$addition."<br>";
try {
$sql = $db->prepare("update ".$table." set ".$update." ".$addition);
$sql->execute();
} catch (PDOException $e) {
print $e->getMessage();
}
$db = null;
}
and here are the parameters and the sql query
$this->db->update("brands", "car_count", $brandCarCount[0]+1, "where brand = '".$brand."'");
update brands set car_count=2, where brand = 'alfa_romeo'
i really do not understand what happens, i can not find the problem. it works for other inserting selecting or deleting functions.
i need help!
That is the relevant line which removes the trailing comma:
$update = rtrim($update,',');
and this is the full code:
public function update ($table, $cols, $values, $addition) {
$db = $this->connect();
$i = 0;
$update = '';
if ((is_array($cols)) && (is_array($values))) {
foreach ($cols as $a) {
if (!is_int($values[$i])) {
$update = $a.'="'.$values[$i].'",';
} else {
$update = $a.'='.$values[$i].',';
}
$i++;
}
} else {
if (!is_int($values)) {
$update = $cols.'="'.$values.'",';
} else {
$update = $cols.'='.$values.',';
}
}
$update = rtrim($update,',');
echo "update ".$table." set ".$update." ".$addition."<br>";
try {
$sql = $db->prepare("update ".$table." set ".$update." ".$addition);
$sql->execute();
} catch (PDOException $e) {
print $e->getMessage();
}
$db = null;
}
I have a query and it looks like:
if (strlen($search->q)) {
$where[] = ' AND (`name` LIKE :q)';
$arr['q'] = "%" . $search->q . "%";
}
$sql = 'SELECT
*,
FROM
`shop_products`
WHERE
1=1
'.implode('', $where);
Not I'm trying to get products from DB:
$result->products = $db->query($sql, $arr, $search->limitstart, $search->limit)->fetchAll();
My query function:
public function query($sql, $params=array(), $offset = null, $limit = null){
if (!is_null($offset) && !is_null($limit)) {
$sql .= ' LIMIT :limit OFFSET :offset';
$params['limit'] = (int)$limit;
$params['offset'] = (int)$offset;
}
$stmt = $this->database->prepare($sql);
if (!empty($params)) {
foreach($params as $key => $value) {
if(is_int($value)) {
$param = PDO::PARAM_INT;
} elseif(is_bool($value)) {
$param = PDO::PARAM_BOOL;
} elseif(is_null($value)) {
$param = PDO::PARAM_NULL;
} elseif(is_string($value)) {
$param = PDO::PARAM_STR;
} else {
$param = false;
}
if($param) $stmt->bindValue(":$key", $value, $param);
}
}
$stmt->execute();
return $stmt;
}
My problem that LIKE instruction does not work. How can I solve this problem and fix my code?
I have a class 'DB' of which i have taken from an online tutorial. It has some SELECT queries but not INSERT.
Its worked really well so far but i would like to develop it further for future use.
class DB {
private static $_instance = null;
private $_pdo,
$_query,
$_error = false,
$_errorMsg,
$_results,
$count = 0;
private function __construct(){
try{
$this->_pdo = new PDO('mysql:host=' . Config::get('mysql/host') . ';dbname=' . Config::get('mysql/db'), Config::get('mysql/username'), Config::get('mysql/password'));
}catch(PDOException $e){
die($e->getMessage());
}
}
public static function getInstance() {
if(!isset(self::$_instance)) {
self::$_instance = new DB();
}
return self::$_instance;
}
public function query($sql, $params = array()) {
$this->_error = false;
if($this->_query = $this->_pdo->prepare($sql)) {
$x = 1;
if(count($params)) {
foreach($params as $param){
$this->_query->bindValue($x, $param);
$x++;
}
}
if($this->_query->execute()) {
$this->_results = $this->_query->fetchAll(PDO::FETCH_OBJ);
$this->_count = $this->_query->rowCount();
} else {
// return error & write to log
$this->_error = true;
//get Error message and save to log
$errormsg = $this->_query->errorInfo();
$message = date('l jS \of F Y h:i:s A') . "\n";
$message .= 'Invalid query: ' . $errormsg[2] . "\n";
$message .= 'Whole query: ' . $sql . "\n";
$message .= '------------------------------------------------------' . "\n";
$this->createLog($message);
$this->_errorMsg = $errormsg[2];
}
}
return $this;
}
public function action($action, $table, $where = array(), $and = array()) {
if(count($where) === 3){
$operators = array('=', '>', '<', '>=', '<=');
$field = $where[0];
$operator = $where[1];
$value = $where[2];
// Check if AND is set
$and = array_filter($and);
if ( !empty($and) && $and != '' ) {
$andOR = $and[0];
$andField = $and[1];
$andFieldOperator = $and[2];
$andValue = $and[3];
if(in_array($operator, $operators)) {
$sql = "{$action} FROM {$table} WHERE {$field} {$operator} ? {$andOR} `{$andField}` {$andFieldOperator} '{$andValue}'";
if( !$this->query($sql, array($value) )->error()) {
//print_r( $this->query($sql, array($value)));
return $this;
} else {
print_r('ERROR: Check error log - Click here');
}
}
} else {
if(in_array($operator, $operators)) {
$sql = "{$action} FROM {$table} WHERE {$field} {$operator} ?";
if( !$this->query($sql, array($value) )->error()) {
return $this;
} else {
print_r('ERROR: Check error log - Click here');
}
}
}
} else {
$sql = "{$action} FROM {$table}";
if( !$this->query($sql )->error()) {
return $this;
}
}
return false;
}
How can i add a function 'INSERT' for adding data to my database using PDO prepare?
This question already has an answer here:
Mysqli prepared statements build INSERT query dynamically from array
(1 answer)
Closed 6 months ago.
<?php
$files=array(name1,name2,name3,);
$conn = new mysqli($host, $user, $pass, $name);
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "INSERT INTO parmi_files (name)
VALUES ('$files')"; ///// -problem is here
if ($conn->query($sql) === TRUE) {
echo "New record created successfully";
} else {
echo "Error: " . $sql . "<br>" . $conn->error;
}
?>
I want to insert each value from array to MySql row, please solve it out.
Iterate through the items in the array and add them individually:
foreach ($arrayWithValues as $key=>$value) {
$sql = "INSERT INTO parmi_files (name) VALUES ('$value')";
mysqli_query($conn, $sql);
}
Something like this to insert multiple records at once:
$files = array('name1', 'name2', 'name3');
// ...
$filesMap = implode(',', array_map(function($value) {
return "('" . $conn->real_escape_string($value) . "')";
}, $files));
$sql = "INSERT INTO parmi_files (name) VALUES $filesMap";
You could use a PDO abstraction layer for this
I have made a class for this in the past
It uses: PDO, bound parameters, prepared statements
and it inserts everything in one sql query and the insert looks like this:
$db->insertRows('test_table', $default_row, $rows);
The full code
(which might seem a bit long, but makes sense if you read it) including the code for the connection would look like:
<?php
// Establish connection (on demand)
$db = new PdoHelper(function(){
$db_server = 'localhost';
$db_port= '3306';
$db_name = 'your_database';
$db_user = 'your_username';
$db_pass = 'your_password';
$dsn = 'mysql:host='.$db_server.';dbname='.$db_name.';port='.$db_port;
$driver_options = array(
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8'",
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
);
$dbh = new PDO( $dsn, $db_user, $db_pass, $driver_options );
return $dbh;
});
// Make a blank sample to have default values for row keys
$default_row = array(
'a'=>null,
'b'=>null,
'c'=>null,
);
// The rows that we want to insert, with columns in the wrong order and nonsense
$rows = array(
array(
'b'=>'a2',
'c'=>'a3',
),
array(
'c'=>'b3',
'b'=>'b2',
),
array(
'b'=>'c2',
'c'=>'c3',
'nonsense'=>'boo',
),
);
// The actual insert query
// INSERT INTO `test_table` (`a`,`b`,`c`) VALUES (null,'a2','a3'), (null,'b2','b3'), (null,'c2','c3')
$db->insertRows('test_table', $default_row, $rows);
// The class that does it all
class PdoHelper {
private $db, $factory;
public function __construct($factory)
{
$this->factory = $factory;
}
public function connect()
{
$cb = $this->factory;
$this->db = $cb();
}
public function release()
{
$this->db = null;
}
public function implyConnect()
{
if(!$this->db){
$this->connect();
}
}
public function begin()
{
$this->implyConnect();
if($this->db instanceof PDO){
$this->db->beginTransaction();
}
}
public function commit()
{
$this->implyConnect();
if($this->db instanceof PDO){
$this->db->commit();
}
}
public function prepare($sql, $data=null, $callback=null)
{
$err = null;
$flat_data = array();
if($data){
$flat_data = self::flatten($data);
$sql = preg_replace_callback('/\?/isu', function($v) use (&$data) {
$val = array_shift($data);
if(is_array($val)){
return self::arrayToPlaceholder($val);
}
return '?';
}, $sql);
}
$this->implyConnect();
if($this->db instanceof PDO){
$stmt = $this->db->prepare($sql);
if($stmt instanceof PDOStatement){
$i = 1;
foreach($flat_data as $v) {
if(is_int($v)){
// workaround for a PDO bug with LIMIT ?,?
$stmt->bindValue($i++, $v, PDO::PARAM_INT);
}else{
$stmt->bindValue($i++, $v, PDO::PARAM_STR);
}
}
}
}
if($callback){
return call_user_func_array($callback, array($stmt));
}
return $stmt;
}
public function query($sql)
{
$res = false;
$args = func_get_args();
$data = array();
$callback = null;
if(isset($args[2])){
$data = $args[1];
$callback = $args[2];
}else
if(isset($args[1])){
if(is_callable($args[1])){
$callback = $args[1];
}else{
$data = $args[1];
}
}
$this->implyConnect();
$stmt = $this->prepare($sql, $data);
$res = $stmt->execute();
if($res && $callback && is_callable($callback)){
return call_user_func_array($callback, array($stmt, $this->db));
}
return $stmt;
}
// Helper functions
public function insertRows($table, $default, $rows=array(), $flag=null, $chunk_size=500)
{
if(empty($rows)){
return null;
}
$chunks = array_chunk($rows, $chunk_size);
foreach($chunks as $rows){
$data = array();
$data[] = $this->extend($default, $rows);
// http://stackoverflow.com/questions/1542627/escaping-column-names-in-pdo-statements
$flag = strtolower($flag);
$flags = array(
'ignore'=>'INSERT IGNORE INTO ',
'replace'=>'REPLACE INTO ',
);
$cols = array();
foreach($default as $k=>$v){
$k = str_replace('`', '``', $k);
$cols[] = '`'.$k.'`';
}
$sql = (isset($flags[$flag])?$flags[$flag]:'INSERT INTO ').$table.' ('.implode(',', $cols).') VALUES ?';
if($flag==='update'){
$cols = array();
foreach($default as $k=>$v){
$k = str_replace('`', '``', $k);
$cols[] = '`'.$k.'`=VALUE('.$k.')';
}
$sql .= ' ON DUPLICATE KEY UPDATE '.implode(', ', $cols);
}
$res = $this->query($sql, $data);
if(!$res){
return $res;
}
}
return $res;
}
public function insertRow($table, $default, $row, $flag=null)
{
$rows = array($row);
return $this->insertRows($table, $default, $rows, $flag);
}
// Helper functions
public static function extend($set, $rows)
{
foreach($rows as $k=>$v){
$v = array_intersect_key($v, $set);
$rows[$k] = array_replace($set, $v);
}
return $rows;
}
public static function flatten($x)
{
$d = array();
if(is_array($x)){
foreach($x as $k=>$v){
$d = array_merge($d, self::flatten($v));
}
}else{
$d[] = $x;
}
return $d;
}
public static function arrayToPlaceholder($array, $timeZone=null) {
return implode(',', array_map(function($v) use($timeZone){
if(is_array($v)){
return '('.self::arrayToPlaceholder($v, $timeZone).')';
}
return '?';
}, $array));
}
public function arrayToList($array, $timeZone=null) {
return implode(',',array_map(function($v) use($timeZone){
if(is_array($v)){
return '('.self::arrayToList($v, $timeZone).')';
}
$this->implyConnect();
return $this->escape($v);
},$array));
}
public function escape($val, $stringifyObjects=false, $timeZone=false) {
if(is_null($val)) return 'NULL';
if(is_bool($val)) return ($val) ? 'true' : 'false';
if(is_int($val)) return (string)$val;
if(is_float($val)) return (string)$val;
if (is_array($val)) {
return $this->arrayToList($val, $timeZone);
}
if(is_callable($val)){ return null; } // TODO
$val = preg_replace_callback('/[\0\n\r\b\t\\\'\"\x1a]/um', function($s) {
switch($s) {
case "\0": return "\\0";
case "\n": return "\\n";
case "\r": return "\\r";
case "\b": return "\\b";
case "\t": return "\\t";
case "\x1a": return "\\Z";
default: return "\\".$s;
}
}, $val);
return $this->db->Quote($val);
}
// Debug functions
public function getSQL($sql, $data){
foreach($data as $k=>$v){
if(is_array($v)){
$data[$k] = self::arrayToList($v);
}else{
$this->implyConnect();
$data[$k] = $this->escape($v);
}
}
$sql = preg_replace_callback('/\?/', function($match) use(&$data)
{
return array_shift($data);
}, $sql);
return $sql;
}
}
Here is how a wrapper looks like:
<?php
Class mysqliwrapper{
protected $_mysqli;
protected $_debug;
public function __construct($host, $username, $password, $database, $debug) {
$this->_mysqli = new mysqli($host, $username, $password, $database);
$this->_debug = (bool) $debug;
if (mysqli_connect_errno()) {
if ($this->_debug) {
echo mysqli_connect_error();
debug_print_backtrace();
}
return false;
}
return true;
}
public function q($query) {
if ($query = $this->_mysqli->prepare($query)) {
if (func_num_args() > 1) {
$x = func_get_args();
$args = array_merge(array(func_get_arg(1)),
array_slice($x, 2));
$args_ref = array();
foreach($args as $k => &$arg) {
$args_ref[$k] = &$arg;
}
call_user_func_array(array($query, 'bind_param'), $args_ref);
}
$query->execute();
if ($query->errno) {
if ($this->_debug) {
echo mysqli_error($this->_mysqli);
debug_print_backtrace();
}
return false;
}
if ($query->affected_rows > -1) {
return $query->affected_rows;
}
$params = array();
$meta = $query->result_metadata();
while ($field = $meta->fetch_field()) {
$params[] = &$row[$field->name];
}
call_user_func_array(array($query, 'bind_result'), $params);
$result = array();
while ($query->fetch()) {
$r = array();
foreach ($row as $key => $val) {
$r[$key] = $val;
}
$result[] = $r;
}
$query->close();
return $result;
} else {
if ($this->_debug) {
echo $this->_mysqli->error;
debug_print_backtrace();
}
return false;
}
}
public function handle() {
return $this->_mysqli;
}
}
?>
This works fine:
$w = new mysqliwrapper("localhost","root","","testdb",1);
$r = $w->q("SELECT * FROM `testdb_news` WHERE `id`=? AND `lang`=?","is",16,'en');
However, this does not:
$r = $w->q("INSERT INTO `testdb_news` ('lang','title','content','date') VALUES (?,?,?,?)","ssss","en","NewTitle","NewContent",mktime());
Why? Should I be using ?-s only for SELECT statements? And go for insert like this?
$r = $w->q("INSERT INTO `testdb_news` (lang,title,content,date) VALUES ('en','newTitle','newContent','".mktime()."')");
Is this secure? Is this class actually secure? Thanks!
safe against injections. see this question which has similar questions Parameterized Query