Account activation PHP - php

I created this account registration activation script of my own, I have checked it over again and again to find errors, I don't see a particular error...
The domain would be like this:
http://domain.com/include/register.php?key=true&p=AfRWDCOWF0BO6KSb6UmNMf7d333gaBOB
Which comes from an email, when a user clicks it, they get redirected to this script:
if($_GET['key'] == true)
{
$key = $_GET['p'];
$sql = "SELECT * FROM users
WHERE user_key = '" . $key . "'";
$result = mysql_query($sql) or die(mysql_error());
if(mysql_affected_rows($result) > 0)
{
$sql = "UPDATE users
SET user_key = '', user_active = '1'
WHERE user_key = '" . $key . "'";
$result = mysql_query(sql) or die(mysql_error());
if($result)
{
$_SESSION['PROCESS'] = $lang['Account_activated'];
header("Location: ../index.php");
}
else
{
$_SESSION['ERROR'] = $lang['Key_error'];
header("Location: ../index.php");
}
}
else
{
$_SESSION['ERROR'] = $lang['Invalid_key'];
header("Location: ../index.php");
}
}
It doesn't even work at all, I looked in the database with the user with that key, it matches but it keeps coming up as an error which is extremely annoying me. The database is right, the table and column is right, nothing wrong with the database, it's the script that isn't working.
Help me out, guys.
Thanks :)

Change $_GET['key'] == true to $_GET['key'] == "true"
You do before this if, a successful mysql_connect(...) or mysql_pconnect(...) ?
Change mysql_affected_rows($result); to mysql_num_rows($result);. Affected you can use for DELETE or UPDATE SQL statements.
Before you second if was opened, add before you second mysql_result(...), mysql_free_result($result); to free memory allocated to previous result.
if($result) change to if(mysql_affected_rows($result));. You can do that here.
After the header(...); function call's add a return 0; or exit(0); depends on your complete code logic.
You are using $key variable in SQL statements, to get your code more secure on SQL Injection attacks get change $key = $_GET['p']; to $key = mysql_real_escape_string($_GET['p']);
I think your location in header() functions fails. In header() url address should be full like: http://www.example.com/somewhere/index.php
And check your $_GET['p'] variable exists!! If this not exist and if $_GET['key'] exists, you find all activated users. Then i think the setting user_key to '' is nessesary if you have user_activated marker.

you shouldnt be using:
if(mysql_affected_rows($result) > 0)
You should be using mysql_num_rows()

Your problem is:
$result = mysql_query($sql) or die(mysql_error());
"or" makes your statement boolean so $result gets a True instead of value returned by mysql_query()
echo 'Hello' or die('bye'); // outputs nothing, because result is True not 'Hello'
3 or die() == True; // true
3 or die() != 3; // true
OR is the same as || and it is operator of logical statement.
This will work:
$result = mysql_query($sql);
if(!$result) die(mysql_error());
The same mistake was made a few hours ago: link
Cases where OR can be used:
defined('FOO') or
define('FOO', 'BAR');
mysql_connect(...) or die(...);
mysql_select_db( .... ) or die(...);
mysql_query('UPDATE ...') or die(...);
if(FOO or BAR) { ... }

Related

If statement is not working correctly

