PHP - Dynamic SQL Query from Dynamic POSTs - php

First time question, long time reader :)
I am building forms dynamically from Columns in a MYSQL DB. These columns
are created/ deleted etc.. elsewhere on my App. My form runs a query against a
SQL View and pulls in the column names and count of columns. Simple! build the form,
with the HTML inputs built with a PHP for loop, and it echos out the relevant HTML for the new form fields. All very easy so far.
Now i want a user to update these dynamically added fields and have the data added to the relevant columns - same table
as existing columns. So, as the input fields are named the same as the columns, they are posted to a PHP script for processing.
Problem is, while i have the actual field names inserted in to the SQL INSERT query, i cannot figure out how to extract the POST
data from the POST dynamically and add this to the VALUEs section of the query.
Here is my attempt....
The Query works without the variables added to it.
It works like this, first section/ is to retrieve the columns names from earlier created VIEW - as these are identical to POST names from the form. Then output to array and variable for insertion to Query. It looks like the implode function works, in that the relevant column names are correct in the statement, but i fear that my attempt to inject the column names on to the POST variables is not working.
$custq = "SELECT * FROM customProperties";
$result = $database->query($custq);
$num_rows = mysql_numrows($result);
while (list($temp) = mysql_fetch_row($result)) {
$columns[] = $temp;
}
$query = '';
foreach($columns as $key=>$value)
{
if(!empty($columns[$key]))
{
$values .= "'".'$_POST'."['".$value."'], ";
}
}
$q = "INSERT INTO nodes
(deviceName,
deviceInfo,
".implode(", ", $columns).",
nodeDateAdded,
status
)
VALUES
('" . $_POST['deviceName'] . "',
'" . $_POST['deviceInfo'] . "',
".$values."
CURDATE(),
'1'
)";
$result = $database->query($q)
Any help is much appreciated. I will feed back as much as i can. Please note, relativity new to PHP, so if i am all wrong on this, i will be glad for any tips/ advice
Regards
Stephen

