How to add mysqli_real_escape_string() to dynamic variables? - php

<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
session_start();
$username= $_SESSION['username'];
require "connection.php";
// GET THE DATA FROM POST IF IT EXISTS
$data = isset($_POST['data']) ? $_POST['data'] : false;
// IF IT IS A VALID ARRAY THEN PROCESS IT
if (is_array($data)) {
// LOOP THOUGH EACH SUBMITTED RECORD
foreach($data as $id => $rec) {
// START AN UPDATE STRING
$updatestr = '';
// ADD FIELD / VALUES TO UPDATE STRING
foreach($rec as $fieldname => $value) {
if($fieldname == 'id'){
continue;
}
else{
$updatestr .= "`{$fieldname}` = '{$value}',";
}
}
// REMOVE THE TRAILING ,
trim($updatestr, ',');
$updatestr = rtrim($updatestr, ',');
// CREATE THE UPDATE QUERY USING THE ID OBTAINED FROM
// THE KEY OF THIS data ELEMENT
$query = "UPDATE `call` SET {$updatestr} WHERE id= '$id'";
// SEND IT TO THE DB
$result= mysqli_query($conn, $query);
}
echo "working";
}
else {
echo "not working";
}
?>
I have this code and it works perfectly, however I want to add
mysqli_real_escape_string But how can I do that to each variable since I don't know there exact information? I want it before it gets added to the query incase special characters were added
I also realized that my id never changes, it always stays one, whats the problem with that?

Granted I do not have access to PHP right now I believe this should work and get you on prepared statements.
<?php
foreach($data as $id => $rec) {
// START AN UPDATE STRING
$update_fields = array();
$bind_params_types = ''
$bind_params_values = array();
// ADD FIELD / VALUES TO UPDATE STRING
foreach($rec as $fieldname => $value) {
if($fieldname == 'id'){
continue;
}
else{
$update_fields[] = '{$fieldname} = ?';
$bind_params_types .= 's';
$bind_params_values[] = $value;
}
}
$update_fields = implode(',', $update_fields);
$bind_params_values = implode(',', $value);
// CREATE THE UPDATE QUERY USING THE ID OBTAINED FROM
// THE KEY OF THIS data ELEMENT
$query = "UPDATE `call` SET {$update_fields} WHERE id= '$id'";
if($stmt = mysqli_prepare($conn, $query)){
$stmt->bind_param($bind_params_types,$bind_params_values);
$stmt->execute();
} else {
echo "failed";
}
}
}

I've done addon in your code before updation i've esacpe the string
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
session_start();
$username= $_SESSION['username'];
require "connection.php";
// GET THE DATA FROM POST IF IT EXISTS
$data = isset($_POST['data']) ? $_POST['data'] : false;
// IF IT IS A VALID ARRAY THEN PROCESS IT
if (is_array($data)) {
// LOOP THOUGH EACH SUBMITTED RECORD
foreach($data as $id => $rec) {
// START AN UPDATE STRING
$updatestr = '';
// ADD FIELD / VALUES TO UPDATE STRING
foreach($rec as $fieldname => $value) {
if($fieldname == 'id'){
continue;
}
else{
$updatestr .= "`{$fieldname}` = '{$value}',";
}
}
// REMOVE THE TRAILING ,
trim($updatestr, ',');
$updatestr = rtrim($updatestr, ',');
$updatestr = mysqli_real_escape_string($conn, $updatestr);
// CREATE THE UPDATE QUERY USING THE ID OBTAINED FROM
// THE KEY OF THIS data ELEMENT
$query = "UPDATE `call` SET {$updatestr} WHERE id= '$id'";
// SEND IT TO THE DB
$result= mysqli_query($conn, $query);
}
echo "working";
}
else {
echo "not working";
}
?>

Related

Stored array data into string with comma(,)