This is my first topic so far in this great webpage
The problem is this:
I'm scripting an UCP (PHP & MySQL based). I want it to show the user's status like score, money, etc. (Yeah, it's for a game) but when I click on the login button nothing happens it just erases the content of the requested fields.
It was working properly before I made some changes (Checking if the username exists)
Here's the code:
if (isset($_POST['login']))
{
$hashedpass = hash('whirlpool', $password);
$query = "SELECT * FROM users WHERE Username = '$playername' AND Password = '$hashedpass'";
$result = mysql_query($query);
$num = mysql_num_rows($result);
mysql_close();
if($num != 0)
{
echo"Account doesn't exist!";
header("Location: ucp.html");
}
else
{
$name=mysql_result($result,$i,"UserName");
$money=mysql_result($result,$i,"Money");
$score=mysql_result($result,$i,"Score");
$wantedlevel=mysql_result($result,$i,"WantedLevel");
$adminlevel=mysql_result($result,$i,"AdminLevel");
echo "<b>$name</b><br>Money: $money<br>Score: $score<br>Wanted Level: $wantedlevel<br>Admin Level: $adminlevel<br><br>";
}
}
else if (isset($_POST['register']))
{
header("Location: register.html");
}
else
{
header("Location: index.html");
}
if($num != 0)
change to:
if($num == 0)
This simply won't work here nor does it make much logical sense:
$num = mysql_num_rows($result);
mysql_close();
if($num != 0)
{
echo"Account doesn't exist!";
header("Location: ucp.html");
}
First the logic is wrong, if $num is NOT equal to 0 then your query MUST have found at least one account. So you need to change your if statement to:
if($num == 0){ //if 0 rows were found - the account was not found thus it doesn't exist
echo "Account doesn't exist!";
}
Notice also i did not add header("location: ucp.html");. You cannot display output + relocate the user to another page. You either do one or the other, or you will get an error/warning.
Finally check your MYSQL is not causing an error by adding a check at the end with :
$result = mysql_query($query) or die(mysql_error());
Final tip, you should avoid using mysql_* and look into mysqli_* or PDO best explained here:
Why shouldn't I use mysql_* functions in PHP?

mysql_affected_rows not working

I use a mysql_affected_rows on a query but it seems to return false even though the query did execute so i'm a bit confused....
This is what i have:
$check = mysql_query("DELETE FROM $table
WHERE name = '".$darray[0]."' AND
password = '".$darray[1]."' AND uid = '$uid'
AND validation = '22'")
or die(mysql_error());
if(mysql_affected_rows($check)>0){
echo 1;
exit;
} else {
echo 'Less than one!';
exit;
}
Any idea why it says less than one - even though my query did actually delete the row ?
mysql_affected_rows() takes the link identifier (i.e., the connection resource), not the result.
mysql_affected_rows takes in a connection link, not a query. You can leave that parameter empty and it will refer to the last query executed on that connection.
Solved:
Error was that mysql_affected_rows() doesn't expect the query.
More info here: http://php.net/manual/es/function.mysql-affected-rows.php
$check = mysql_query("DELETE FROM $table
WHERE name = '".$darray[0]."' AND
password = '".$darray[1]."' AND uid = '$uid'
AND validation = '22'")
or die(mysql_error());
if(mysql_affected_rows() >0){
echo 1;
exit;
} else {
echo 'Less than one!';
exit;
}

Session variables in PHP

Hey guys, Im doing a series of if statements based on a session variable that is set (which looks at a value in the DB and then decides whether to empty the session, or name it. However I'm having problems in that the session is always named, regardless of whether the record in the database is '0' or not. The query works fine when run in mysql. Here's the code:
session_start();
$_SESSION['MemberType'] = '';
mysql_select_db($database_choices, $choices);
$query = "Select lifemember from registrants where username = '" . $_SESSION[kt_login_user] . "'";
$result = mysql_query($query) or die ("Error in query: $query. ".mysql_error());
while($row = mysql_fetch_array($result))
{
if ($row['lifemember'] == '1')
{
$_SESSION['MemberType'] = 'LifeMember';
}
else if($row['lifemember'] == '0')
{
$_SESSION['MemberType'] = '';
}
}
Precheck: If you are getting any 'Headers already sent...' then you have some output already on the page which is preventing the setting of session.
Otherwise try debugging steps like:
1) Do an echo $row['lifemember'] inside the while loop so that you know REAL value of what's been fetched from DB.
2) In else block, change it to $_SESSION['MemberType'] = 'Hello'; Then see, whether Hello is printed or not?

my "remember me"-feature

Finally I have got this function to work. It does its job but it looks real messy, just wanna hear your thoughts and maybe theirs something I could improve?
Thanks alot!
Login
$result = mysql_query("SELECT * FROM users WHERE username = '".mysql_real_escape_string($_POST['username'])."' AND password = '".md5($_POST['password'])."'");
$row = mysql_fetch_object($result);
if (mysql_num_rows($result) == 0) {
exit('Bad Login');
}
$_SESSION['id'] = mysql_result($result, 0, 'id');
# The user wants to be remembered
if (isset($_POST['remember'])) {
$key = md5(uniqid());
setcookie('remember', $key, time()+900000); /* expire in 10 days */
mysql_query("UPDATE users SET sessionkey = '$key' WHERE id = ".mysql_result($result, 0, 'id'));
}
And on each page I check:
if (isset($_SESSION['id'])) {
header("Location: welcome.php");
}
elseif (isset($_COOKIE['remember'])) {
$rs = mysql_query("SELECT * FROM users WHERE sessionkey = '$_COOKIE[remember]'");
if (mysql_num_rows($rs) == 1) {
$_SESSION['id'] = 1;
header("Location: welcome.php");
}
}
Put the code that checks if the number of rows is zero before the mysql_fetch_object($result) statement. That way, you don't waste that extra CPU cycle if the user doesn't exist.
Change this (in both places):
mysql_result($result, 0, 'id');
to
$row->id;
Also, if your id column isn't sanitary (i.e.: the user has entered some data for it at some point), you're going to want to escape it in your UPDATE query.
Just a matter of preference on this one, but when I check URL parameters existance, I like to use !empty() instead of isset. The reason is that if the parameter is set but empty, it will still return false:
!empty($_POST['remember'])
Also on that note, be sure to sanitize $_COOKIE['remember']. Cookie values can be changed by the user.
mysql_query("SELECT * FROM users WHERE sessionkey = '" . mysql_real_escape_string($_COOKIE[remember]) . "'");
Lastly, it might be a good idea not to select * in your query, as this can bump you up against a performance wall later on in your app. Consider just selecting, say, the ID of the user:
mysql_query("SELECT id FROM users ...
Everything else looks pretty good!
I'm no PHP expert, but there's probably an off-the-shelf solution for session management - I would suggest using it over rolling your own.

PHP/MySQL update a news record in a database problem

I have this PHP code that I am trying to use to let a user edit a news record in a form and then when they hit the submit button, it will update the record in a database. The problem is that everything works but the record is not actually updated in the database.
Could someone look at my code and see where a problem could occur?
<?php
$title = "Edit News";
include("../includes/header.php");
include("../includes/database.php");
$done = false;
$expected = array('newstitle', 'newscontent', 'id');
if ($_GET && !$_POST) {
if (isset($_GET['id']) && is_numeric($_GET['id'])) {
$id = $_GET['id'];
}
else {
$id = NULL;
}
if ($id) {
$sql = "SELECT * FROM news WHERE id = $id";
$result = mysql_query($sql) or die ("Error connecting to database...");
$row = mysql_fetch_assoc($result);
}
// if form has been submitted, update record
if (array_key_exists('update', $_POST)) {
// prepare expected items for insertion into database
foreach ($_POST as $key => $value) {
if (in_array($key, $expected)) {
${$key} = mysql_real_escape_string($value);
}
}
// abandon the process if primary key invalid
if (!is_numeric($id)) {
die('Invalid request');
}
// prepare the SQL query
$query = "UPDATE news SET title = '$title', content = '$content' WHERE id = $id";
// submit the query
$done = mysql_query($query) or die("Error connecting to database...");
}
}
// redirect page if $id is invalid
if ($done) {
header("Location: $ROOT/admin/listnews.php");
exit;
}
?>
if ($_GET && !$_POST) {
...
if (array_key_exists('update', $_POST)) {
Won't that ensure the update code never fires?
If you run that UPDATE from the mysql cli with the same data the user sends does it update?
If not check for escaping characters.
Should $content and $title in the line below be $newstitle and $newscontent?
// prepare the SQL query
$query = "UPDATE news SET title = '$newstitle', content = '$newscontent' WHERE id = $id";
It's a little hard to know exactly what's going on without seeing the HTML source of your form, but I think that the
if (array_key_exists('update', $_POST)) {
block needs to be moved out of the outer if, since it will never be executed if it's there.
If you don't want to use some sort of testing framework, print() is your friend when it comes to debugging your code. Try to find what's executing and what's not; you'll quickly discover which of your assumptions are incorrect, and therefore where the bug is.
Take this if statement out of the nested if:
if (array_key_exists('update', $_POST)) {
...
}
and then add this conditional:
if (count($_POST) && array_key_exists('update', $_POST)) {
...
}
I'm pretty sure that will take care of your problem.
Couple of things to try and narrow down the problem:
echo out some debug text just inside the if (array_key_exists('update', $_POST)) block to make sure you're actually getting in there. The top of your "if" is if($_GET && !$_POST), so you may need to change this $_POST to $_GET
have you tried echoing out $query just before the db call? Does it run on the command line mysql interface ok?
if my reading of your foreach ($_POST as $key => $value) is correct, you'll end up setting variables with the same names as those in $expected - ($newstitle, $newscontent, $id) - but in your sql reference $content and $title. They may be the cause of this bug, but something to keep an eye out for.

Categories