SQL query results are different than varibles - php

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.

Related

mysql problem using php when update table

This system is based on invitation codes, if u have a code that is present in the database you can submit the input therefore change a value in a row. There are 2 inputs, 1) Invitation Code (key), if exist in the database the user can submit the value 2)Name (user). I done the following code but it doesn't work, any suggestions?
<?php
//get value pass from form in login.php
$username = $POST['user'];
$password = $POST['key'];
//connect to the server and select database
mysql_connect("localhost", "...","...");
mysql_select_db("...");
// Query the database for user
$result = mysql_query("UPDATE invitation_keys SET name ='$username' WHERE key = '$password'";)
or die("Failed to query database".mysql_error());
$row = mysql_fetch_array($result);
if ($row['key'] == $password) {
echo "Login success!!!".$row['key'];
} else {
echo "Failed to login";
}
?>
When you are coding in PHP, var_dump($var) is your best friend.
So the first thing to do here, is to print the query.
You will see, that your $username and $password vars are NULL, because you missed the syntax of $_POST[].
After, you can put in var_dump what you want, and that's why its interesting, because you will debug faster with this.

How to dynamically populate new page with variable set on last page?

I'm new to PHP and am trying to build my a website to display information on TV shows stored in a MySQL DB. I've currently got a webpage that will create a table to display the information in the DB, however I'd like each row to link to a dynamically populated page with more info on each show (also pulling from the DB). My question is how do I get the site to know which link has been clicked and then save that as a variable so it can then be recalled on a new to populate the correct information?
I'm currently using this to populate the page.
<!--Populate page with data from SQL-->
<?php
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "media_server";
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "SELECT show_title, show_desc, thumbnail_path FROM tv_shows WHERE status = 'Y'";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
echo "<table><tr><th></th><th></th></tr>";
// output data of each row
while($row = $result->fetch_assoc()) {
echo "
<tr>
<td>
<img src='../images/thumbnails/tv/".$row["thumbnail_path"]."'>
</td>
<td class='td_title'>
<a href='#' onclick='show_var_set();'>".$row["show_title"]."</a>
</td>
<td class='td_desc'>".$row["show_desc"]."</td>
</tr>";
}
echo "</table>";
} else {
echo "Error - 0 results were returned my the database. Please try again.";
}
$conn->close();
?>
One option is to change your href links to point to this page and pass a GET variable you can retreive. The added bonus to this approach is you could bookmark a particular show and come back to that page, since the bookmark will include that GET variable.
So you could change your links to something like this:
echo '', $row['show_title'],'';
Then you'd retrieve that variable by testing for, then reading the GET variable and performing a db query to populate the page with that show's data.
Here's how you'd test for and retreive that variable:
if (isset($_GET['show']))
{
$show = $_GET['show'];
// Perform database lookup using $show
}
Remember to never put user input directly into a query, but use prepared statements and bind the user data to avoid the risk of SQL injection.
There are many ways to pass values from page to page but one is to use session variables:
//Include this at the top of your php scripts that use session variables
session_start();
$_SESSION['your_variable_name_here'] = value_you_want_to_store;
Then on the page you would like to access this use:
$someVariable = $_SESSION['your_variable_name_here'];
Change the SQL to return the show_id,
$sql = "SELECT show_id, show_title, show_desc, thumbnail_path FROM tv_shows WHERE status = 'Y'";
and use that as a parameter to the show_var_set() function.
<a href='#' onclick='show_var_set(".$row["show_id"].");'>".$row["show_title"]."</a>
The show_var_set() function can then use that parameter to get the details for that show from the database.

Why is my MySQL database adding empty rows?

