I've been working for the past 5 hours on why does this if get triggered...
Let me show you the code and explain you :
<?php
require_once "ConnectDB.php";
$link2 = $link;
$key = $posthwid = "";
$err = "";
if($_SERVER["REQUEST_METHOD"] == "POST"){
if(empty($_POST["key"])){
$err = "Thanks for the ip (" .$_SERVER['REMOTE_ADDR']. "), have a good day! (1)";
}
else{
$key = trim($_POST["key"]);
}
$hwid = $_POST["hwid"];
if(empty($err)){
$sql = "SELECT hwid, idkey, length, created_at FROM money WHERE idkey = '" .$key. "'";
$row = mysqli_query($link, $sql);
if(mysqli_num_rows($row) < 2){
while($result = mysqli_fetch_assoc($row)) {
if($result["idkey"] == $key)
{
$err = "key";
if($result["hwid"] == "")
{
$err = "nohwid";
$sql2 = "UPDATE IceCold SET hwid = '" .$hwid. "' WHERE idkey = '" .$key. "'";
if(mysqli_query($link2, $sql2)){
$hwid = $result["hwid"];
mysqli_close($link2);
echo "debug";
}
else {
$err = "Oops! Something went wrong. Contact the support.";
}
}
if ($hwid !== $result["hwid"]) {
$err = "Contact the support";
}
elseif($_SESSION["admin"] == true) {
//Do special stuff
}
else {
///do other checks
if($created_at > $date){
$err = $hwid;
} else {
$err = "The key date is too old, buy a new one.";
}
}
}
else{
$err = "The key you entered was not valid.";
}
} mysqli_close($link);
} else {
$err = "multiple entry, contact support";
}
}
} else {
$err = "Thanks for the ip (" .$_SERVER['REMOTE_ADDR']. "), have a good day! (3)";
}
echo $err;
?>
So basically, I have this Connect DB file with a mysqli_connect called $link and I'm designing a liscence API for my program. My program will send a request with the "idkey" and "hwid" and is waiting for the hwid to come back. I have an entry in my sql databse with only a key registered and I've trying to make my program wotk by generating POST request with the id and a random hwid but I've found no success. If variables are weirdly moved around, It's because of the debugging.
Right now, with my current setup, I get the Contact the support response which I don't understand why?!? The request and the key are correct if I'm able to get this awnser.
It's probably a stupid mistake but I jsut can't figure it out...
Thanks in advance for your help
Edit: the if statement I'm referring to is this:
if($hwid !== $result["hwid"])
There was a typo in the code that I fixed but it wasn't the issue,
as for the elseif, that would destroy the order of execution of the code and destroy the logic behind it(If that made sense).
Weirdly, after some tests, I found out that the second SQL request I send doesn't want to be executed ($sql2) and there is no error in httpd logs... Can you execute two requests? I tried to create $link2 but it doesn't change anything
EDIT : Found solution
if($result["hwid"] == "")
{
$sql2 = "UPDATE money SET hwid = '" .$_POST["hwid"]. "' WHERE idkey = '" .$key. "'";
if(mysqli_query($link2, $sql2)) {
$newhwid = $_POST["hwid"];
mysqli_close($link2);
}
else {
$err = "Oops! Something went wrong. Contact the support.";
}
}
elseif ($_POST["hwid"] != $result["hwid"]) {
$err = "Contact the support";
}
if($_POST["hwid"] == $newhwid || $_POST["hwid"] == $result["hwid"] ) {
/// do other checks
}
The condition before that one, if($row['hwid'] = ""), is an assignment. This code is changing the value of $row['hwid'] to an empty string, causing the condition after it to be true. I assume you meant to write == to test if $row['hwid'] is empty; otherwise it doesn't make sense to write this as an if statement.
By the way, it's not clear whether this if statement shouldn't be an else if. The rest of the branches here are else if (or elseif, which is the same in PHP), so you should consider whether you have missed out an else on this one too.
When user clicks on the Save, check whether the data is successfully inserted record to the table, and display a proper message accordingly. If forms are empty then the error message should be shown and database should not have any record.
//SAVE
if (isset($_POST['SAVE'])) {
$Name = $_POST['name'];
$City = $_POST['city'];
$query = "Insert Into Info Values('$Name','$City')";
$result = mysqli_query($con, $query) or die ("query is failed" . mysqli_error($con));
$Name = '';
$City = '';
if(mysqli_affected_rows($con)>0) {
echo "record is saved";
}else {
echo "record is not saved";
}
I can only do validation through php. I am not sure if I am doing this right. So far I can get the "record is saved" message on my form, but I cannot get the latter if the form are empty. It just make an empty record in my database.
Untested Code:
if (!isset($_POST['SAVE'], $_POST['name'], $_POST['city'])) { // avoid Notices
echo "Missing required submission data";
} elseif (!strlen(trim($_POST['name']))) { // validate however you wish
echo "Name data is not valid"; // explain however you wish
} elseif (!strlen(trim($_POST['city']))) { // validate however you wish
echo "City data is not valid"; // explain however you wish
} elseif (!$con = new mysqli("localhost", "root", "", "db")) { // declare and check for a falsey value
echo "Connection Failure"; // $con->connect_error <-- never show actual error details to public
} elseif (!$stmt = $con->prepare("INSERT INTO Info VALUES (?,?)")) {
echo "Error # prepare"; // $con->error; // don't show to public
} elseif (!$stmt->bind_param("ss", $_POST['name'], $_POST['city'])) {
echo "Error # bind"; // $stmt->error; // don't show to public
} elseif (!$stmt->execute()) {
echo "Error # execute"; // $stmt->error; // don't show to public
} else {
echo "Insert Successful";
}
The validation conditions on the submission data ensure that the values are not empty and they are not completely comprised of whitespace characters. If you wish to refine the validation requirement further, just update the conditions.
If you want to simply ensure that $_POST['name'] and $_POST['city'] are not empty, you can replace the first three conditionals with
if (empty($_POST['SAVE']) || empty($_POST['name']) || empty($_POST['city'])) {
echo "Submission data is missing/invalid";
}...
If you don't use a prepared statement, then name values like Paul O'Malley will break your query. Worse, if someone wants to try to run some injection attacks, your query is vulnerable.
Checking affected_rows() is unnecessary. If there is no error message from the query execution, the INSERT query was a success.
The above suggestions are all best practices which I urge you to adopt.
Checking isset($_POST['SAVE']) only tells you if "SAVE" is set. It does not tell you if the fields have values.
To do the validation in PHP, use something like the following:
if (isset($_POST['SAVE'])) {
$Name = $_POST['name'];
$City = $_POST['city'];
if ($Name && $City)
{
//...
//code to insert data into the database goes here
//...
if(mysqli_affected_rows($con)>0) {
echo "record is saved";
}else {
echo "record is not saved (error saving)";
}
} else {
echo "record is not saved (input was empty)";
}
}
The key being the if ($Name && $City) check.
Alternately, if you want to rely on mysql to reject the insert on blank values, then make sure the fields in the mySql table are not nullable and then change this part of your code: (but this would be moving the validation to MySql)
$Name = $_POST['name']?$_POST['name']:null;
$City = $_POST['city']?$_POST['city']:null;
The data is not inserting into another table, here's the code below :
if (isset($_POST))
{
$job = $_POST['jobtitle'];
$dur = $_POST['duration'];
$deg = $_POST['requireddegree'];
$exp = $_POST['experiance'];
$sal = $_POST['salary'];
$mark = $_POST['marks'];
if ( !empty($job) && !empty($dur) && !empty($deg) && !empty($exp) && !empty($sal) && !empty($mark))
{
$dur = mysql_real_escape_string($dur);
$deg= mysql_real_escape_string($deg);
$exp = mysql_real_escape_string($exp);
$sal = mysql_real_escape_string($sal);
$mark = mysql_real_escape_string($mark);
$job = mysql_real_escape_string($job);
$query="INSERT INTO jobposting (duration,degree,experiance,salary,marks,Jobtitle) VALUES ('".$dur."','".$deg."','".$exp."','".$sal."','".$mark."','".$job."') ";
if ($query_run= mysql_query($query))
{
header('location : Main.html');
}
else
{
echo ' Data not Inserted! ';
}
}
With this it gives me server error or there was an error in CGI script.But when I write the variables in this form '$dur' instead of '".$dur." then the else conditon runs after insert query and displays data is not inserted.
However, i have written the same logic while inserting data in my another table and it inserts successfully.But there I put '$dur'.
I can't find the problem.Will be glad for your suggestions :)
I can't seem to find any other error by seeing this code expect for
$query="INSERT INTO jobposting (duration,degree,experiance,salary,marks,Jobtitle) VALUES ('$dur','$deg','$exp','$sal','$mark','$job') ";
//Use ".$job." only for stuff like '".md5($_POST['password'])."' otherwise this creates problem some times.
// Adding this always helps
if(!mysqli_query($con,$query))
{
die('error'.mysqli_error($con));
}
// in $con = $con=mysqli_connect("localhost","root","");
else
{
if ($query_run= mysql_query($query))
{
header('location : Main.html');
}
else
{
echo ' Data not Inserted! ';
}
}
I think by making these changes and making sure that your db name and other basic stuff are correct then you should be good to go otherwise, specify your exact error.
As you can see in the script below, I use multiple if statements when checking registration inputs. Is there an easier, less spaghetti?
The script works as is, but i would like it to be neater.
<?php
if (isset($_POST['register'])) {
$uname = trim($_POST['uName']);
$email = trim($_POST['email']);
$pass = trim($_POST['pass']);
$passCon = trim($_POST['passCon']);
$uname = strip_tags($uname);
$email = strip_tags($email);
$pass = strip_tags($pass);
$passCon = strip_tags($passCon);
if (!empty($pass)) {
if (!empty($email)) {
if (!empty($uname)) {
if ($pass == $passCon) {
$query = "SELECT username FROM users WHERE username='$uname'";
$result = mysqli_query($conn, $query);
$checkUsername = mysqli_num_rows($result);
if ($checkUsername == 0) {
$query = "SELECT email FROM users WHERE email='$email'";
$result = mysqli_query($conn, $query);
$count = mysqli_num_rows($result);
if ($count == 0) {
$password = hash('sha256', $pass);
$queryInsert = "INSERT INTO users(id, username, email, password, date) VALUES('', '$uname', '$email', '$password', '" . time() . "')";
$res = mysqli_query($conn, $queryInsert);
if ($res) {
$errTyp = "success";
$errMsg = "successfully registered, you may login now";
}
} else {
$errTyp = "warning";
$errMsg = "Sorry Email already in use";
}
} else {
$errTyp = "warning";
$errMsg = "Sorry Username already in use";
}
} else {
$errTyp = "warning";
$errMsg = "Passwords didn't match";
}
} else {
$errTyp = "warning";
$errMsg = "You didn't enter a Username";
}
} else {
$errTyp = "warning";
$errMsg = "You didn't enter an email address";
}
} else {
$errTyp = "warning";
$errMsg = "You didn't enter a password";
}
}
Thank you,
Jay
The problem you are facing is not at all uncommon. Many programmers have faced this issue. Let me help you along the way restructuring your script.
First of all, let's get rid of the nested if-else statements. They confuse and obfuscate what is really going on.
Version 1:
if (!isset($_POST['register']))
redirect('register.php'); // Let's assume that redirect() redirects the user to a different web page and exit()s the script.
$uname = $_POST['uName'];
$email = $_POST['email'];
$pass = $_POST['pass'];
$passRepeat = $_POST['passRepeat'];
if (empty($pass)) {
$errorMessage = "You didn't enter a password";
}
if (empty($email)) {
$errorMessage = "You didn't enter an email address";
}
if (empty($uname)) {
$errorMessage = "You didn't enter a Username";
}
if ($pass !== $passRepeat) {
$errMsg = "Passwords didn't match";
}
$query = "SELECT username FROM users WHERE username='$uname'";
$result = mysqli_query($conn, $query);
$checkUsername = mysqli_num_rows($result);
if ($checkUsername !== 0) {
$errMsg = 'Sorry Username already in use';
}
$query = "SELECT email FROM users WHERE email='$email'";
$result = mysqli_query($conn, $query);
$count = mysqli_num_rows($result);
if ($count !== 0) {
$errMsg = 'Sorry Email already in use';
}
$password = hash('sha256', $pass);
$queryInsert = "INSERT INTO users(id, username, email, password, date) VALUES('', '$uname', '$email', '$password', '" . time() . "')";
$res = mysqli_query($conn, $queryInsert);
Note that although this avoids the nested if statements, this is not the same as the original code, because the errors will fall through. Let's fix that. While we are at it, why would we want to return after the first error occurs? Let's return all the errors at once!
Version 2:
$errors = array();
if (empty($pass)) {
$errors[] = "You didn't enter a password";
}
if (empty($email)) {
$errors[] = "You didn't enter an email address";
}
if (empty($uname)) {
$errors[] = "You didn't enter a username";
}
if ($pass !== $passRepeat) {
$errors[] = "Passwords didn't match";
}
$query = "SELECT username FROM users WHERE username='$uname'";
$result = mysqli_query($conn, $query);
$usernameExists = mysqli_num_rows($result) > 0;
if ($usernameExists) {
$errors[] = 'Sorry Username already in use';
}
$query = "SELECT email FROM users WHERE email='$email'";
$result = mysqli_query($conn, $query);
$emailExists = mysqli_num_rows($result) > 0;
if ($emailExists) {
$errors[] = 'Sorry Email already in use';
}
if (count($errors) === 0) {
$password = hash('sha256', $pass);
$queryInsert = "INSERT INTO users(id, username, email, password, date) VALUES('', '$uname', '$email', '$password', '" . time() . "')";
$res = mysqli_query($conn, $queryInsert);
redirect('register_success.php');
} else {
render_errors($errors);
}
Pretty clean so far! Note that we could replace the if (empty($var)) statements with a for-loop. However, I think that is overkill in this situation.
As a side note, please remember that this code is vulnerable to SQL injection. Fixing that issue is beyond the scope of the question.
Less spaghetti? Start with functional decomposition, then work towards separating the task of sanitation from that of validation. I will leave out many steps that I take (such as verifying the form / $_POST / filter_input_array() has the correct number of inputs, and the correct keys are in the $_POST superglobal / INPUT_POST, etc, you might want to think about that.). Alter some of my techniques for your exact needs. Your program should be less spaghetti afterwards. :-)
Sanitize then validate. You have to keep them separated, so to speak. ;-)
Sanitizing with Functional Decomposition
Make a single task its own block of code.
If all of your sanitization steps (trim(), strip_tags(), etc.) are the same for all of your form fields, then make a sanitizer function to do that work. Note, that the one-time way you are trimming and stripping tags can be improved upon simply by using a loop. Save the original value in a variable, then trim(), strip_tags(), etc within a while loop. Compare the results to the original. If they are the same, break. If they differ, save the current value of the form field in your variable again and let the loop run again.
function sanitize($formValue)
{
$oldValue = $formValue;
do
{
$formValue = trim($formValue);
$formValue = strip_tags($formValue);
//Anything else you want to do.
$formValue = trim($formValue);
if($formValue === $oldValue)
{
break;
}
$oldValue = $formValue;
}
while(1); //Infinite loop
return $formValue;
}
Then, simply run this function in a loop.
$sanitized = [];
foreach($_POST as $key => $value)
{
$sanitized[$key] = sanitize($value);
}
/* You can keep track your variable anyway you want.*/
Looking further down the road, it is times like this where devising an input source ($_POST, $_GET, $_SESSION, $_FILES, $_COOKIE, etc..) based sanitizing, class hierarcy really comes in handy. Moreover, basing that class hierarchy on the use of filter_input_array() really puts you a head of the game. What about validation?
Validating with Functional Decomposition
You could look at each form field as needing its own validating function. Then, only the logic required to check one form field will be contained within the block. The key, retain your Boolean logic by having the validator functions return the results of a test (true / false).
function uname($uname, &$error)
{
if(! /* Some test */)
{
$error = 'Totally wrong!'
}
elseif(! /* Another test */)
{
$error = 'Incredibly wrong!'
}
else
{
$error = NULL;
}
return !isset($error) //If error is set, then the test has failed.
}
function email($email, &$error)
{
if(! /* Some test */)
{
$error = 'Totally wrong!'
}
elseif(! /* Another test */)
{
$error = 'Incredibly wrong!'
}
else
{
$error = NULL;
}
return !isset($error) //If error is set, then the test has failed.
}
function pass($pass, &$error)
{
if(! /* Some test */)
{
$error = 'Totally wrong!'
}
elseif(! /* Another test */)
{
$error = 'Incredibly wrong!'
}
else
{
$error = NULL;
}
return !isset($error) //If error is set, then the test has failed.
}
function passCon($passCon, &$error)
{
if(! /* Some test */)
{
$error = 'Totally wrong!'
}
elseif(! /* Another test */)
{
$error = 'Incredibly wrong!'
}
else
{
$error = NULL;
}
return !isset($error) //If error is set, then the test has failed.
}
In PHP, you can use variable functions to name your function the same as the fields they are checking. So, to execute these validators, simply do this.
$errorMsgs = [];
foreach($sanitized as $key => $value)
{
$key($value, $errorMsgs[$key])
}
Then, generally speaking, you just need to see if there are any errors in the $errorMsgs array. Do this by processing the $errorMsgs array
$error = false;
foreach($errorMsgs as $key => $value)
{
if(isset($value))
{
//There is an error in the $key field
$error = true;
}
}
..and then.
if($error === true)
{
//Prompt user in some way and terminate processing.
}
// Send email, login, etc ....
Taken further, you could create a generic, Validator, super class.
All this being said. I do all of my sanitization and validation in an object oriented way to reduce code duplication. The Sanitizer super class has children (PostSanitizer, GetSanitizer, ....). The Validator super class has all the test one might perform on a string, integer, or float. Children of the Validator superclass are page/form specific. But, when something like a form token is needed, it's validating method is found in the Validator super-class because it can be used on any form.
A good validation routine keeps track of:
1) Input values in an associative array..
2) Test results (Booleans) in an associative array. Test results (true/false) can be converted to CSS classes or a JSON string of '1's and '0's.
3) Error messages in an associative array.
..then makes final decisions about what to do with the input values and/or error messages based on the test results (by key). If there are errors (false values in the a hypothetical test results array), use the error messages that have the corresponding key.
My previous example condenses the final error checking and error message data structures with one array, but using separate data structures allows more flexibility (decouples error messages from the detected errors). Simply store the results of each validating variable function into a $testResults array like this.
function sanitize($formValue)
{
$oldValue = $formValue;
do
{
$formValue = trim($formValue);
$formValue = strip_tags($formValue);
//Anything else you want to do.
$formValue = trim($formValue);
if($formValue === $oldValue)
{
break;
}
$oldValue = $formValue;
}
while(1); //Infinite loop
return $formValue;
}
$sanitized = [];
foreach($_POST as $key => $value)
{
$sanitized[$key] = sanitize($value);
}
$testResults = [];
$errorMsgs = [];
foreach($sanitized as $key => $value)
{
$testResults[$key] = $key($value, $errorMsgs[$key])
}
if(!in_array(false, $testResults, true))
{
return true //Assuming that, ultimately, you need to know if everything worked or not, and will take action on this elsewhere. It's up to you to make the correct functions/methods, but this general foundation can get you going.
}
return false; //Obviously. Do not submit the form. Show the errors (CSS and error messages).
Then, simply check for the existence of false in the $testResults array. Get the corresponding error message from $errorMsgs using the appropriate $key. Using this generic, final stub, you can create a powerful santization and validation routine, especially if you go object oriented.
Eventually, you will begin to see that the same kinds of test are being repeated among the various validation variable functions: data type, length, regular expression, exact matches, must be a value within a set, etc. Thus, the primary difference between the validating variable functions will be the minimum and maximum string lengths, regex patterns, etc... If you are savvy, you can create an associative array that is used to "program" each variable function with its set of validation parameters. That's getting a bit beyond the scope, but that is what I do.
Thus, all my variable functions perform the same basic tests via factored out logic using a method of class Validator called validateInput(). This method receives the following arguments
1) The value to be tested.
2) An associative array of the test parameters (which can specify datatype)
3) An array element, passed in as a variable (by reference), that corresponds the field being tested that will hold the error message, if any.
What's funny, is that I use a two step sanitization and a two step validation. I use a custom filter algorithm using PHP functions, then I use the PECL filter functions (filter_input_array()). If anything fails during these steps, I throw a SecurityException (because I extend RuntimeException).
Only after these filters pass do I attempt to use the PHP/PECL filter valiation functions. Then, I run my own validation routine using validating, variable functions. Yes, these only run if the previous test passed as true (to avoid overwriting previous failures and corresponding error message).
This is entirely object oriented.
Hope I helped.
(Sorry for my bad english)
Well, I've 3 errors in my code.
Error's:
First of all it's show : Notice: Undefined index: form in C:\xampp\htdocs\evantechbd\index.php on line 461. When i run this form.
if any error found it's show error message, well, but correct field is empty. Example: In this form there is 4 fields. a) upload image, b) select discussion c) subject and d) message. Suppose you upload a image, select a discussion and write a subject but forgot to write message. Then It's show "Message Required" and every filed is empty. I don't want empty field which is correct.
After successfully submitted the form it's show "Discussion was submitted ". But after that if i refresh the page it's send the data to database. But I did not click submit button. why this happen?
Here is my code:
<?php
if ($_POST['form'] == "Submit") {
$err = array();
$filed = addslashes($_FILES['file']['tmp_name']);
$img_named = addslashes($_FILES['file']['name']);
$img_type = addslashes($_FILES['file']['type']);
#$imgd = addslashes(file_get_contents($_FILES['file']['tmp_name']));
function getExtension($str)
{
$i = strrpos($str, ".");
if (!$i) {
return "";
}
$l = strlen($str) - $i;
$ext = substr($str, $i + 1, $l);
return $ext;
}
$extension = getExtension($img_named);
$extension = strtolower($extension);
$image_named_uniq = uniqid() . '.' . $extension;
$upload_path_dis = 'user/manage/discussionimg/';
$diss = $_POST['type'];
$sub = $_POST['sub'];
$msg = $_POST['msg'];
$date = "On " . date("F Y h:i:s A");
if (!isset($_SESSION['uname']))
$err[] = "You need to login";
else {
$uname = $_SESSION['uname']; //session username
if (empty($sub) && empty($msg) && empty($filed))
$err[] = "All field required";
else {
if (empty($sub))
$err[] = "Subject Requried";
if (empty($msg))
$err[] = "Message Requried";
if (empty($filed))
$err[] = "SORRY, you have to be upload a image";
}
}
if (!empty($err)) {
foreach ($err as $er) {
echo "<font color=red>$er</font><br/>";
}
}
else {
$sql = mysql_query("INSERT INTO discussion VALUES ('', '$imgd', '$image_named_uniq',
'$diss', '$sub', '$msg', '$uname', '$date' ) ");
if (!$sql)
echo "Can't submit your discussion" . mysql_error();
if (!move_uploaded_file($_FILES['file']['tmp_name'], $upload_path_dis . $image_named_uniq)) {
die('File Not Uploading');
} else {
echo "Discussion was submitted";
}
}
}
?>
Many Thanks for your help!!
Kanta.
Try changing your first if condition as follows
if (isset($_POST['submit']))
Now most of web sites uses client side validations using javascript. You can use jquery frame work to make things easier. However since you already uses validations after the POST event. You have to set values to relevant fields as bellow code. It will set tha value of the subject.
<input type="text" name="sub" value="<?php if(isset($_POST["sub"])) echo $_POST["sub"]; ?>" size="46"/>
Yes if you refresh the code it will again do the post and insert. You have to do few controls. However these things depend on your data.
a. Make unique key indexes in the database
b. Check for existing record before the insertion.
c. Redirect your page to the same page after few seconds once the user see the successful message.