I'm new to PHP but normally able to solve most problems but this one has got me.
I'm trying to create a newsletter sign up (single field) with a single submit button. I have this working fine, sending out an email and inserting the form data into my table. However I want to add functionality to have a confirmation email send to the person who signs up. I've done extensive research and I know the method behind this but my code just is not inputting data into my 2nd table used to store the confirmation information.
I have 2 tables:
Table 1 named 'newsletter' columns are:
idmail,emailaddress,datetime,state
idmail is set to AUTO_INCREMENT
Table 2 named 'confirm' columns are:
idconfirm,emailaddress,confirmkey
Here is my code (I've omitted the email part which goes after this as that all work OK):
//connect to database
include('admin/connection.php');
$email = mysqli_real_escape_string($dbc, $_POST['email']);
//check if value exists in table
$result = mysqli_query($dbc, "SELECT emailaddress FROM newsletter WHERE emailaddress = '$email'");
if (mysqli_num_rows($result)==0) {
//Insert value into database
$query1 = mysqli_query($dbc, "INSERT INTO newsletter(emailaddress, datetime, state) VALUES('$email','$now','0')");
mysqli_query($dbc, $query1);
// Get ID of last record
$id = mysqli_insert_id($dbc);
//Create a random key
$hash = $email.date('mY');
$hash = md5($hash);
//Insert value into database
$query2 = mysqli_query($dbc, "INSERT INTO confrim(idconfirm, emailaddress, confirmkey) VALUES('$id','$email','$hash')");
mysqli_query($dbc, $query2);
When I submit an email address, the first table is populated correctly.
The goal here is to get the auto ID created in the first INSERT INTO query into a variable then to add that in the 2nd tables column named 'idconfim'.
I tried:
echo $id;
echo $email;
echo $hash;
and all of the variables hold the correct information.
Does anyone have any ideas?
I've tried to many things to list here, but I've researched this and I just don't know where I'm going wrong.
Thanks in advance.
I'm posting my comment as an answer here:
The problem here is this $query2 = mysqli_query($dbc,... '$hash')"); mysqli_query($dbc, $query2); and you should have gotten an error about that. This besides the possible typo for the table name confrim.
You need to remove mysqli_query($dbc, $query2); here and replace it with:
if($query2){ echo "Success"; }
else{ echo "Error: " . mysqli_error($dbc);
(Another edit): You did the same error here:
$query1 = mysqli_query($dbc, "INSERT INTO newsletter ... '$now','0')");
mysqli_query($dbc, $query1);
and needs to be changed to:
if($query1){ echo "Success"; }
else{ echo "Error: " . mysqli_error($dbc);
As stated in comments by RiggsFolly; don't use MD5 to hash passwords, it's no longer safe. A lot of water's run under the bridge in over 30 years.
Use password_hash() http://php.net/manual/en/function.password-hash.php and a prepared statement.
Edit: It looks to me now that after looking at your code again, that you're not trying to save a password, but more as a confirmation key. If that is the case, then you can disregard the password stuff. However, if you do decide to use MD5 to store passwords with in the future, don't.
One of the problems is that you aren't showing the MySQL error, if there is one. So you need to either check the server logs for the error in PHP, you can force to print the error to the error log or do something else:
for example:
mysqli_query($dbc, $query2) or error_log(mysqli_error($dbc));
mysqli_query($dbc, $query2) or custome_error_handler(mysqli_error($dbc));
As well php should be returning an HTTP error to the client. You should be catching that error.
Once you see the SQL error it will be easy to figure out what you did wrong.
EDIT Fred ii caught the real error, but I think the error would have been thrown the first time the mistake is made:
mysqli_query($dbc, $query1);
$query1 isn't a string. And if you noticed you already executed the query on the line above. Reading the PHP error logs will show you exactly where the error is.
Sorry for wasting time.
Thanks to jeffery_the_wind for pointing me to the logs. I will use them in future.
The problem was TWO spelling mistakes, one in the column name in the php and one on the mysql database. confrim is not a word! I'm slightly lexdixlick!
Thanks for your prompt responses.
Related
Context
I'm trying to implement a (hopefully) simple login system using PHP and PostgreSQL.
This is the postgres table containing usernames and hashed passwords.
Users are not meant to be able to create new rows in this table so I already hashed the passwords using password_hash('password', PASSWORD_BCRYPT) and then manually copypasted the value in the table.
Let me know if you think this could pose a problem.
Users can, however, login to an already existing account by inputting the right username and password combination into a login form.
When the login button is pressed I need to retrieve information about the user entered, so that if it matches any user I can then verify the password using password_verify().
The Problem
When the login button is clicked I run this code:
$dbconn = pg_connect("host=host dbname=dbname user=user password=pwd");
if (!$dbconn) {
die("Error in connection: " . pg_last_error());
}
// setting the username as it would be provided by the form field
$username = 'Dan';
// maybe unrelated: why do I need to write 'username' instead of username? all of my other queries work without ''
$query = "SELECT * FROM user WHERE 'username' = $1";
$stmt = pg_prepare($dbconn, "", $query);
var_dump($stmt); // gives output "resource(3) of type (pgsql result)", got no clue on how to see what's indside
$result = pg_execute($dbconn, "", array($username));
var_dump($result); // gives output "resource(4) of type (pgsql result)"
$row = pg_fetch_assoc($result);
var_dump($row); // gives output "bool(false)", indicating that pg_fetch_assoc() failed
The main problem would be that pg_fetch_assoc() fails and returns false, however I believe this may also be caused by an incorrect query or by the way I build the statement, hence why I included everything.
Edit
Forgot to mention that I also tried formulating the query as:
$query = "SELECT * FROM user WHERE username = $1";
And in this case I get and error saying:
Warning: pg_prepare(): Query failed: ERROR: column "username" does not exist LINE 1: SELECT * FROM user WHERE username = $1.
Thanks to Don't Panic's comment I renamed my user table to utiliser and everything worked as it should have.
It should also be noted that this could be circumvented by using double quotes on the table name (according to this answer), however, double quotes are evil so better to just stay away.
Here's the full table of reserved words to avoid as table/column names.
$query = "INSERT INTO users ". "(first_name,last_name,dob,mobile_number,landline_number,email) ". "VALUES('$fname','$sname','$dob','$mobile','$landline','$email', NOW())";
$query = "INSERT INTO address ". "(house_number,street_name,town/city,postcode,province/county) ". "VALUES('$hnumber','$addr','$town','$pcode','$county', NOW())";
$result = mysqli_query($conn, $query) or die("Invalid query 2"); // runs query using open connection
So I can create a connection to my database no problem and on my previous page I can send username and password to the database but then I come to the user details page to save the information and continually getting Invalid query 2 error. The table names are correct (users & address) and all variables are spelt correctly. Does anyone have a suggestion to fix the issue or a better alternative (I mean to just point me in the right direction of the research I should be looking at if I am way off target, if I have just mispelled something or have something in the wrong place then I would appreciate the heads up, have been at this quite a while now)
This is the code from the previous page and it works fine and sends the information to the database:
$query = "INSERT INTO login ". "(username,password) ". "VALUES('$uname','$epass', NOW())";// sets up sql query
$result = mysqli_query($conn, $query) or die("Invalid query 2"); // runs query using open connection
mysqli_close($conn); // close database connection
As far as I know all the database side of things is fine, all data types are varchar except for dob which is date (I have tried changing this to varchar to see if it fixed the problem but it didnt) and userID is int and is an autoincrement for the unique primary key. I have also tested the php file without the validation rules and still gives the same error.
Quite a few things wrong here.
First you are reassigning the variable $query; so the first insert will be getting overwritten by the second, you need to concat the variable.
Then you have 2 queries you are attempting to send at one time. However you never tell Sql you've finished your first before starting your second.
Try the following instead take note Of The semi colons ; at the end of each.
You are also putting slashes into your column names which is illegal.
Lastly, you've got more values to insert than you have columns. Remove the now() from the end.
$query = "INSERT INTO users ". "(first_name,last_name,dob,mobile_number,landline_number,email) ". "VALUES('$fname','$sname','$dob','$mobile','$landline','$email');";
$query .= "INSERT INTO address ". "(house_number,street_name,town_city,postcode,province_county) ". "VALUES('$hnumber','$addr','$town','$pcode','$county');";
Although this will now work, I highly recommend you do some research regarding safe practices with Sql.
Here would be a great starting point https://www.w3schools.com/php/php_mysql_prepared_statements.asp
On a side note, why are you concating your Strings? There's no need
$query = "INSERT INTO users (first_name,last_name,dob,mobile_number,landline_number,email) VALUES('$fname','$sname','$dob','$mobile','$landline','$email', NOW());";
Maybe it's the fact that you are closing the connection after your first call.
try or die(mysqli_error($conn));
EDIT:
Delete passing value "NOW()".
code:
$query = "INSERT INTO address ". "(house_number,street_name,town_city,postcode,province_county) ". "VALUES('$hnumber','$addr','$town','$pcode','$county')";
I've read all the questions or at least lots of them and what I see is lots of code that for a beginner like me doesn't help a lot...
Probably, you will say that I'm a noob to start making my own webpage with login, register, and all that stuff and I also see people talking about giving up on mysql stuff to avoid sql injection and all of those security details.
All I need to know is a simply a thing about 1 code I'm getting wrong.
$mail = mysql_query("select email from users where username = '".$_SESSION['username']."'");
This is the variavel I have made to get the email of the actual user in the logged in session.
When I put your email is <?php echo"$mail".; ?>, it gives me the next detail:
your email is Resource id #8.
Why am I getting that? I've made the variable in a place with session started but I don't get what I have in that column on the specified user.
Sorry if I shouldn't post that in here, but I really don't see anyone with the same problem. All I see is complex codes and I really don't understand a lot of that.
I'm still a beginner, so if you guys can give me an hand, I will be grateful.
You have to use mysql_fetch_[array|object|assoc] PHP function
$res = mysql_query("select email from users where username = '".$_SESSION['username']."'");
$field = mysql_fetch_assoc($res);
echo $field['email'];
You have to fetch the returning rows of your query:
$row = mysql_fetch_assoc($query/$mail);
All the columns you queried will be in the array $row now.
print "Email: " . $row['email'];
This example assumes the query only returned one row.
If you were to query for several rows, you have to call mysql_fetch_assoc each time you wanted a new row:
while($row = mysql_fetch_assoc($query)) {
Good luck.
Take what you need.
$user = strip_tags($_SESSION['username']);
$sql = sprintf("SELECT FROM email WHERE username='%s'", mysql_real_escape_string($user));
$result = mysql_query($sql);
$row = mysql_fetch_array($result);
$mail = $row['email'];
echo "Your email is" .$mail;
The strip_tags() method will remove any HTML tags in the submitted entry.
I like to use the sprintf() method when making single row queries because it's a lot faster to just paste and change attribute names then worry about using the correct quote syntax.
Once your query is process you need to fetch the results then you can access the data inside the tables.
I hope this helps you out.
I am a newbie in PHP and i am trying to create a system where user will add firstname, lastname and email address. Basically what i am trying to do is verify if the e-mail already exists in database or not.
Have been working for hours but it doesn't work. But when i try to verify the firstname and lastname they both works.
But with email field ... the code cannot compare that there are duplicate values. There are lot of duplicate email Id in the database but the code ignores that and inserts the value :/. Meanwhile if i try verifying for duplicate firstname and lastname it works
Any help please :(
$firstname=$_POST['firstname'];
$lastname=$_POST['lastname'];
$email=$_POST['email'];
$firstname= stripslashes($firstname);
$lastname= stripslashes($lastname);
$email= stripslashes($email);
$host="localhost";
$user="root";
$pass="";
$db="site";
$link=mysql_connect($host,$user,$pass);
mysql_select_db($db,$link);
$test="SELECT * FROM email_list WHERE email = '$email' ";
$select=mysql_query($test);
if(mysql_num_rows($select)>0)
{
echo "Email already exists".$email."<br>";
echo "Please enter another email";
}
else
{
$query="INSERT into email_list (first_name, last_name, email) values ('$firstname', '$lastname', '$email')";
mysql_query($query);
echo "values entered" .$firstname. "<br>". $lastname. "<br>". $email;
}
First of all as you can read from the comments below your question mysql_* isn't recomended any longer. try mysqli_* functions instead if you like the procedural approach, but that is besides the point.
Your code as it is above seems without any obvious error but inserting raw input into a database is a dangerous thing - you should (at the minimum) change your INSERT and SELECT statemens so all the textual input is enclosed in mysql_real_escape_string() function.
The select statement would then look like this:
"SELECT * FROM email_list WHERE email = '".mysql_real_escape_string($email)."' ";
That will not change the behaviour of your code, it will only make sure, that if someone enters nonsense into $email field it will be saved as entered (without crashing your code) or if they try to "hack" (inject) your mysql queries they will not succeed in doing so.
I am guessing here from (as i do not have too much information to work with) that your email field in email_list table is too short - and saving only maybe first 16 characters of any entered email address - which in turn will not help you determining whether an email address exists because you are comparing the entered joe#test.com with joe#test.c (that in case if your email field was defined as char(10)
Basic debugging steps:
mysql_query() can fail. You don't test it. Test it:
$select=mysql_query($test);
if(!$select){
die(mysql_error());
}
If mysql_num_rows() is never greater than zero, you should find out what it is:
var_dump(mysql_num_rows($select));
This function does not work with all possible configurations.
You run a SELECT query? Aren't you curious about the result set? Grab and print all rows.
Additionally:
There's more SQL than SELECT * FROM table. If you want to count, you can count in SQL:
SELECT COUNT(*) AS dupes FROM email_list
You are using a MySQL extension that will be removed when the next major PHP release comes out.
I see stripslashes() out there. The magic quotes feature is annoying, useless and deprecated.
Make sure you read and understand How to prevent SQL injection in PHP?.
I strongly agree with the one who points out that mysql_query and mysql in general should be avoided (also because they're going to deprecate it sooner or later). You want to switch to MySQLi or whatever else. This said, you're not checking for errors. Does the connection to database fail? You'll never know. Does $test fail? You'll never know either.
Try to debug with an "or die()" (N.B.: or die(); is strongly discouraged! However, if its' not used in production it'll suffice it).
mysql_select_db($db,$link) or die("cannot open db");
$select=mysql_query($test) or die ("cannot select the email");
EDIT: to check if the email is in the database, you probably need a function to do that. Or, if you don't want to put it into a function, try to edit this way
$test="SELECT * FROM email_list WHERE email = '$email' ";
$select=mysql_query($test);
if(mysql_num_rows($select)!=0) //different from 0
{
echo "Email already exists".$email."<br>";
echo "Please enter another email";
}
I hope this helps.
Everything looks okay but Check your defined length of email on your db, if it matches the one you're sending then try and print the email being accepted on your form. Like
Print $email ;
And I'll advice you change all names of "mysql" to "mysqli"
I enclosed the '$email' variable in parentheses and it worked for me.
$test= "SELECT Password FROM persons WHERE Email=('$email')";
Im a php/mySQL newbie and am trying to get the hang of it. I have code to detect whether i get a username/password match, and now im trying to get the userid field so i can update the record. Heres what I have so far:
$sql = "SELECT username FROM users WHERE username='$username' AND password='$password'";
$result = $link->query($sql) or die(mysqli_error());
Using print_r($result) shows that there is an item, but im lost from here on out.
Try this.
$sql = "SELECT username FROM users WHERE username='$username' AND password='$password'";
$result = $link->query($sql) or die(mysqli_error());
while ($row = mysqli_fetch_array($result, MYSQLI_ASSOC)) {
$userID= $row['username'] ;
// If you need other field as userID just change the sql and the index of $row according to that.
}
EDIT
If you want to get only one row.
if($result->num_rows==1)
{
$row = $result->fetch_array(MYSQLI_ASSOC);
$userID = $row["username"];
}
Perhaps this will help. In any programming language, running an SQL query is going to consist of these steps:
Build the text of the SQL statement that you want to run.
(Optional) If your statement involves the use of parameters (or "placeholders"), prepare an array of the parameter-values that are to be substituted for each of them.
("Prepare" and...) "Run" the query, on some previously-opened "database connection." (In your example, "$link" must correspond to that connection.) This gives you a handle (you called it "$result") that corresponds to the zero-or-more rows that were returned by that query.
Now, use that handle to retrieve each of these rows, one at a time, until there are no more or until you're tired of doing it.
(Optional) Be neat and tidy and "close" the handle, thus indicating to the database system that it can discard all of the resources it was using to furnish those rows to you.
"Those, in simple terms, are the basic steps that every program in the known universe are going to go through," and if you now browse again through the PHP documentation, you'll see that there are functions that correspond to each of these steps. Browse through the chapters you've been reading and see if you can now match the up to the scenario I just described. HTH...