If you want to get the values of every POST input without knowing the input names then you can do it this way:
//get all form inputs
foreach($_POST as $name => $value)
{
echo $name . " " . $value . "<br>";
}
If you want to get the value of certain POST inputs where you know the name of the input field then you can do it this way:
if(isset( $_GET["deviceName"]))
{
$deviceName = $_POST["deviceName"];
}
if(isset( $_GET["deviceInfo"]))
{
$deviceInfo = $_POST["deviceInfo"];
}
To connect to a database and insert the info then you have to do something like this:
$host = "localhost";
$dbuser = "username";
$pass = "password";
$datab = "databasename";
//Create DB connection
$con=mysqli_connect($host, $dbuser, $pass,$datab);
if (mysqli_connect_errno($con))
{
echo "ERROR: Failed to connect to the database: " . mysqli_connect_error();
}
else
{
echo "Connected to Database!";
}
//insert into database
mysqli_query($con, "INSERT INTO nodes (deviceName, deviceInfo) VALUES ('$deviceName', '$deviceInfo')");
(Don't forget to add mysql_real_escape_string to the $_POST lines after you get it working.)

Related

SQL query results are different than varibles

I want to set a url parameter by using uniqid function in php, I get the unique numbers and place them in my database by useing them in a hidden input form. I try to make it so, at the start of the script $number is set to a uniqid which I placed in the hidden input so it will be posted into the database and I can use the same variable to create a href link.
The problem I'm having is that the value stored in my database is not the same as the value stored in the number variable used in the href link which renders the link useless. How do I get both the values equal is there a better way to do what I'm trying to do?
I have tried putting uniqid() in a function
<?php
$servername = "localhost";
$username = "root";
$password = "";
$homeDB = "homeDB";
$conn = new mysqli($servername, $username, $password, $homeDB);
if($conn->connect_error) {
die("failed to connect to server".$conn->connect_error);
}
$number = uniqid();
if(isset($_POST["namn"])) {
$sql = "INSERT INTO information (firstname, lastname, urlID)
VALUES ('".$_POST["namn"]."','".$_POST["efternamn"]."',
'".$_POST["hide"]."')";
if($conn->query($sql)== TRUE){
$link = "http://localhost/sqltutorial/execute.php?id=".$number;
} else {
echo "failed";
}
echo $link;
}
html
<html>
<body>
<form method="post" action="home.php">
<input type="text" name="namn"> <br>
<input type="text" name= "efternamn"><br>
<input type="hidden" value="<?php $number ?>" name="hide">
<input type="submit" >
</form>
<br>
</body>
</html>
I get different values on the link that is echoed and the value stored in my database ( I know this form is not secure )
I think you just need to use the $_POST['hide'] value on the link.
It would also be better to echo the link only if it has been created.
Where you have the echo currently, it is possible to echo the $link variable even if it was not been created!
<?php
$servername = "localhost";
$username = "root";
$password = "";
$homeDB = "homeDB";
$conn = new mysqli($servername, $username, $password, $homeDB);
if($conn->connect_error) {
die("failed to connect to server".$conn->connect_error);
}
$number = uniqid();
if(isset($_POST["namn"])) {
$sql = "INSERT INTO information (firstname, lastname, urlID)
VALUES ('".$_POST["namn"]."','".$_POST["efternamn"]."',
'".$_POST["hide"]."')";
if($conn->query($sql)== TRUE){
$link = "http://localhost/sqltutorial/execute.php?id=$_POST[hide]";
// line moved to here
echo $link;
} else {
echo "failed";
}
}
The problem is that when the postback runs, you also run the line $number = uniqid(); again. So the final number which is output is not the one you placed in the hidden field.
Now, you could write
$link = "http://localhost/sqltutorial/execute.php?id=".$_POST["hide"];
and it would output the number which was passed in the POST variable.
Or you could just wait until the postback has happened to generate the unique ID, and use that in both the database call and the output. This saves a) a round-trip for the variable to the browser and back to the server, and b) anyone trying to tamper with the form data. So move the number creation code inside the if:
if(isset($_POST["namn"])) {
$number = uniqid();
...and then replace both references to $_POST["hide"] with $number instead. You can also remove the hidden field from your form.
One final alternative suggestion: Do you even need to do this? I assume your database table has an auto_increment integer field as the primary key? Why not just use the value already being generated by the database as the value for your link?
if($conn->query($sql)== TRUE){
$link = "http://localhost/sqltutorial/execute.php?id=".$conn->insert_id;
would get the auto-generated ID of the last row you inserted and use that in the link instead. See also documentation
I don't see any great purpose in creating a second ID for your row (especially since uniqid() does not promise to always give you a completely unique value), unless you have some specific reason?
So, you want to create a row and redirect on that link after creating.
Steps:
1) First get the next auto increment value for this informations table by this function and store it in $number.
$stmt = $this->db->prepare("SHOW TABLE STATUS LIKE 'informations'");
$stmt->execute();
$result = $stmt->fetchAll();
foreach ($result as $row) {
$number = $row[10];
}
2) Now do inserting, and after insert you'll get the same autoincrement ID and do everything with that.
Hope, it will help.
NB: You can make a function to grab that auto Increment ID for any table also.

Data Management Issue - How to manage retrieved data from mysql?