[!]problem: whenever I get the data from frontend and try to insert into database...the data are inserted as a single alphabet in elective cell...but what I really needed that the whole data to be inserted in the elective cell with separated by comma(,)
<?php
include_once '../../config/db_connection.php';
include_once '../../config/functions.php';
include "autho.php";
include('../db_mysqli.php');
if (isset($_POST['submit'])) {
$username1 = $_POST['username'];
$username1 = preg_replace('#<script(.*?)>(.*?)</script>#is', '', $username1);
$rollno = $_POST['register_no'];
$rollno = preg_replace('#<script(.*?)>(.*?)</script>#is', '', $rollno);
$subjectcode = implode(',', $_POST['subject']); ;
date_default_timezone_set("Asia/Kolkata");
$today = date('g:ia \o\n l jS F Y');
$rollnos = array_map('strlen', $rollno);
$rollnos = min($rollnos);
if ($rollnos < 6) {
$error = 'Roll Number is too short.';
} else {
}
if (!isset($error)) {
for ($i = 0; $i < count($rollno); $i++) {
$sql = "UPDATE students SET elective='$subjectcode[$i]' WHERE register_number='$rollno[$i]'";
$result = mysqli_query($conn, $sql);
if ($result) {
header('Location:./?edu_camp=elective_student_update&success');
} else {
header('Location:./?edu_camp=elective_student_update&fail');
}
}
} else {
//echo "Sorry! something Wrong.";
}
}
?>
As the comments mentioned, you can implode your array into a string an insert it (docs).
Also, you're using MySQLi, but not using bound parameters which you REALLY should be using (docs).
// Concatenate all values together
$commaSeparatedList = implode(',',$subjectcode);
// Prepare your statement
$stmt = $mysqli->prepare("UPDATE students SET elective=? WHERE register_number=?");
// Bind the relevant parameters (not sure what the where clause should be here)
$stmt->bind_param('si', $commaSeparatedList, $i);
// Check if rows were affected
if ($mysqli->affected_rows > 0) {
// Success, rows were changed
}
// Execute and close the statement object
$stmt->execute();
$stmt->close();

PHP PDO dynamic update query to MYSQL

I have a form with an image upload and text inputs. it keeps replacing the profile_picture field with NULL. Therefore, I'm trying to create a dynamic update query, where if one value is empty it's excluded from the query altogether.
Any help is appreciated.
IMAGE UPLOAD:
if (!empty($_FILES['profile_picture']) && $_FILES['profile_picture']['error'] == UPLOAD_ERR_OK) {
// Rename the uploaded file
$uploadName = $_FILES['profile_picture']['name'];
$tmp_name = $_FILES['profile_picture']['tmp_file'];
$ext = strtolower(substr($uploadName, strripos($uploadName, '.')+1));
$filename = round(microtime(true)).mt_rand().'.'.$ext;
if (move_uploaded_file($_FILES['profile_picture']['tmp_name'],'../profile_picutres/'. $filename)) {
}
}
UPDATE QUERY:
$stmt = $dbh->prepare("UPDATE 001_user_table_as SET profile_picture=:profile_picture, first_name=:first_name, last_name=:last_name, phone_number=:phone_number, nationality=:nationality, years_experience=:years_experience, data=:data WHERE id=:id");
$stmt->bindParam(':profile_picture', $filename);
$stmt->bindParam(':first_name', $first_name);
$stmt->bindParam(':last_name', $last_name);
$stmt->bindParam(':phone_number', $phone_number);
$stmt->bindParam(':nationality', $nationality);
$stmt->bindParam(':years_experience', $years_experience);
$stmt->bindParam(':data', $cv_data);
$stmt->bindParam(':id', $user_id);
if($stmt->execute()){
$response["message"] = 'success';
}else{
$response["message"] = 'error';
$errors++;
}
Below is the solution, where an input is empty, it'll use the existing data in that field and will accept not only $_POST variables, but all variables.
// the list of allowed field names
$allowed = ["profile_picture","first_name","last_name", "phone_number", "nationality", "years_experience", "data" ];
// initialize an array with values:
$params = [];
// initialize a string with `fieldname` = :placeholder pairs
$setStr = "";
// loop over source data array
foreach ($allowed as $key)
{
if (!empty([$key]) || $key != "" || $key != NULL)
{
if($GLOBALS[$key] != NULL){
$setStr .= "`$key` = :$key ,";
$params[$key] = $GLOBALS[$key];
}else{
$setStr .= "`$key` = $key ,";
}
}else{
}
}
$setStr = rtrim($setStr, ",");
$params['id'] = $_SESSION['user_id'];
$dbh->prepare("UPDATE 001_user_table_as SET $setStr WHERE id = :id")->execute($params);
Rather than relying on a global variable, you could use a function to generate the SQL string that depends only on a table name, allowed columns and columns provided. This allows you to react to any source of request (forms, raw body, ...).
<?php
function getPreparedUpdateSql(string $table, array $allowedColumns, array $columns): string
{
$set = [];
foreach ($columns as $column) {
if (!in_array($column, $allowedColumns)) {
continue;
}
$set[] = "$column = :$column";
}
$set = implode(", ", $set);
return "UPDATE $table SET $set WHERE id = :id";
}
And here is an example usage of that function anywhere you need it.
<?php
$connection = new PDO("mysql:dbname=dbname;host=127.0.0.1", "user", "pass");
$jsonRequestBody = json_decode(file_get_contents("php://input"), true);
// ["firstname" => "firstname", "lastname" => "lastname"]
$entityId = 1;
$table = "users";
$allowedColumns = ["firstname", "lastname", "email", "role"];
$columns = array_keys($jsonRequestBody);
// ["firstname", "lastname"]
$sql = getPreparedUpdateSql($table, $allowedColumns, $columns);
// UPDATE users SET firstname = :firstname, lastname = :lastname WHERE id = :id
$query = $connection->prepare($sql);
$query->execute([...$jsonRequestBody, "id" => $entityId]);
If you want to use it on traditional forms, you can simply change the columns variable to this.
<?php
$columns = array_keys($_POST);
Do not forget to check for thrown exceptions!

