I have a 3 parameters which should append new/update old entries to a custom mysql table. However, I cannot figure out WHY when I press the submit button ... nothing happens (nor do I get any errors). I am at a loss for what to do. I have asked this question before and have modified my code a bit based on other tutorials thinking that was my issue... no luck :(
I understand that there are concerns for mysql injections - presently I'd just like to see it work and if you have suggestions for mitigating injections I am all ears. I am still a novice at mySQL... but learning slowly and understand (minimally) how string variables can be used to create altered queries.
Here is my code;
echo "<p><h5>Change address:</h5>";
//get user id when the login/visit page
$userid = get_current_user_id();
$loop = new WP_Query( $args );
//form start
echo '<form method = "post" action = "'. $_SERVER['PHP_SELF'] .'">';
//dropdown menu for collecting SKU of product
echo '<br><select name="sku">';
echo '<option>-- Select product--</option>';
while ( $loop->have_posts() ) : $loop->the_post();
global $product;
echo '<option value=' . $product->get_sku() . '>' . $product->get_sku() . ' </option>';
endwhile;
echo '</select>';
//hidden input for userid
echo '<input type="hidden" id="userid" name="userid" value="' . $userid . '">';
//textbox for address
echo '<br><input type="text" value="Insert new address here" id="address" name="address" size="40" />';
//submit button
echo '<br><input type="submit" name="submit">';
echo '</form>';
//write to database
if(isset($_POST['submit'])) {
$user = $_POST['userid'];
$sku = $_POST['sku'];
$address = $_POST['address'];
$con2 = mysqli_connect("IP","user","password","wpdb");
$updateaddress = "REPLACE INTO wp_newaddress(user, sku, address) VALUES($user, $sku, $address)";
$retval = mysqli_query($con2,$updateaddress);
if($retval)
{
echo 'Data Updated';
}else{
echo 'Data Not Updated';
}
mysqli_close($con2);
}
Thanks :)
You need to use prepare and execute with bound parameters to avoid the SQL injection risk.
You need to check for error conditions after every prepare and execute, and output any errors to your error log. You won't see errors if you don't do this.
Of course you should also watch your PHP error log (which is typically the same as your http server error log), but this goes without saying. Every PHP developer should be watching the error log (even though many developers don't know this).
Here's an example:
$user = $_POST['userid'];
$sku = $_POST['sku'];
$address = $_POST['address'];
$con2 = mysqli_connect("IP","user","password","wpdb");
$updateaddress = "REPLACE INTO wp_newaddress (user, sku, address) VALUES (?, ?, ?)";
$stmt = mysqli_prepare($con2,$updateaddress);
if ($stmt) {
mysqli_stmt_bind_param($stmt, 'sss', $user, $sku, $address);
$ok = mysqli_stmt_execute($stmt);
if ($ok) {
echo 'Data Updated';
} else {
echo 'Data Not Updated';
error_log(mysqli_stmt_error($stmt));
}
mysqli_stmt_close($stmt);
} else {
error_log(mysqli_error($con2));
}
mysqli_close($con2);
Also read answers in How can I prevent SQL injection in PHP?
Related
This is a form within a PHP file saved as single.php
<form action="comments.php" method="post" >
<?php include(ROOT_PATH . "/app/helpers/formErrors.php"); ?>
<input type= "hidden" name="id" value= <?php echo $id; ?> >
<textarea rows="4" name="comment"class="text-input contact-input" placeholder="Comment here....."></textarea>
<button type='submit' name="postcomment" value="comment" class="btn"> Add Comment</button>
</form>
This is also the php file that is receiving the form. comments.php
<?php
include(ROOT_PATH . "/app/helpers/validateComment.php");
$errors = array();
if(isset($_POST['postcomment'])){
$errors = validateComment($_POST);
//USE MYSQLI_REAL_ESCAPE_STRING() TO ESCAPE SINGLE QUOTES
// AND AGAINST SQL INJECTION
$userid = mysqli_real_escape_string($conn, $_SESSION['id']);
$username = mysqli_real_escape_string($conn,$_SESSION['username']);
$postid = mysqli_real_escape_string($conn,$_POST['id']);
$comment = mysqli_real_escape_string($conn,$_POST['comment']);
//prepared statement
$sql = $conn->stmt_init();
$query = "INSERT INTO comments (user_id, post_id, username, comment)
VALUES (?,?,?,?)";
if($sql->prepare($query)){
$sql->bind_param('ssss',$userid,$postid,$username,$comment);
$sql->execute();
header("Location:single.php?id=" . $postid); }
}
?>
and lastly my validatecomment.php
<?php
function validateComment($comments)
{
$errors = array();
if (empty($comments['comment'])){
array_push($errors, 'Comment is required!' );
}
if(!isset($_SESSION['username'])){
array_push($errors, "Sign UP first!");
}
return $errors;
}
?>
I don't understand why the validation is not working. Any help to get this working will highly be appreciated.
Right now, you're creating an error array, and doing nothing with it. Basically, you're letting in anyone who knocks whether you want them in or not. What you need to do is actually decide what to do if there are any errors.
$errors = validateComment($_POST);
if(!empty($errors)) {
// Insert code here to redirect, print out errors, whatever you want
} else {
// And here is where you would put all of your database stuff
$sql = $conn->stmt_init();
$query = "INSERT INTO comments (user_id, post_id, username, comment)
VALUES (?,?,?,?)";
if($sql->prepare($query)){
$sql->bind_param('ssss',$userid,$postid,$username,$comment);
$sql->execute();
header("Location:single.php?id=" . $postid); }
}
}
Note that I did not use the real_escape_string functions. They are unnecessary when you're using prepared statements.
I'm having a problem getting a result from my mysql database and getting it to popular a form. Basically, i'm making an item database where players can submit item details from a game and view the database to get information for each item. I have everything working as far as adding the items to the database and viewing the database. Now i'm trying to code an edit item page. I've basically reused my form from the additem page so it is showing the same form. At the top of my edititem page, I have the php code to pull the item number from the url as the item numbers are unique. So i'm using a prepared statement to pull the item number, then trying to retrieve the rest of the information from the database, then setting each information to a variable. Something is going on with my code but I can't find any errors. I entered a few header calls to debug by putting information in the url bar...But the headers aren't even being called in certain spots and im not getting any errors.
In the form, I used things like
<input name="itemname" type="text" value="<?php $edit_itemname?>">
and nothing is showing in the textbox. I'm fairly new to php and it seems much more difficult to debug than the other languages i've worked with..Any help or suggestions as far as debugging would be greatly appreciated. I posted my php code below as well if you guys see anything wrong...I shouldn't be having issues this simple! I'm pulling my hair out lol.
Thanks guys!
<?php
require 'dbh.php';
if (!isset($_GET['itemnumber'])) {
header("Location: itemdb.php");
exit();
}else{
$sql = "SELECT * FROM itemdb WHERE id = ?";
$stmt = mysqli_stmt_init($conn);
if (!mysqli_stmt_prepare($stmt, $sql)) {
header("Location: edititem.php?error=sqlerror");
exit();
}else{
$getid = $_GET['itemnumber'];
mysqli_stmt_bind_param($stmt, "i", $getid);
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);
//Make sure an item is selected
if ($result == 0) {
$message = "You must select an item to edit!";
header("Location: edititem.php?Noresults");
exit();
}else{
while ($row = mysqli_fetch_assoc($stmt)) {
$edit_itemname = $row['name'];
$edit_itemkeywords = $row['type'];
$edit_itemego = $row['ego'];
$edit_itemweight = $row['weight'];
$edit_itemacordmg = $row['acordmg'];
$edit_itemtags = $row['tags'];
$edit_itemworn = $row['worn'];
$edit_itemaffects = $row['affects'];
$edit_itemloads = $row['loads'];
$edit_itemarea = $row['area'];
$edit_itemcomments = $row['comments'];
header("Location: edititem.php?testing");
}
}
}
}
?>
To get the value of $edit_itemname into the output you should be using <?= not <?php. Saying <?php will run the code, so basically that is just a line with the variable in it. You are not telling it to print the value in the variable.
If your whole line looks like:
<input name="itemname" type="text" value="<?= $edit_itemname?>">
That should give you what you are looking for. The <?= is the equivalent of saying echo $edit_itemname;
If you don't like using <?= you could alternatively say
<input name="itemname" type="text" value="<?php echo $edit_itemname; ?>">
Your code should be change to a more readable form and you should add an output - I wouldn't recomment to use <?= - and you need to choose what you're going to do with your rows - maybe <input>, <table> - or something else?
<?php
require 'dbh.php';
if (!isset($_GET['itemnumber'])) {
header("Location: itemdb.php");
exit();
} // no else needed -> exit()
$sql = "SELECT * FROM itemdb WHERE id = ?";
$stmt = mysqli_stmt_init($conn);
if (!mysqli_stmt_prepare($stmt, $sql)) {
header("Location: edititem.php?error=sqlerror");
exit();
} // no else needed -> exit()
$getid = $_GET['itemnumber'];
mysqli_stmt_bind_param($stmt, "i", $getid);
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);
//Make sure an item is selected
if ($result == 0) {
$message = "You must select an item to edit!";
header("Location: edititem.php?Noresults");
exit();
} // no else needed -> exit()
while ($row = mysqli_fetch_assoc($stmt)) {
$edit_itemname = $row['name'];
$edit_itemkeywords = $row['type'];
$edit_itemego = $row['ego'];
$edit_itemweight = $row['weight'];
$edit_itemacordmg = $row['acordmg'];
$edit_itemtags = $row['tags'];
$edit_itemworn = $row['worn'];
$edit_itemaffects = $row['affects'];
$edit_itemloads = $row['loads'];
$edit_itemarea = $row['area'];
$edit_itemcomments = $row['comments'];
// does not make sense here: header("Location: edititem.php?testing");
// show your data (need to edited):
echo "Name: " + $edit_itemname + "<br/>";
echo "Area: " + $edit_itemarea + "<br/>";
echo "Comment: " + $edit_itemcomments + "<br/>";
// end of current row
echo "<hr><br/>"
}
?>
I am using a form. (I wanted the message text as a text area but changed back to normal text to see if this was the problem)
This is the form I am using
<form name="addmessage" method="POST" action="addmessage.php" >
<input type="text" name="message_title" id="message_title">Message Title</input>
<input type="text" name="message_text" id="message_text">Message</input>
<input type="submit" name="submit" value = Add>
</form>
Below is the PHP code. I understand i need to protect against sql injection however, i can do this later.
<?php
include_once("config.php");
if(isset($_POST["message_title"]) && strlen($_POST["message_title"])>0)
{
$message_title=$_POST['message_title'];
$message_text=$_POST['message_text'];
session_start();
$barber_id = $_SESSION['barber_id'];
$insert_row = $mysqli->query("INSERT INTO messages(barber_id,message_title,message_text) VALUES('".$barber_id."','".$message_title."',".$message_text.")");
}
else
{
//Output error
header('HTTP/1.1 500 Error You have left it blank');
exit();
}
header("location:messages.php");
?>
If manually enter data using phpMyAdmin, I can get it to display using the code below.
include_once("config.php");
session_start();
$barber_id = $_SESSION['barber_id'];
$results = $mysqli->query("SELECT * FROM messages WHERE barber_id ='$barber_id' ");
//get all records from table
while($row = $results->fetch_assoc())
{
$prices_id = $row['prices_id'];
echo '<div data-role="collapsible">';
echo '<h1>';
echo ' Message Title: ';
echo $row['message_title'];
echo '</a>';
echo '</h1>';
echo '<p>';
echo $row['message_text'];
echo ' Delete</div>';
}
$mysqli->close();
?>
At $insert_row = $mysqli->query("INSERT INTO messages(barber_id,message_title,message_text) VALUES('".$barber_id."','".$message_title."',".$message_text.")");
you should write
$insert_row = $mysqli->query("INSERT INTO messages(barber_id,message_title,message_text) VALUES('".$barber_id."','".$message_title."','".$message_text."')");
Everytime you pass a String or other non int values you must pass them like that: 'xx', otherwise mysql will see it as query param and it crashes.
I am losing my mind on this and I could really use some direction. Just trying to learn PDO along with PHP and failing to understand the logic. I keep trying to find something online that shows a good example of the flow for this test attempt and I'm having a real hard time.
Could someone, even if you have to flame the heck out of me (although like anyone, I'd prefer you not), give me some direction on what I'm doing horribly wrong? I'm building this to start my understanding. There's plenty of info on using mysqli but not pdo and it's driving me nuts.
Thanks in advance. Here's the code:
<?php
# connection info to the db
$host = "--shadowed--";
$dbname = "--shadowed--";
$user = "--shadowed--";
$pass = "--shadowed--";
# pdo options/attributes
$opt = array( PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION ); // not getting errors
# data source name
$dsn = "mysql:host=$host;dbname=$dbname";
# basic pdo connection (with added option for error handling)
if (isset($_POST['submit'])) {
try {
$DBH = new PDO($dsn, $user, $pass, $opt);
$STH = $DBH->prepare("INSERT INTO data (name,email,phone,detail,cost) VALUES (:name,:email,:phone,:detail,:cost)");
$STH->bindParam(':name', $name);
$STH->bindParam(':email', $email);
$STH->bindParam(':phone', $phone);
$STH->bindParam(':detail', $detail);
$STH->bindParam(':cost', $cost);
$name = $_POST['name'];
$email = $_POST['email'];
$phone = $_POST['phone'];
$detail = $_POST['detail'];
$cost = $_POST['cost'];
$STH->execute();
echo $STH; // attempted to echo back the data, but nothing happens
} catch (PDOException $e) {
echo $e->getMessage(); // no errors
}
}
echo '<form method="POST" action="">';
echo '<p>Enter the below information if you want to live:</p>';
echo 'Name: <input type="text" name="name"><br />';
echo 'E-mail: <input type="text" name="email"><br />';
echo 'Phone: <input type="text" name="phone"><br />';
echo 'Order will be generated randomly from class (once built)<br />';
echo 'Description: <input type="text" name="detail"><br />';
echo 'Cost: <input type="text" name="cost"><br />';
echo '<input type="submit" value="Do-It"></form>';
# close the connection
$DBH = null;
?>
------------- Final Code after Resolution Reached -------------
------------- Final Code after Resolution Reached -------------
(still a newb so can't answer my own question currently)
So first off, I didn't come up with this... it's a mix of everyone here really. I appreciate everyone's help and time with this while I try to learn all the missing links from my knowledge.
The main issues seems to be that when I used my original attempt to utilize if (isset($_POST['submit'])), it didn't actually do or send anything. No errors... no database issues... just a bunch of nothing. We removed that to find it was holding back ( ty #Fred ). Although this didn't change how the code works, it became more efficient using #hjpotter92 suggestion. Then we looked how to submit using this single page. I ended up using a mix of #Fred's and #david strachan suggestions as neither was giving me the right reaction, then I added an if/else statement to perform the check and if it passed, run the try/catch.
It's no work of art, but I learned quite a bit and appreciate the help. Also, I think it will be nice to get something out there people can bump into to see a full example. If any of you guys have any additional suggestions, please let me know. Along with learning the base knowledge, I'm also reviewing how to help against sql injection (which may not be fully covered in this test).
#------------------ Working Code ------------------#
# pdo options/attributes
$opt = array( PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION );
# data source name
$dsn = "mysql:host=$host;dbname=$dbname";
# basic pdo connection (with added option for error handling)
if ($_SERVER['REQUEST_METHOD'] == "POST") {
if (!$_POST['name'] || !$_POST['email'] || !$_POST['phone'] || !$_POST['detail'] || !$_POST['cost']) {
echo "<p>Please supply all of the data! You may press your back button to attempt again minion!</p>";
exit;
} else {
try {
$DBH = new PDO($dsn, $user, $pass, $opt);
$STH = $DBH->prepare("INSERT INTO data (name,email,phone,detail,cost) VALUES (:name,:email,:phone,:detail,:cost)");
$STH->bindParam(':name', $_POST['name']);
$STH->bindParam(':email', $_POST['email']);
$STH->bindParam(':phone', $_POST['phone']);
$STH->bindParam(':detail', $_POST['detail']);
$STH->bindParam(':cost', $_POST['cost']);
$STH->execute();
} catch (PDOException $e) {
echo $e->getMessage();
}
echo "<p>Data submitted successfully</p>";
}
}
echo '<form method="POST" action="">';
echo '<p>Enter the below information if you want to live:</p>';
echo 'Name: <input type="text" name="name"><br />';
echo 'E-mail: <input type="text" name="email"><br />';
echo 'Phone: <input type="text" name="phone"><br />';
echo 'Order will be generated randomly<br />';
echo 'Description: <input type="text" name="detail"><br />';
echo 'Cost: <input type="text" name="cost"><br />';
echo '<input type="submit" value="Do-It"></form>';
# close the connection
$DBH = null;
?>
To check if the request is POST type use $_SERVER['REQUEST_METHOD'] Documentation
// Get POST variables
$name = isset($_POST['name']) ? $_POST['name'] : '';
$name = isset($_POST['email']) ? $_POST['email'] : '';
$name = isset($_POST['phone']) ? $_POST['phone'] : '';
$name = isset($_POST['detail']) ? $_POST['detail'] : '';
$name = isset($_POST['cost']) ? $_POST['cost'] : '';
If($_SERVER['REQUEST_METHOD'] == "POST") {
Try{
Remainder of code
Switch the ordering from the following
$STH->bindParam(':name', $name);
$STH->bindParam(':email', $email);
$STH->bindParam(':phone', $phone);
$STH->bindParam(':detail', $detail);
$STH->bindParam(':cost', $cost);
$name = $_POST['name'];
$email = $_POST['email'];
$phone = $_POST['phone'];
$detail = $_POST['detail'];
$cost = $_POST['cost'];
to
$name = $_POST['name'];
$email = $_POST['email'];
$phone = $_POST['phone'];
$detail = $_POST['detail'];
$cost = $_POST['cost'];
$STH->bindParam(':name', $name);
$STH->bindParam(':email', $email);
$STH->bindParam(':phone', $phone);
$STH->bindParam(':detail', $detail);
$STH->bindParam(':cost', $cost);
or simply use:
$STH->bindParam(':name', $_POST['name']);
$STH->bindParam(':email', $_POST['email']);
$STH->bindParam(':phone', $_POST['phone']);
$STH->bindParam(':detail', $_POST['detail']);
$STH->bindParam(':cost', $_POST['cost']);
This is not an answer but a form validation function that could be of help.
I'm sure there are multiple ways of achieving this, but it will surely get you started.
$name = $_POST['name'];
$email = $_POST['email'];
$phone = $_POST['phone'];
$detail = $_POST['detail'];
$cost = $_POST['cost'];
if (isset($_POST['submit'])) {
if (empty($name) || empty($email) || empty($phone))) || empty($detail))) || empty($cost)) {
// do something
exit;
}
if (!empty($name) || !empty($email) || !empty($phone))) || !empty($detail))) || !empty($cost)) {
// do something else
// for example, write the data in database
exit;
}
}
Why would you let the user send a blank form? Handle the "please supply all of the data" warning on the client side with javascript. Don't allow the form to get past javascript without fulfilling all of the requirements.
I'm having a very annoying problem. Whenever I edit a post, the first time it gets edited, it will lose all of its information. I can't figure it out, I've worked on it for 2 days.
Heres the form code:
<?php
$post = htmlspecialchars($_GET["id"]);
$name = $_SESSION['Username'];
if (in_array($name, $allowedposters)) {
$results = mysql_query("SELECT * FROM tool WHERE id = $post");
while($row = mysql_fetch_array($results)){
$title= $row['title'];
$details= $row['details'];
$date= $row['date'];
$author= $row['author'];
$id= $row['id'];
echo "<a href=story.php?id=";
echo $post;
echo ">Cancel edit</a> <br><br><b>";
echo $title;
echo "</b> <br><br>";
echo '
<form action="edit-new.php?story=';
echo $id;
echo '" method="post" enctype="multipart/form-data">
<textarea rows="1" cols="60" name="title" wrap="physical" maxlength="100">';
echo $title;
echo '</textarea><br>';
?>
<textarea rows="30" cols="60" name="details" wrap="physical" maxlength="10000">
<?php
echo $details;
echo '</textarea><br>';
echo '<label for="file">Upload featured image:</label><br>
<input type="file" name="file" id="file" />';
echo'<br><input type="submit" />';
}
} else {
echo "Not enough permissions.";
}
?>
.
.
Here is the actual php code, inserting information into the database:
.
.
<?php
$post = $_GET['story'];
$title = $_POST['title'];
$details = $_POST['details'];
echo 'Updated.';
$dbtype = "mysql";
$dbhost = "localhost";
$dbname = "x";
$dbuser = "xx";
$dbpass = "xxx";
$conn = new PDO("mysql:host=$dbhost;dbname=$dbname",$dbuser,$dbpass);
$sql = "UPDATE tool SET title=:title, details=:details WHERE id = '$post'";
$q = $conn->prepare($sql);
$q->execute(array(
':details'=>$details,
':title'=>$title,
));
?>
Again, I would like to mention, the only problem is that, the first time I edit the post, it will lose its information. It will never happen to that specific post after that.
The editing works flawlessly, after that.
This doesn't directly answer your question - it would be useful to know what you're actually getting for $_GET['id'], what actual SQL is running on your database and what the generated content of your form looks like.
However:
$post = htmlspecialchars($_GET["id"]);
Is wrong. htmlspecialchars escapes data for output to the client. Encoding special characters for SQL is not going to protect you from SQL injection attacks.
Since $post is expected to be an integer (presumably), this is sufficient:
$post = (int)$_GET['id'];
But be sure to check that a valid integer is returned, and throw an appropriate error if not.
Don't forget to do this again in edit-new.php - even better, use a parametized value like you have done for title and details.
Finally, you should use htmlspecialchars to escape $details and $title in the form. Otherwise content like </textarea> will not be displayed correctly and you are vulnerable to XSS flaws (e.g. followed by <script>alert("I'm going to do bad things now");</script>