I have the following code in an application I'm building and to be honest... it feels like a great deal of pain when I want to change something like this. I've always had this problem with SQL in code but never understood how to address it. Is there some way or common practice that would make the SQL here a bit easier to maintain and change? (I've read not to use stored procedures)
$stmt_arr = array(
':steamid' => isset($playerSummary['steamid']) ? $playerSummary['steamid'] : "",
':personaname' => isset($playerSummary['personaname']) ? utf8_encode($playerSummary['personaname']) : "",
':community_vis_state' => isset($playerSummary['communityvisibilitystate']) ? $playerSummary['communityvisibilitystate'] : "",
':profile_state' => isset($playerSummary['profilestate']) ? $playerSummary['profilestate'] : "NULL",
':profile_url' => isset($playerSummary['profileurl']) ? $playerSummary['profileurl'] : "",
':avatar_url' => isset($playerSummary['avatar']) ? $playerSummary['avatar'] : "",
':avatar_medium' => isset($playerSummary['avatarmedium']) ? $playerSummary['avatarmedium'] : "",
':avatar_full' => isset($playerSummary['avatarfull']) ? $playerSummary['avatarfull'] : "",
':shallow_update' => $isFriend
);
$stmt = $this->DBH->prepare("INSERT INTO `user`(`steamid`, `personaname`, `community_visibility_state`, "
. "`profile_state`, `profile_url`, `avatar_url`, `avatar_medium_url`, `avatar_full_url`, `last_updated`, `shallow_update`)"
. " VALUES (:steamid, :personaname, :community_vis_state, :profile_state, :profile_url, "
. ":avatar_url, :avatar_medium, :avatar_full, NOW(), :shallow_update) "
. "ON DUPLICATE KEY UPDATE `steamid` = VALUES(`steamid`), "
. "`personaname` = VALUES(`personaname`), "
. "`community_visibility_state` = VALUES(`community_visibility_state`), "
. "`profile_state` = VALUES(`profile_state`), "
. "`profile_url` = VALUES(`profile_url`), "
. "`avatar_url` = VALUES(`avatar_url`), "
. "`avatar_medium_url` = VALUES(`avatar_medium_url`), "
. "`avatar_full_url` = VALUES(`avatar_full_url`), "
. "`last_updated` = VALUES(`last_updated`),"
. "`shallow_update` = VALUES(`shallow_update`)");
$stmt->execute($stmt_arr);
Use this function
function pdo_insert($con, $table, $data_arr)
{
if (!is_array($data_arr) || !count($data_arr)) return false;
$bind = ':'.implode(',:', array_keys($data_arr));
$sql = 'INSERT into '.$table.'('.implode(',', array_keys($data_arr)).') '.
'values ('.$bind.')';
$stmt = $con->prepare($sql);
$status = $stmt->execute(array_combine(explode(',',$bind), array_values($data_arr)));
if($status)
{
// success
$msg = 'Data added to database successfully';
return $msg;
}
else
{
// failure
$msg = 'Error in adding data into database';
return $msg;
}
}
Calling the function
$msg = pdo_insert($db, 'table name here', $_POST);
// see the result
echo $msg;
function generateSQL($table, $arr) {
$sql = "INSERT INTO ".$table . " (";
foreach($arr as $k => $v) {
$sql .= "`".substr_replace($k, "", 0, 1)."`, ";
}
$sql = substr_replace($sql, "", -2);
$sql .= ") VALUES (";
foreach($arr as $k => $v) {
$sql .= $k.", ";
}
$sql = substr_replace($sql, "", -2);
$sql .= ") ON DUPLICATE KEY UPDATE ";
foreach($arr as $k => $v) {
$sql .= "`".substr_replace($k, "", 0, 1)."` = VALUES(`".substr_replace($k, "", 0, 1)."`), ";
}
$sql = substr_replace($sql, "", -2);
return $sql;
}
print_r(generateSQL("user", $stmt_arr));
Where did you read not to use stored procedure ?
They are the solution to your problem, when queries get complex, it is better to move the logic to a sotored procedure and just execute it (e.g CALL sp_isnert_user ?, ?)
They also allow you to maintain/modify your SQL logic without really touching your code.
Related
So I am trying to make an undetermined amount of bindParam calls within a foreach, but for some reason it fails. I know the $sql variable is working fine, but I am pretty sure it is failing at the bindParam. Is there any reason for this?
$sql = "INSERT INTO " . $row1["rand"] . " (" . $areas . ") VALUES (" . $vals . ")";
echo $sql;
$entry2 = $conn->prepare("'".$sql."'");
//echo "swag";
foreach($splitHeader as $element){
if(strlen($element)>0) {
$thisVal = "':" . $element . "'";
$entry2->bindParam($thisVal,$_POST[$element]);
}
}
$entry2->execute();
The number of parameters that you define in the query must match the number of parameters that you bind.
You would need to loop twice trough your data : once to dynamically construct a sql statement (that you can then prepare), and then a second time to bind the parameters, before finally calling execute.
Here is an adaptation of your code that demonstrates the principle :
$cols = "";
$vals = "";
foreach( $splitHeader as $element ) {
if( strlen($element) > 0 ) {
if ( strlen($cols) > 0 ) {
$cols .= ", ";
$vals .= ", ";
}
$cols .= $element;
$vals .= "?";
}
}
$sql = "INSERT INTO " . $row1["rand"] . " (". $cols . ") VALUES(". $vals . ")";
echo $sql;
$sth = $conn->prepare($sql);
$i = 1;
foreach($splitHeader as $element){
if( strlen($element) > 0 ) {
$sth->bindParam( $i, $_POST[$element] );
$i++;
}
}
$sth->execute();
I'm newbie with PHP and JSON. I have a script that collects data from an JSON API and stores it in to MySQL data-base.
Script is working fine but I have a problem collecting specific array data.
This is the script :
<?php
$url="";
$db_name=" ";
$db_server=" ";
$db_user=" ";
$db_password="";
$newline=PHP_EOL;
$mysqli = new mysqli($db_server,$db_user, $db_password, $db_name);
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}else{
echo "You are connected to the database ($db_name)" . $newline;
}
echo "Initial character set: ". $mysqli->character_set_name(). $newline;
if (!$mysqli->set_charset("utf8")) {
echo "Error loading character set utf8: ", $mysqli->error. $newline;
exit();
} else {
echo "Current character set: ", $mysqli->character_set_name(). $newline;
}
$json = file_get_contents($url . '1}');
$obj = json_decode(utf8_encode($json));
$totalPages=$obj->totalPages;
//read page
for($i = 1; $i < $totalPages ; $i++) {
echo "Read URL " . $url . $i . '}'. $newline;
$json = file_get_contents($url . $i . '}');
$obj = json_decode($json);
foreach($obj->items as $item){
$id = $item->id;
$Name=$item->name;
$FirstName = $item->firstName;
$LastName = $item->lastName;
$attributes = $item->attributes;
foreach($attributes as $attribute){
if ($attribute->name=="fut.attribute.DIV"){
$DIV = $attribute->value;
}
if ($attribute->name=="fut.attribute.POS"){
$POS = $attribute->value;
}
}
$r = $mysqli->query("SELECT id FROM DATABAS WHERE id=". $id);
if ($r->num_rows <= 0){ //INSERT
$query = "INSERT INTO DATABASE ( ";
$query.= "`id` , ";
$query.= "`Name` , ";
$query.= "`FirstName` , ";
$query.= "`LastName` , ";
$query.= "`DIV` ,";
$query.= "`POS` ) VALUES (";
$query.= $id . " , ";
$query.= "'" . $Name . "' , ";
$query.= "'" . $FirstName . "' , ";
$query.= "'" . $LastName . "' , ";
$query.= "'" . $DIV. "' , ";
$query.= "'" . $POS. "' ";
$query.= ");";
$mysqli->query($query);
echo "Last Name inserted was: " . $Name . $newline;
}else{ //UPDATE
$query = "UPDATE database ";
$query.= "SET `Name` ='".$Name."' , ";
$query.= "`FirstName` ='".$FirstName."' , ";
$query.= "`LastName` ='".$LastName."' , ";
$query.= "`DIV`='".$DIV."' , ";
$query.= "`POS`='".$POS."' ";
$query.= "WHERE id=".$id;
$mysqli->query($query);
echo "Last ID update was: " . $_id . $newline;
}
}
}
$mysqli->close();
function replace_unicode_escape_sequence($match) {
return mb_convert_encoding(pack('H*', $match[1]), 'UTF-8', 'UCS-2BE');
}
function unicode_decode($str) {
return preg_replace_callback('/\\\\u([0-9af]{4})/i', 'replace_unicode_escape_sequence', $str);
}
The Json data which I like to add is Traits "traits" and Specialties specialities. Data is stored with [] and I simply have now idea how to read it.
Attributes are stored likewise but have fixed names to point to.
This is partial Json data:
,"position":"RW","playStyle":"Basic","playStyleId":null,"height":170,"weight":72,"birthdate":"1987-06-24","age":29,"acceleration":99,"aggression":58,"agility":95,"balance":98,"ballcontrol":99,"foot":"Left","skillMoves":4,"crossing":90,"curve":99,"dribbling":99,"finishing":99,"freekickaccuracy":99,"gkdiving":6,"gkhandling":11,"gkkicking":15,"gkpositioning":14,"gkreflexes":8,"headingaccuracy":99,"interceptions":36,"jumping":82,"longpassing":89,"longshots":97,"marking":21,"penalties":82,"positioning":99,"potential":95,"reactions":95,"shortpassing":99,"shotpower":89,"slidingtackle":35,"sprintspeed":96,"standingtackle":38,"stamina":91,"strength":71,"vision":99,"volleys":94,"weakFoot":4,"traits":["Shooting - Finesse Shot","Dribbler - Speed Dribbler","One Club Player","Ultimate Professional"],"specialities":["Speedster","Dribbler","Distance Shooter","Crosser","FK Specialist","Acrobat","Clinical Finisher","Complete Forward","Poacher"],"atkWorkRate":"Medium","defWorkRate":"Low","playerType":"TEAM OF THE YEAR","attributes":[{"name":"fut.attribute.PAC","value":99,"chemistryBonus":[0]},{"name":"fut.attribute.SHO","value":98,"chemistryBonus":[0]},{"name":"fut.attribute.PAS","value":97,"chemistryBonus":[0]},{"name":"fut.attribute.DRI","value":99,"chemistryBonus":[0]},{"name":"fut.attribute.DEF","value":40,"chemistryBonus":[0]},{"name":"fut.attribute.PHY","value":75,"chemistryBonus":[0]}],"name":"Messi","quality":"gold","color":"toty","isGK":false,"positionFull":"Right
I really hoop some can help me. I try to find the solution myself but the solutions I have seen don’t correspond with the used code and my lack of knowledge on the subject is limiting me to implement it myself.
Or if you are using MySQL 5.7 just have a column in the table of data type JSON and just write the JSON object or array into it.
$arr = json_decode($json_obj,true);//decode object
foreach($arr as $ar){
$id = $ar["id"];
$name = $ar["name"];
$system_id = $ar["system_id"];
$max_landing_pad_size = $ar["max_landing_pad_size"];
$distance_to_star = $ar["distance_to_star"];
$faction = $ar["faction"];
$government = $ar["government"];
$allegiance = $ar["allegiance"];
$state = $ar["state"];
$type = $ar["type"];
$has_blackmarket = $ar["has_blackmarket"];
$has_commodities = $ar["has_commodities"];
$has_refuel = $ar["has_refuel"];
$has_repair = $ar["has_repair"];
$has_rearm = $ar["has_rearm"];
$has_outfitting = $ar["has_outfitting"];
$has_shipyard = $ar["has_shipyard"];
//insert values into mysql database
$sql="INSERT INTO stations (station_id, name, system_id, max_landing_pad_size, distance_to_star, faction, government, allegiance, state, type, has_blackmarket, has_commodities, has_refuel, has_repair, has_rearm, has_outfitting, has_shipyard)
VALUES ('$id', '$name', '$system_id', '$max_landing_pad_size', '$distance_to_star', '$faction', '$government', '$allegiance', '$state', '$type', '$has_blackmarket', '$has_commodities', '$has_refuel', '$has_repair', '$has_rearm', '$has_outfitting', '$has_shipyard')";
if(!mysql_query($sql,$con)) //$con is mysql connection object
{
die('Error : ' . mysql_error());
}
}
Let's say i have and array like this
$array= Array('id'=>'3', 'name'=>'NAME', 'age'=>'12');
Keys from this array are name of columns in table and values are value of columns which i need to update.
I want to update the table based on keys and values.
I am using ADODB
Please help me
try this:
$sql = "UPDATE table SET ";
foreach($array as $key=>$value) {
$sql .= $key . " = " . $value . ", ";
}
$sql = trim($sql, ' '); // first trim last space
$sql = trim($sql, ','); // then trim trailing and prefixing commas
and of course the WHERE clause:
$sql .= " WHERE condition = value";
you will get the string:
UPDATE table SET id = 3, name = NAME, age = 12 WHERE condition = value
L.E: You might need to add apostrophes to strings so I have to change my code to something like this:
$sql = "UPDATE table SET ";
foreach($array as $key=>$value) {
if(is_numeric($value))
$sql .= $key . " = " . $value . ", ";
else
$sql .= $key . " = " . "'" . $value . "'" . ", ";
}
$sql = trim($sql, ' '); // first trim last space
$sql = trim($sql, ','); // then trim trailing and prefixing commas
$sql .= " WHERE condition = value";
which will produce this:
UPDATE table SET id = 3, name = 'NAME', age = 12 WHERE condition = value
L.E 2: If you want the id column in your condition, the code becomes this:
$sql = "UPDATE table SET ";
foreach($array as $key=>$value) {
if($key == 'id'){
$sql_condition = " WHERE " . $key . " = " . $value;
continue;
}
if(is_numeric($value))
$sql .= $key . " = " . $value . ", ";
else
$sql .= $key . " = " . "'" . $value . "'" . ", ";
}
$sql = trim($sql, ' '); // first trim last space
$sql = trim($sql, ','); // then trim trailing and prefixing commas
$sql .= $sql_condition;
which will produce this result:
UPDATE table SET name = 'NAME', age = 12 WHERE id = 3
Hope this helps! :D
foreach ($update_array as $key => $testimonials) {
$name = mysql_real_escape_string($testimonials->name);
$content = mysql_real_escape_string($testimonials->content);
$id = intval($testimonials->id);
$sql = "UPDATE testimonials SET name='$name', content='$content' WHERE id=$id";
$result = mysql_query($sql);
if ($result === FALSE) {
die(mysql_error());
}
}
Source : https://stackoverflow.com/a/7884331/3793639
Other sources to check.
PHP SQL Update array and Simple UPDATE MySQl table from php array
You could use something like this for achieving that:
foreach($values as $value) {
if(!key_exists($value, $item)) {
return false;
}
$table->{$value} = $items[$value];
}
Assuming that the key index is always id and that adodb can use named placeholders you could do this:
$array = Array('id'=>'3', 'name'=>'NAME', 'age'=>'12');
$set = array();
$data = array();
while(list($key,$value)=each($array)) {
$data[':'.$key] = $value;
if($key!='id') {
$set[] = $key . ' = :' . $key;
// if no placeholders use $set[] = $key . " = '" . database_escape_function($value) . "'";
}
}
$sql = "UPDATE table SET ".implode($set, ',')." WHERE id=:id";
//$data is now Array(':id'=>'3', ':name'=>'NAME', ':age'=>'12');
//$sql is now "UPDATE table SET name=:name, age=:age WHERE id=:id";
$stmt = $DB->Prepare($sql);
$stmt = $DB->Execute($stmt, $data);
This is probably the shortest and easiest for you, you can also use something like this to achieve it:
$array = Array('id'=>'3', 'name'=>'NAME', 'age'=>'12');
$sql = "UPDATE table SET ";
$sql .= implode(', ', array_map(function($key, $value){
return is_numeric($value) ? "{$key} = {$value}" : "{$key} = '". mysql_real_escape_string($value). "'";
}, array_keys($array), $array));
$sql .= " WHERE id = 123";
// Result : UPDATE table SET id = 3, name = 'NAME', age = 12 WHERE id = 123
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);
}
i'm trying to insert multiple data using a query, i've tried the implode function, the while loop, for loop, but still can't be done..
can u help plz
well i've a combobox box for selecting course name, created a function to get its ID and assign a variable. supose i'm a manager of a department and need to assign all staff below me a course, i select the course, input the date assigned and expected ending date. i've created another field in database to enter the training owner. Since i'm the 1 assigning the course, my name will appear as owner field.
$m_name = $_SESSION['SESS_FIRST_NAME'];
//combobox to get the department ID using variable $dept
//query to get all user concerning the department
$query = mysql_query("select userid from dept_user where dept_id=$dept LIMIT 0, 30 ");
$row= mysql_query($query);
//from here i'm not being able to execute
$qry = mysql_query("INSERT INTO course_detail(userid, course_id, date_assign, expected_end_date, owner) VALUES('$query','$name','$sdate', '$edate', '$m_name')" ) ;
$qry = mysql_query("INSERT INTO course_detail(userid, course_id, date_assign, expected_end_date, owner) VALUES('$query','$name','$sdate', '$edate', '$m_name')" ) ;
So, you're basically trying to insert $query in the userid column. In your code, $query is the result of a mysql select statement, thus a multi-array of user ids. Think of it like a simple SQL query, you can't execute that. Even more, you're doing mysql_query on a mysql_query result, which is plain wrong. Where does the $dept variable come from? What about the others? If you're sure they're valid here's what you need:
// Get the user ids you need to insert in the db
$query = "select userid from dept_user where dept_id=$dept LIMIT 0, 30 "; // this will select the first 30 users in a dept
$buffer = mysql_query($query); // this is a variable that will hold all the results returned by the query above
// While we still have results in the $buffer array, fetch those in the $data array
while ($data = mysql_fetch_assoc($buffer)) {
$insert_query = "INSERT INTO course_detail(userid, course_id, date_assign, expected_end_date, owner) VALUES('".$data['userid']."','$name','$sdate', '$edate', '$m_name')"; // add the userid from the first query and the other data (don't know where you got those
$insert_buffer = mysql_query($insert_query); // execute the statement above, watch out so you don't overwrite the initial $buffer variable
}
// At this point you should have all the data in database
Also, I'm not sure you got the insert statement right
userid > $data['userid'] (ok)
course_id > $name (?!)
date_assign > $sdate (you sure?)
expected_end_date > $edate (ok)
owner > $m_name (ok?)
Make sure you have a good naming convention or else you get lost very easy.
Good luck, a lot of mistakes on just 5 lines of code.
Let's give it a wild guess and assume that this is what you want:
//query to get all user concerning the department
$query = mysql_query("
SELECT userid
FROM dept_user
WHERE dept_id=$dept
");
if(mysql_num_rows($query)){
$insertSQL = "
INSERT INTO course_detail
(userid, course_id, date_assign, expected_end_date, owner)
VALUES
";
$rowsSQL = Array();
while($row = mysql_fetch_row($query)){
$rowsSQL[] = "('{$row['userid']}','$name','$sdate', '$edate', '$m_name')";
}
mysql_query($insertSQL.implode(',', $rowsSQL));
}
Also you should start reading the manual.
Read the doc, you can separate each set of data with a comma.
$values = array();
$values[] = array(
'id' => 1,
'v1' => 'a',
'v2' => 'b'
);
$values[] = array(
'id' => 2,
'v1' => 'c',
'v2' => 'd'
);
$sql = "INSERT INTO course_details (id,v1,v2) VALUES ";
foreach ($values as $value) {
$sql .= '('.$value['id'].','.$value['v1'].','.$value['v2'].'),';
}
$sql = substr ($sql,0,-1) // that will remove the last comma
mysql_query($sql);
Below is the function and here is how to use it
Update Query
$data_array=array(
"bannername" => addslashes($_POST["bannername"]),
"url" => $_POST["url"],
"openin" => $_POST["openin"]
);
$param=" bannerid = '$bannerid'";
$sql=db_makequery("banner",$data_array,"update",$param);
Insert Query
$data_array=array(
"bannername" => addslashes($_POST["bannername"]),
"url" => $_POST["url"],
"openin" => $_POST["openin"]
);
$sql=db_makequery("banner",$data_array);
Function
function db_makequery($table, $data, $action = 'insert', $parameters = '')
{
reset($data);
if ($action == 'insert')
{
$query = 'insert into ' . $table . ' (';
while (list($columns, ) = each($data)) {
$query .= $columns . ', ';
}
$query = substr($query, 0, -2) . ') values (';
reset($data);
while (list(, $value) = each($data))
{
switch ((string)$value)
{
case 'now()':
$query .= 'now(), ';
break;
case 'null':
$query .= 'null, ';
break;
default:
//$query .= '\'' . tep_db_input($value) . '\', ';
$query .= '\'' . $value . '\', ';
break;
}
}
$query = substr($query, 0, -2) . ')';
}
elseif ($action == 'update')
{
$query = 'update ' . $table . ' set ';
while (list($columns, $value) = each($data))
{
switch ((string)$value) {
case 'now()':
$query .= $columns . ' = now(), ';
break;
case 'null':
$query .= $columns .= ' = null, ';
break;
default:
//$query .= $columns . ' = \'' . tep_db_input($value) . '\', ';
$query .= $columns . ' = \'' . $value . '\', ';
break;
}
}
$query = substr($query, 0, -2) . ' where ' . $parameters;
}
return $query;
}