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.
Related
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.
I'm trying to output a simple list with all the usernames registered on a single e-mail address in our database. The SQL queries necessary for it shouldn't be too hard, but apparently they are too hard for me - here's my issue:
$sql = "SELECT emailaddress FROM ".db_prefix("accounts")." where acctid = '$mailid'";
$mailadress = db_query($sql);
That one's working just fine - I'm declaring mailid in a earlier part of the code, and with that query I can output the e-mail adress (for debugging) of the currently logged in user without any problems. Fine so far.
$sql = "SELECT name FROM ".db_prefix("accounts")." where emailadress ='$mailadress'";
$charakterliste = db_query($sql);
Here's the issue: $charakterliste seems to stay empty, even though I'm pretty sure my syntax is correct. var_dump() and print_r() don't return anything that would point towards the array/variable containing something.
I've double checked and executed a similar query directly in the SQL database and found no problems there - all the fields I'm calling do exist, and the DB connection is fine too. I guess something is wrong in my syntax for the second SQL query? I'd want to list all the names saved in the $charakterliste afterwards with a foreach loop, but as of now there doesn't seem to be anything to list saved in there, although there should be.
Thanks in advance!
Are you sure the column 'emailadress' exist?
Maybe it's 'emailaddress' with two 'd'?
According to your first line of code it should be 'emailaddress'.
$sql = "SELECT name FROM ".db_prefix("accounts")." where emailaddress ='$mailadress'";
$charakterliste = db_query($sql);
When you authenticate registered users you make request e.g. one examples i found:
$user = $_POST['user'];
$pw = $_POST['password'];
$sql = "SELECT user,password FROM users
WHERE user='$user'
AND password='$pw'
LIMIT 1";
$result = mysql_query($sql);
if (mysql_num_rows($result)){
//we have a match!
}else{
//no match
}
Now what would be the benefit or any point of having LIMIT 1 at the end?
And why you need to select user and password when you can just select user_id?
Would not the
SELECT user_id FROM users
WHERE user = '{$user}'
AND password = '{$pw}'
be same exact logistics but shorter code?
EDIT: thinking about this little detail made me find one more check to prevent hackers.
There should not be more than one user with same email and password so if they somehow supply instead of password 123 e.g. string ' OR password = '*' (or similar logics) this will compromise my query, having no limit would help because next step i can count
if (count($result) > 1) {
echo "we got hacked";
else
<proceed...>
Assuming you have only a single row in the database for each username/password pair, the LIMIT clause improves performance by discontinuing the search after the first match is found, primarily when used in conjunction with an ORDER BY clause.
From the MySQL manual:
If you use LIMIT row_count with ORDER BY, MySQL ends the sorting as soon as it has found the first row_count rows of the sorted result, rather than sorting the entire result. If ordering is done by using an index, this is very fast.
Most likely, you will have a unique user column, so LIMIT 1 is not necessary - you won't have more than 1 row anyway.
In this case, it might be a decorative element - self explaining syntax to tell a programmer that reads a code, that query is expected to return no more than one row.
Aside from your question, I would strongly recommend to use some password encryption, for example MD5(). A tutorial that teaches you to store a plain passwords is not the best one...
You can read "SQL Injection: How To Prevent Security Flaws In PHP / MySQL" and see how your login might be useless without proper measures.
Everything else was answered by far wiser posters above.
In most cases your table will hold unique usernames so you will always get back 1 or 0 rows. And as such as far as your code is concerned it doesn't make a difference. Even if you had multiple rows returned your code would still work, as you are only checking for existence of rows and not how many of them have been returned (but it would be wrong, as you wouldn't know which user actually logged in).
Basically it just tells MySQL to stop searching the table after the first row that meets the conditions in WHERE is found. In some cases even this could be redundant (if you had a UNIQUE index on the "user" field for instance).
One more thing not related to your question: please do not use this code for anything but learning. It's full of security holes. Google for "SQL injection" and "storing password securely" before you put this code into production.
Firs you need to sanitize strings from injection:
class main{
public function sanitize($str,$remove_nl=true)
{
stripslashes($str);
if($remove_nl)
{
$injections = array('/(\n+)/i',
'/(\r+)/i',
'/(\t+)/i',
'/(%0A+)/i',
'/(%0D+)/i',
'/(%08+)/i',
'/(%09+)/i'
);
$str = preg_replace($injections,'',$str);
}
return $str;
}
}
Next yours code:
$main_class = new main();
$user = $main_class->sanitize(trim($_POST['user']));
$pw = $main_class->sanitize(trim($_POST['password']));
$sql = "SELECT * FROM `users` WHERE `user`='".$user."' AND `password`='".$pw."' LIMIT 0,1";
$result = mysql_query($sql) or die(mysql_error());
$count = mysql_num_rows($result);
if($count > 0){
//we have a match!
}else{
//no match
}
I am doing a really simple script to delete a row out of a database. I have done it before with almost identical code but for some reason this wont work!
Viewmessages.php has no problem running but when I try and delete the row using deletemessage.php I receive the an sql error, I only have one line of sql:
viewmessage (sending info to deletemessage.php):
echo "<a href='deletemessage.php?contactname=".$contactname."'>Delete</a>";
The following is the delete message code:
<?php
session_start();
if ( !isset($_SESSION['adminusername']))
{
header("Location:admin.php");
exit();
}
require "dbconn.php";
$contactname = $_GET['contactname'];
$query = "DELETE FROM message WHERE contactname =".$contactname;
$results = mysql_query($query) or die(mysql_error());
header("Location: viewmessages.php");
?>
I cant work out what the error is! $contactname in the viewmessages.php file definately speaks of the primary key for the table!
Any Ideas?>
EDIT: I know that the problem lies with the contactname in the sql... for some reason it is not recieving it well, I did an echo to see what it thought the contactname was and it was correct. I then changed the variable and put in a string of one values in contactname and it deleted the row correctly... so the problem is the GET_['contactname'] but I am not sure what....
Enclose $contactname in quotes in the query, since it is a string. But escape it first! It is highly vulnerable to SQL injection the way it is now. I understand it may be an administrative page, but it is a very good habit to always observe, even when your users are trusted. (Especially since Mr O'Malley would break the SQL statement when you tried to delete him)
$concatname = mysql_real_escape_string($_GET['contactname']);
$query = "DELETE FROM message WHERE contactname ='".$contactname . "'";
Always beware when deleting via a hyperlink. Looks like you are checking for admin privileges before allowing this to execute, but be sure these links are not accessible to the broad Internet, where they might get crawled.
Wild guess here? $contactname is a STRING. Therefore it must be in quotes in the query. Also, you want people to destroy your database, apparently.
$query = "DELETE FROM `message` WHERE `contactname` = '".mysql_real_escape_string($contactname)."'";
You need quotes around a string you're inserting.
$query = "DELETE FROM message WHERE contactname ='".$contactname."'";
Note that this is MASSIVELY vulnerable to SQL injection. Someone could delete your entire database table with this code as it stands.
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...