Keeping a value in the database upon updating

This is my table in my database. It should only contain one row.
I have this code, that checks if there is no data , if there is not.. The data is inserted, else it's updated. The problem is, that if i update only Brevet, the value of Baccalaureabt will disappear from my database. Any help?
Code:
if(isset($_POST['submit']))
{ $brevet = $_POST['Brevet'];
$baccalaureatbt = $_POST['Baccalaureatbt'];
$sql1="SELECT Brevet,Baccalaureatbt FROM university";
if ($result=mysqli_query($con,$sql1))
{
$rowcount=mysqli_num_rows($result);
}
if($rowcount==0)
{
$sql="INSERT INTO university(Brevet,Baccalaureatbt) VALUES('$brevet','$baccalaureatbt')";
$result = mysql_query($sql);
}
else
{
$sql2 = "UPDATE university SET Brevet = '$brevet' , Baccalaureatbt = '$baccalaureatbt'";
$result2 = mysql_query($sql2);
}
The issue is that you are setting both values, if however either $baccalaureatbt or $brevet is empty, it will be updated with a empty value, i.e the original value will be deleted.
There are multiple ways to avoid this, but one way to do it is like so:
$sql2 = "UPDATE university SET ";
if(!empty($brevet)){
$sql2 .= "Brevet = '$brevet'";
$first = 1;
}
if(!empty($baccalaureatbt)){
$sql2 .= isset($first) ? ", Baccalaureatbt = '$baccalaureatbt'" : "Baccalaureatbt = '$baccalaureatbt' " ;
}
$result2 = mysql_query($sql2);
To update the values dynamically, use the following code. Just add the values you want in the values array.
if(isset($_POST['submit']))
{
$brevet = $_POST['Brevet'];
$baccalaureatbt = $_POST['Baccalaureatbt'];
$sql1="SELECT Brevet,Baccalaureatbt FROM university";
$result=mysqli_query($con,$sql1);
if ($result)
{
$rowcount=mysqli_num_rows($result);
}
if($rowcount==0)
{
$sql="INSERT INTO university(Brevet,Baccalaureatbt) VALUES('$brevet','$baccalaureatbt')";
$result = mysql_query($sql);
}
else
{
$values = array("brevet","baccalaureatbt");
$sql2 = "UPDATE university ";
$n = 0;
foreach($_POST as $key => $val) {
if(in_array($key, $values)) {
$sql2 += ($n !== 0 ? ", " : 0);
$sql2 += "SET".$key." = ".$val;
$n++;
}
if($n > 0) {
$result2 = mysql_query($sql2);
}
}
}
}

PDO update, no errors and no respons in DB

I am trying to update a specifik row in a table with no success or error message. I $_POST a form with many different inputs including one for selecting the specifik row(clubId).
I $_POST and use both name and value from my inputs in the form, handling these in the code below to make a query.
However, as I do not get any errormessage or can see anything wrong with my code except the security against injections I do not know where to proceed with this.
Do you see anything wrong with the code that could cause this? Otherwise, how should I proceed, tips, directions, new working code with the ability to handle forms without having to make any bigger change in the php code(Like I am trying below).
<?php
include ('../../db_conn.php');
$nameArrayValue = array();
foreach($_POST as $name => $value) {
if($name == 'clubId') {} else {
$nameArrayValue[] = $name." = :".$name;
}
}
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$values = implode(', ', $nameArrayValue);
$sql = "UPDATE random SET ".$values." WHERE id = :clubId";
$addRandom = $dbh->prepare( $sql );
foreach($_POST as $name => $value) {
$name = ":".$name;
$addRandom->bindParam($name, $value);
}
$addRandom->execute();
if($addRandom->rowCount() > 0) { echo' yaay'; }
//header('Location: ' . $_SERVER['HTTP_REFERER']);
?>
There where two errors in the code:
$addRandom->bindParam(:clubId, 199);
I had to remove the : before clubId and then change my value into a variable like below:
$addRandom->bindParam(clubId, $_POST['clubId']);
And now my code looks like:
include ('../../db_conn.php');
$nameArrayValue = array();
foreach($_POST as $name => $value) {
if($name == 'clubId') {} else {
if(!empty($value)) {
$nameArrayValue[] = $name." = :".$name;
}
}
}
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$names = implode(', ', $nameArray);
$values = implode(', ', $nameArrayValue);
$sql = "UPDATE random SET ".$values." WHERE id = :clubId";
$addRandom = $dbh->prepare( $sql );
foreach($_POST as $name => $value) {
if(!empty($value)) {
$addRandom->bindParam($name, $_POST[$name]);
$name = '';
}
}
$addRandom->execute();
if($addRandom->rowCount() > 0) { echo 'yaay'; }

Warning: Invalid argument supplied for foreach() and Warning: Cannot modify header information - headers already sent [duplicate]

This question already has answers here:
How to fix "Headers already sent" error in PHP
(11 answers)
Closed 9 years ago.
I've been stuck with the following problem for some time.
I keep getting the following error:
Warning: Invalid argument supplied for foreach() in
/home/content/50/10835750/html/dogdays/game/table.class.php on line 32
Warning: Cannot modify header information - headers already sent by (output started at
/home/content/50/10835750/html/dogdays/game/table.class.php:32) in
/home/content/50/10835750/html/dogdays/game/loadplayer.php on line 77
Redirecting to /game/locations/
My code is as follows:
<?php
// First we execute our common code to connection to the database and start the session
define('MyConst', TRUE);
include('database.class.php');
include('table.class.php');
include('user.class.php');
include('characters.class.php');
include('pc/player.class.php');
include('pc/human.class.php');
include('loginattempts.class.php');
include('timer.class.php');
include('functions.php');
include('loginf.php');
$dbo = database::getInstance();
$dbo -> connect("*****************", "***********", "*********", "********",
array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'));
secSessionStart();
$_SESSION['page'] = "loadplayer.php";
// At the top of the page we check to see whether the user is logged in or not
if(empty($_SESSION['user']))
{
// If they are not, we redirect them to the login page.
header("Location: login.php");
// Remember that this die statement is absolutely critical. Without it,
// people can view your members-only content without logging in.
die("Redirecting to login.php");
}
// Everything below this point in the file is secured by the login system
// We can display the user's username to them by reading it from the session array.
Remember that because
// a username is user submitted content we must use htmlentities on it before
displaying it to the user.
?>
<?php
// if(empty($_SESSION['playercharacter'])) {
$character_id = "";
$queryString = $_SERVER['QUERY_STRING'];
$queryString = explode("&", $queryString);
if(strcmp(substr($queryString[0],0,2),"c=") == 0) {
$character_id = substr($queryString[0],2);
}
$c = new characters();
$c -> load($character_id);
$playercharacterobject = new human($c, null);
$_SESSION['playercharacter'] = $playercharacterobject;
try {
$stmt = $dbo->getConnection()->prepare("SELECT * FROM location WHERE
location_id = :location_id");
$query_params = array(':location_id'=>$playercharacterobject->location_id);
// Execute the prepared query.
$result = $stmt->execute($query_params);
}
catch(PDOException $ex) {
// Note: On a production website, you should not output $ex->getMessage().
// It may provide an attacker with helpful information about your code.
die("Failed to run query1: " . $ex->getMessage());
}
$rows = $stmt->fetch(PDO::FETCH_ASSOC);
$_SESSION['currentlocation'] = $rows['url'];
$validAccess = array("babelfloor.php");
$_SESSION['validAccess'] = $validAccess;
$_SESSION['prevlocation'] = "loadplayer.php";
// }
// echo $_SESSION['currentlocation'];
// echo $rows['url'];
// THIS IS LINE 77. THE ONE THAT IS CAUSING PROBLEMS
header("Location: /game/locations/".$_SESSION['currentlocation']);
die("Redirecting to /game/locations/".$_SESSION['currentlocation']);
// header("Location: combat.php");
// die("Redirecting to combat.php");
?>
and
<?php
/**
* #author Alvin Tung
* #copyright 2013
*/
if(!defined('MyConst')) {
die('Direct access not premitted');
}
class table {
protected $id = null;
protected $table = null;
function __construct() {
}
function bind($data) {
foreach ($data as $key=>$value) {
$this -> $key = $value;
}
}
function load($id) {
$this->id = $id;
$dbo = database::getInstance();
$sql = $this->buildQuery('load');
$row = $dbo->query($sql, array(':'.$this->table.'_id'=> $id));
// THIS IS LINE 32
foreach ($row as $key=>$value) {
if($key == "user_id()") {
continue;
}
$this->$key = $value;
}
}
// write database object contents to database
function store() {
$dbo = database::getInstance();
$array = array();
$classVars = get_object_vars($this);
if($this->id =="") {
foreach ($classVars as $key=>$value) {
if ($key == "id" || $key == "table") {
continue;
}
$array[":{$key}"] = $value;
}
}
else {
$array[':'.$this->table.'_id'] = $this->id;
}
$sql = $this -> buildQuery('store');
$dbo -> query($sql, $array);
}
function buildQuery($task) {
$sql = "";
if ($task == "store") {
// if no id value has been store in this object yet,
// add new record to the database, else just update the record.
if ($this->id == "") {
$keys = "";
$values = "";
$classVars = get_class_vars(get_class($this));
$sql .= "INSERT INTO {$this->table}";
foreach ($classVars as $key=>$value) {
if ($key == "id" || $key == "table") {
continue;
}
$keys .= "$key,";
$values .= ":$key,";
}
// NOTE: all substr($keys, 0, -1) does is gets rid of the comma
// at the on the last array element.
$sql .= "(".substr($keys, 0, -1).") Values (".substr($values, 0,
-1).")";
}
else {
$classVars = get_class_vars(get_class($this));
$sql .= "UPDATE {$this->table} SET ";
foreach ($classVars as $key=>$value) {
if ($key == "id" || $key == "table") {
continue;
}
$sql .= "{$key} = '{$this->$key}',";
}
$sql = substr($sql, 0, -1)." WHERE {$this->table}_id = :{$this-
>table}_id";
}
}
elseif ($task == "load") {
$sql = "SELECT * FROM {$this->table} WHERE {$this->table}_id = :
{$this->table}_id";
}
return $sql;
}
}
?>
I've tried adding ob_start() to the top of loadplayer.php as is suggested by most answers on here, but then it justs outputs a blank page. Your insights would be greatly appreciated.
The error message Invalid argument supplied for foreach() indicates that foreach is given something that is not an array nor a Traversable object.
Given this piece of code:
$dbo = database::getInstance();
$sql = $this->buildQuery('load');
$row = $dbo->query($sql, array(':'.$this->table.'_id'=> $id));
// THIS IS LINE 32
foreach ($row as $key=>$value) {
it is clear that $row is not what you expect. Maybe the query contains invalid sql or the id does not exist in the database. You should do more error checking to properly handle those cases.
The message headers already sent is not really important here. If you resolve the first issue, the second one will also be gone.

Categories