I am developing a game(c#) with database(mysql) and web service(php) to retrieving the data. The issue is the data management. There is a table on database with the name of items and it has some columns like id, item_name, item_description, item_prop, update_date, ownerId. I added 70 items to this table manually. The users can also add some items to this table or they can update the items they have already added in the game. My purpose is retrieving the whole affected rows of the table when the user is first logged in and save it as a json file in the game folder. After, read that file to fill the game environment with those items.
I try a way to achieve this. Firstly, i hold an updateDate variable in the game which is past like "1990-05-10 21:15:43". Second, i send this variable to the webservice as '$lastUpdateDate'; and make a query according to that variable at the database. select * from channels where update_date >= '$lastUpdateDate'; and write these rows in a json file as items.json. after that make a second query to retrieve the time and refresh the updateDate variable in the game. select select now() as 'Result';. In this way user would not have to get the whole table and write in json file every login process. So, it would be good for the performance and the internet usage. The problem occurs when the users update an item which is already added before. I can see the updated item, too with the first query, but I wrote it in json file twice in this way.
php code part of the getItems of my loginuser.php :
<?php
include './function.php';
// CONNECTIONS =========================================================
$host = "localhost"; //put your host here
$user = "root"; //in general is root
$password = ""; //use your password here
$dbname = "yourDataBaseName"; //your database
$phpHash = "yourHashCode"; // same code in here as in your Unity game
mysql_connect($host, $user, $password) or die("Cant connect into database");
mysql_select_db($dbname)or die("Cant connect into database");
$op = anti_injection_register($_REQUEST["op"]);
$unityHash = anti_injection_register($_REQUEST["myform_hash"]);
if ($unityHash == $phpHash)
{
if($op == "getItems")
{
$lastUpdateDate = anti_injection_login($_POST["updateDate"]);
if(!$lastUpdateDate)
{
echo "Empty";
}
else
{
$q = "select * from items where update_date >= '$lastUpdateDate';";
$rs = mysql_query($q);
if (!$rs)
{
echo "Could not successfully run query ($q) from DB: " . mysql_error();
exit;
}
if (mysql_num_rows($rs) == 0)
{
echo "No rows found, nothing to print so am exiting";
exit;
}
$arr = array();
while ($row = mysql_fetch_row($rs))
{
$arr = $row;
}
echo json_encode($arr);
}
mysql_close();
}
}
?>
So, how can i solve this problem? Or do you have any better idea for this approach. Help would be much appreciated. Thank you for your time.

CSV upload on front end of wordpress site (PHP/SQL)

I've made a lot of progress on this in some areas but struggling in others. Here's the objective: Existing wordpress site is being used by client. They want the admin user to access one of the front end pages with an upload option where they can upload a CSV (several daily). Then, upon accessing other pages in the portal, respective fields from the tables will be displayed (depending on the user). The CSV files have 201 fields, same order every time. In my php, I've setup a successful connection and coded 201 variables like so:
<?php
$server = "localhost";
$user = "root";
$pw = "root";
$db = "uwsTest";
$connect = mysqli_connect($server, $user, $pw, $db);
if ($connect->connect_error) {
die("Connection failed: " . $conn->connect_error);
}else{
echo'success!';
}
if(isset($_POST['submit']))
{
$coldata = array();
$coldata['orderNumber'] = $filesop[0];
$coldata['null'] = $filesop[1];
$coldata['workOrderNum'] = $filesop[2];
$coldata['lowSideMIUNum'] = $filesop[3];
$coldata['highSideMIUNum'] = $filesop[4];
$coldata['accountNum'] = $filesop[5];
$coldata['custName'] = $filesop[6];
Again, this line goes on through [200]. On the next portion, I will only paste certain variables to save space. This is where I index which tables certain variables will belong in.
$table_cols = array();
/*staging*/
$table_cols[0] ="null,orderNumber,null,workOrderNum,lowSideMIUNum,highSideMIUNum,accountNum
/*clients*/
$table_cols[1] ="orderNumber,null,workOrderNum,lowSideMIUNum,highSideMIUNum,accountNum,custName
/*meters*/
$table_cols[2] ="workOrderNum,lowSideMIUNum,highSideMIUNum,accountNum,custName,address
/*tests*/
$table_cols[3] ="workOrderNum,lowSideMIUNum,highSideMIUNum,accountNum,custName,address
/*costs*/
$table_cols[4] ="workOrderNum,onsiteSurveyTestCost,onsiteSurveyTestRepairCost,offsiteSurveyTestCost
/*workorders*/
$table_cols[5] ="workOrderNum,lowSideMIUNum,highSideMIUNum,accountNum,custName
And now the SQL query:
$tablenames = array("staging","clients","meters","tests","costs","workorders");
for($tableno = 0;$tableno < sizeof($tablenames);$tableno++){
$q = "";
$q .= "INSERT INTO ".$tablenames[$tableno]." (".$table_cols[$tableno].") VALUES (";
$cols = explode("," ,$table_cols);
$data = array();
foreach($col as $key => $fldname) {
$data[] = "'".$coldata[$fldname]."'";
}
$q .= implode(",",$data).");";
}
echo'File submitted';
When I run this, I get no PHP errors. I run it on Mamp, upload the CSV through an html submit form, it calls the php and then on my php index page I get my messages for successful connection and successful insertion. However, when I look in MySQL workbench and select from tables they are empty. My staging table was actually only created with one column for primary key but I don't know if this code will submit everything without established columns/fields in the database tables. In my table_cols array under the 'staging' option (index [0]), I actually have all 201 variables there, as the entire form will be housed in this one table just to be safe. Am I missing something here as to why it's not loading into the database?

How to store data from form builder in database

I am trying to create a form builder that will enable users generate survey form/page.
After the form is generated the form attribute is stored on a table.
Question 1:
Where can I store the form attribute knowing fully well that the number of fields user might add in the form is unknown.
Question 2:
Where and how do I store data submitted through the generated form when some one for example completes the survey form.
Should I create new tables on fly for each of the form attributes? If yes what if over a million forma are created which translates to a million tables.
Is this where multi-tenancy comes into play.
Please provide your answer based on best practices.
I think I get what you're asking, but why not create one table with 100 columns, labelled 1-100. Set a limit on the amount of fields a user can create(Limit 100).
Then, POST the fields and add a sql query to store the values...?
COMMENT ANSWER
If the user is already signed in filling this form I would personally do the POST request on the same page.
<?php if (isset($_POST['field1'])){
$valueforField1 = $_POST['field1'];
$valueforField2 = $_POST['field2'];
$valueforField3 = $_POST['field3'];
$servername = "localhost";
$username = "username";
$password = "password";
$dbname = "myDB";
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "INSERT INTO Survey (field1, field2, field3) // I guess you would `have to add 100 fields here to accommodate the fields in your DB Also, you can set a default value in MySQL that way if field 56-100 is not set it has a value like 0 or add the value in this php file`
VALUES ('$valueforField1', '$valueforField2', '$valueforField3')";
if ($conn->query($sql) === TRUE) {
echo "New record created successfully";
} else {
echo "Error: " . $sql . "<br>" . $conn->error;
}
$conn->close(); ?>
COMMENT ANSWER or if you want to wait for the user to log in you can store all the values in a SESSION variable.
<?php
session_start();
if (isset($_POST['field1'];)){
if (!(isset($_SESSION['email']))){
$_SESSION['field1'] = $_POST['field1'];
// You would have to do 100 of these
}
}
?>

SQL WHERE ID carryover

Basically I've created two php papes. One selects my entire table, and displays just date, and id number from it. Each date has a link directing to a display.php file. It pulls the ID number with it to the next display.php page. What I want to do on the display.php file is to display the entire row using that PHP.
So I know that Select * from tablename WHERE id=1 will pull that data, but how to get the ID number into there WHERE statement?
This is the main page code:
// SQL query
$strSQL = "SELECT * FROM table1";
// Execute the query (the recordset $rs contains the result)
$rs = mysql_query($strSQL);
// Loop the recordset $rs
while($row = mysql_fetch_array($rs)) {
// DATE
$strName = $row['date'];
// Create a link to display.php with the id-value in the URL
$strLink = "<a href = 'display.php?ID = " . $row['ID'] . "'>" . $strName . "</a>";
// List link
echo "<li>" . $strLink . "</li>";
}
That code links works and goes to display.php.
How would I create the link using the ID number pulling with it. Would I use a post command?
$id= Post['id']
then WHERE id = '$id'
?
TBH I did try that and got nothing. Any suggestions?
USING GET now...still not luck
I've tried the GET statement. In my address bar it shows the ID number. So I see the ID number pulling over with it. I tried even just echoing the ID to see if maybe it was just my code messing up.
<?php
$dbhost = 'localhost';
$dbuser = 'myusername';
$dbpass = 'mypw';
$dbname = 'mydbname';
$id = $_GET['id'];
mysql_connect($dbhost, $dbuser, $dbpass) or die('MySQL connect failed. ' . mysql_error());
mysql_select_db($dbname) or die('Cannot select database. ' . mysql_error());
?>
<body>
ID #<?php echo $id ?>
</body>
</html>
<body>
ID #<?php echo $id ?>
</body>
</html>
Still no luck
So in your display file you'd do something like this
$id = $_GET['ID'];
//DO SANITIZATION ETC ON THE ID HERE TO MAKE SURE ITS SOMETHING WE EXPECTED (AN INT)
$sql = "SELECT STUFF WHERE ID = {$id}"; //FOR BREVITY SAKE DOING AWAY WITH SECURITY
So basically what your first script is doing is passing the id in the url query string, values passed here are accessible in the $_GET super globals array.
Anything you access in here and the other super globals should be treated as completely dangerous to your application. You should filter and escape the hell out of it, and then before inserting it into the database you must escape it using the correct mechanism for your database. Otherwise you leave yourself open to SQL injection attacks.
Values passed in the querystring use GET not POST.
Post is for form variables.
You should also be aware of the danger of a SQL injection attack when taking values from the querystring.

Categories