I'm learning PHP and SQL by running MAMP on my Mac, and accessing the database through phpMyAdmin.
I've made one PHP script to add a new user to a table, one for comparing inputted data with the table (login) and one to close an account. All of the scripts are very basic and the data isn't sanitized at all, as I'm just getting used to the basics of PHP.
I've noticed that after I run the script for account creation (inserting data), a few seconds after the script is run, a new row is added to the table with an id (which I've set to auto increment) but no other data.
I'm just wondering if the reason for this is something obvious in MySQL that I'm just missing.
The following is the account creation script:
<?php
//Get values from HTML form
$varUsername = $_POST['username'];
$varPassword = $_POST['password'];
$varPasswordHash = password_hash($varPassword, PASSWORD_DEFAULT);
//Establish connection to database
$server = "localhost";
$username = "root";
$password = "root";
$database = "members";
$connection = mysqli_connect($server, $username, $password, $database);
if(!$connection)
{
die("Connection failed: " . mysqli_connect_error());
}
//Send data to database
$action = "INSERT INTO details (USERNAME, PASSWORD) VALUES ('$varUsername', '$varPassword')";
if(mysqli_query($connection, $action))
{
echo 'Account created.';
}
else
{
echo 'Account creation failed: ' . mysqli_error($connection);
}
mysqli_close($connection); //End connection to database
?>
and the HTML form to go with it:
<html>
<body>
<form action="sign_up.php" method="post">
<input type="text" name="username">
<input type="text" name="password">
<input type="submit">
</form>
</body>
</html>
I'm making a guess right now...
I would add an extra if-statement to the script itself. Like this:
if (isset($_POST['submit-form'])) {
// All the above to insert the data into the script...
}
It would make sense if you visit the sign_up.php itself and notice there is a new entry made into your database.
You'll have to modify your HTML a little, to make the if-statement work.
Just add name='submit-form' to the submit button: <input type="submit" name="submit-form">
This will make the script more complete.
Also a little update on the matter as I just read that it adds an empty row after you submit an empty form.
You can check wether the fields are filled in with, guess what, another if-statement:
if (empty($_POST['username'])) {
echo 'Please enter your username...';
} else
if (...)
You do not verify if the POSTed values have anything in them, thus submitting an empty form results in an empty entry in the DB with just the ID.

php mysql prevent duplicate inserts from rapid form submits

I'm testing with this code:
<?php
$db = new PDO('mysql:host=localhost;dbname=test', 'root', 'root');
if(filter_has_var(INPUT_POST, 'submit')) {
$r = $db->query('SELECT * FROM test WHERE value="'.$_POST['value'].'"');
$n = $r->rowCount();
for ($i=0; $i<=10000000; $i++) {
// do nothing
}
if (!$n) {
$db->query('INSERT INTO test (id, value) VALUES (NULL, "'.$_POST['value'].'")');
}
}
?>
<form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
<input type="text" name="value" value="">
<input type="submit" name="submit" value="Submit">
</form>
When testing the above form in safari I am able to submit the same value into my database multiple times by rapidly clicking the submit button.
But, when I test with this code:
<?php
$db = new PDO('mysql:host=localhost;dbname=test', 'root', 'root');
if(filter_has_var(INPUT_POST, 'submit')) {
for ($i=0; $i<=10000000; $i++) {
// do nothing
}
$r = $db->query('SELECT * FROM test WHERE value="'.$_POST['value'].'"');
$n = $r->rowCount();
if (!$n) {
$db->query('INSERT INTO test (id, value) VALUES (NULL, "'.$_POST['value'].'")');
}
}
?>
The conditional works and I'm unable to submit the same value multiple times no matter how fast I click the submit button.
Is there a reliable way to prevent duplicate database inserts from occurring with the first code snippet so that it behaves just like the second snippet?
Generally a client side onsubmit handler can help stop accidental rapid-submissions, but I usually opt for a server side solution using _SESSION variables. Just create a hash of the $_POST array, store it as a session variable, and then compare the next submitted _POST to the hashed version:
session_start();
//if this is the first time they've posted, just create a placeholder session var
if (!isset($_SESSION['repost_hash'])){$_SESSION['repost_hash']="";}
//if the post array is a duplicate, nullify the submission
if (isset($_POST) && md5(serialize($_POST)) == $_SESSION['repost_hash']){
unset($_POST);
} else { //otherwise, if this is new data, update the stored hash
$_SESSION['repost_hash'] = md5(serialize($_POST));
}
...
If you only want to stop repeat-submissions for a short period of time, you can also have a second $_SESSION variable store the time of the last hash, so you can expire it after a second or two.

PHP - Dynamic SQL Query from Dynamic POSTs

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.)

Categories