...

View Full Version : My variables don't carry over from functions.



Auax
05-08-2009, 10:00 PM
I have the function "register()" for a very simple user registration script, but for some reason it doesn't write the variables "$email" and "$veri" to the database.



function sanitize($input) {
//sanitize database input
$input = stripslashes($input);
$input = mysql_real_escape_string($input);
}

function veri($input) {
//generates a hash to use for verification
$random = rand();
$data = $input . $random;
$veri = md5($data);
}

function register($email, $password) {
//registers a new user
//secure the password, no data grabbing plz
$password = md5($password);
//secure the email, no injection plz
$email = sanitize($email);

//generate initial verification hash
veri($email);

$query = "INSERT INTO users VALUES (NULL, '" . $email . "', '" . $password . "', '" . $veri . "', 0)";
mysql_query($query) or die(mysql_error());
}

2Pacalypse
05-08-2009, 11:07 PM
You got it slightly wrong :(
Try this template (not the exact thing


<--the table:-->
INSERT INTO `users`

<--the area you want to insert to:-->
(`email` ,`password` ,`verify`)

<--the actual values-->
VALUES ('".$email."', '".$password."', '$veri."');


Note make sure the "area" and actual value are respective. ie/ if you want to add something like username, make sure if it is the 4th "area", it is the 4th value!

Fou-Lu
05-09-2009, 12:29 AM
You got it slightly wrong :(
Try this template (not the exact thing


<--the table:-->
INSERT INTO `users`

<--the area you want to insert to:-->
(`email` ,`password` ,`verify`)

<--the actual values-->
VALUES ('".$email."', '".$password."', '$veri."');


Note make sure the "area" and actual value are respective. ie/ if you want to add something like username, make sure if it is the 4th "area", it is the 4th value!

This is not accurate, there is nothing in SQL that defines that fields have to be presented in an insert query. They are only required if you're not inserting every field or if the order is different than specified.

Functions take a scope of their own when created. That means any variable defined within a function is function dependent, and when the function stack pops the variables are destroyed.

You're sanitize method is returning void. This call $email = sanitize($email); sets the value of $email to null. This call veri($email); doesn't assign the value to anything, nor does the veri function return a result.

Options are as follows. Use a reference in you're function signatures:


function sanitize(&$input) {
//sanitize database input
$input = stripslashes($input);
$input = mysql_real_escape_string($input);
}

function veri(&$input) {
//generates a hash to use for verification
$random = rand();
$data = $input . $random;
$veri = md5($data);
}

These will physically alter the original data given to them. This is not recommended.
The better option is to return a result, so sanitize should have a return $input;, and veri should have an return $veri; and the call should be assigned to a variable within the register function.

Now, this still won't work. Sanitize will fail since it doesn't an open scope to a mysql connection resource. Fix with a global call to you're $connection variable, or whatever it is named, or even better - pass it into the method as well. Stripslashes also should only be used of get_magic_quotes_gpc() returns true, otherwise you'll be stripping data that may have been intended.

Auax
05-09-2009, 01:14 AM
So would this be acceptable?



function sanitize(&$input) {
//sanitize database input
doconnect();
$input = stripslashes($input);
if(get_magic_quotes_gpc()) {
$input = mysql_real_escape_string($input);
}
return $input;
}

function veri(&$input) {
//generates a hash to use for verification
$random = rand();
$data = $input . $random;
$veri = md5($data);

return $veri;
}

function register($email, $password) {
//registers a new user
//secure the password, no data grabbing plz
$password = md5($password);
//secure the email, no injection plz
sanitize($email);

//generate initial verification hash
veri($email);

$query = "INSERT INTO users VALUES (NULL, '" . $email . "', '" . $password . "', '" . $veri . "', 0)";
mysql_query($query) or die(mysql_error());
}


doconnect() calls my sql connection function, but do I need that if I've already got an sql connection outside the function?

Also, if you could explain what the ampersand does? I don't understand what it's for.

Fou-Lu
05-09-2009, 02:15 AM
& is the addressof operator. It passes a variable by pointer and not by value letting you operate on the original.
No this won't work. I'll fix it:


function sanitize($input)
{
//sanitize database input
doconnect();
if (@get_magic_quotes_gpc())
{
$input = stripslashes($input);
}

$input = mysql_real_escape_string($input);
return $input;
}

function veri($input)
{
//generates a hash to use for verification
$random = rand();
$data = $input . $random;
$veri = md5($data);

return $veri;
}

function register($email, $password)
{
doConnect();
//registers a new user
//secure the password, no data grabbing plz
$password = md5($password);
//secure the email, no injection plz
$email = sanitize($email);

//generate initial verification hash
$veri = veri($email);

$query = "INSERT INTO users VALUES (NULL, '" . $email . "', '" . $password . "', '" . $veri . "', 0)";
mysql_query($query) or die(mysql_error());
}


If you have a specific connection in use, you can either globalize it in a function:


function myfunc()
{
global $dbConnect;

which should actually be avoided, or signature you're methods to use it as a parameter:


function register($dbConnect)
{
}

register($myConnection);



I just tested this, it looks like resources are autoglobals.
That means you don't need to use you're doConnect function or globalize you're connection object in you're functions. But you do need to make sure that a connection is open and available or the mysql_real_escape_string will not work.

Auax
05-09-2009, 02:51 AM
Perfect! Thank you!

Auax
05-09-2009, 03:16 AM
I'm not sure if this is because of a similar problem, but if you could help me with this it'd be appreciated.



function doesExist($data, $table, $feild) {
//checks to see if the data provided exists in the database
//returns 0 if false, 1 if true
$query = "SELECT * FROM " . $table . " WHERE " . $feild . " = " . $data;
$result = mysql_query($query);

if($result == true) {
$doesExist = 1;
} else {
$doesExist = 0;
}

return $doesExist;
}

bdl
05-09-2009, 03:56 AM
@Auax> The reason that function doesn't work is because of the subtlety of mysql_query() (http://www.php.net/mysql_query) return types.

If the function is executing a valid SELECT statement, it will return a MySQL Result Resource, not boolean TRUE. If the SELECT statement fails, it does however, return boolean FALSE. On the other hand, if the query is an INSERT, DELETE, DROP type statement, it does return boolean TRUE or FALSE values. So your function will always return FALSE, since the mysql_query() function call will never return TRUE, even for a valid query.

What you need to do, since you're not actually retrieving data from the SELECT statement, is use a COUNT(*) expression in the SQL statement, that returns a single value: the number of records matched, or zero. Your function can then retrieve this value and your conditional statement can determine if the value is anything greater than zero, returning TRUE or FALSE.

Auax
05-09-2009, 04:01 AM
Ah, I completely forgot about COUNT!

Thank you! :)

But this still doesn't seem to work.



function doesExist($data, $table, $feild) {
//checks to see if the data provided exists in the database
//returns 0 if false, 1 if true
$query = "COUNT(*) FROM " . $table . " WHERE " . $feild . " = " . $data;
$result = mysql_query($query);

if($result <= 1) {
$doesExist = 1;
} else {
$doesExist = 0;
}

return $doesExist;
}


I'm calling it like this:


$email = $_POST['email'];
$pass = $_POST['pass'];
$cpass = $_POST['cpass'];

$feild = "email";
$table = "users";

doesExist($email, $table, $feild);


But when I try to use, or echo out the $doesExist variable, I get nothing.

bdl
05-09-2009, 05:25 AM
You're still doing the same thing. As I mentioned in my previous post (and linked to the PHP manual page), mysql_query() returns either a MySQL Result Resource or FALSE. It does not return TRUE or a value from the query itself. You must use another function to retrieve data from the query, i.e. mysql_result() (http://www.php.net/mysql_result), then compare the value returned from that function in your conditional.

Plus, it's


SELECT COUNT(*) FROM sometable...

Auax
05-09-2009, 05:34 AM
Can you please provide an example?

I've got this... which gives a "not a valid mysql result resource" error.


function doesExist($data, $table, $feild) {
//checks to see if the data provided exists in the database
//returns 0 if false, 1 if true
$query = "SELECT COUNT(*) FROM " . $table . " WHERE " . $feild . " = " . $data;
$result = mysql_query($query);
$num = mysql_num_rows($result);

if($num == 0) {
$doesExist = 0;
} else {
$doesExist = 1;
}

return $doesExist;
}


Edit:
I tried using mysql_result, but I'm not sure what to use for the second parameter.

bdl
05-09-2009, 05:39 AM
Please read the PHP manual page I linked; there are some good examples there, and you should really get used to reading and understanding the function documentation. Additionally, be sure to read through the PHP Language Reference (http://www.php.net/langref) while you're at it.

Auax
05-09-2009, 05:44 AM
Yes, I read the page you linked, and am quite used to reading the reference material.

I asked you to provide an example, because the reference on the official site was unclear for my situation.

bdl
05-09-2009, 05:56 AM
Ok, but just this once. ;)



$sql= 'SELECT COUNT(*) FROM table WHERE condition <> 1';
$res= mysql_query($sql);
// the conditional statement, incorporating mysql_result()
if ( mysql_result( $res, 0 ) > 0 ) {
// at least one record exists that matches the criteria
} else {
// no records match
}


Note that I pass 0 as the second parameter; it's the numeric index of the row returned. In computer science, lists / arrays are indexed beginning at the 'zeroth' element, so the first (and only, in this case) record is record #0. Alternatively you could add an alias to the COUNT() function return and reference that as well, e.g.


$sql= 'SELECT COUNT(*) AS c FROM table WHERE condition <> 1';
$res= mysql_query($sql);
// the conditional statement, incorporating mysql_result()
if ( mysql_result( $res, 0, 'c' ) > 0 ) {


I also noticed in your attempt that you used mysql_num_rows(); note that using mysql_num_rows() in conjunction with a valid SELECT COUNT() statement will always return 1 record, the record that stores the numeric value returned from the COUNT() function. So it's not useful in these cases.

Auax
05-09-2009, 06:00 AM
Ahh, I see!

Thank you. I was concerned that the number used for the second parameter would affect the count.

However, it still tells me it's not a valid result resource.


function doesExist($data, $table, $field) {
//checks to see if the data provided exists in the database
//returns 0 if false, 1 if true
$query = "SELECT COUNT(*) FROM " . $table . " WHERE " . $field . " = " . $data;
$result = mysql_query($query);

if (mysql_result($result, 0) > 0) {
$doesExist = 1;
} else {
$doesExist = 0;
}

return $doesExist;
}

(I am sure the table and field are correct.)

bdl
05-09-2009, 06:46 AM
What does $data represent? If $data is anything other than a numeric type value, then it needs to wrapped in 'quotes'. In fact, it doesn't hurt to wrap numeric values in quotes anyway, so may as well change your SQL statement to include them. While you're at it, make use of those "double quotes":


$query= "SELECT COUNT(*) FROM $table WHERE $field = '$data'";


BTW, you don't need to do assign a value to a temporary variable just to return it. Instead, you can simply do:


if ( conditional statement ) {
return 1;
} else {
return 0;
}

Auax
05-09-2009, 06:56 AM
Still says it's not a valid result resource.

And, I do need to assign the value, because I have to call that variable in a couple locations after using the function.


Edit: The invalid resource was because of a typo. But I still get nothing when I call the variable outside of the function.

All solved. :)

timgolding
05-10-2009, 12:37 AM
If you have a specific connection in use, you can either globalize it in a function:


function myfunc()
{
global $dbConnect;

which should actually be avoided

Why should this be avoided? I had this argument with someone at work the other day who said i should never use global variables. But i didn't listen to him because he couldn't give me a reason why.

So what is the reason?

usually i use parse by reference but if i have a lot of variables that gets messy

Fou-Lu
05-10-2009, 06:42 AM
Why should this be avoided? I had this argument with someone at work the other day who said i should never use global variables. But i didn't listen to him because he couldn't give me a reason why.

So what is the reason?

usually i use parse by reference but if i have a lot of variables that gets messy

This is something that comes from the old C days.
The problem with globals is that they require the same names. While in PHP this isn't as much of a problem, consider it from the extension point of view. We cannot view the compiled extension code, so if they have created a global variable for use, we're expected to make sure its always under that name instead of one of our choosing. This can create problems if you delete a variable and don't remember what it was called. Imagine the hole it would create if a mysql_connection resource required that the connection be called $connection. This would ensure with 100% certainty that any user who knows of this will also know the name of our variable (which may or may not be a problem).
It is also by reference, so if a function decides to dispose of a global variable, it will / may damage what the intentions of the script were.

From a pure PHP point of view, this isn't a problem since the source is interpreted and can be viewed, but with the advent of the phar, I'm not sure how this is going to work (I don't have details on how the phar works exactly, so I don't know if the source is still viewable).

timgolding
05-10-2009, 03:03 PM
This is something that comes from the old C days.
The problem with globals is that they require the same names. While in PHP this isn't as much of a problem, consider it from the extension point of view. We cannot view the compiled extension code, so if they have created a global variable for use, we're expected to make sure its always under that name instead of one of our choosing. This can create problems if you delete a variable and don't remember what it was called. Imagine the hole it would create if a mysql_connection resource required that the connection be called $connection. This would ensure with 100% certainty that any user who knows of this will also know the name of our variable (which may or may not be a problem).
It is also by reference, so if a function decides to dispose of a global variable, it will / may damage what the intentions of the script were.

From a pure PHP point of view, this isn't a problem since the source is interpreted and can be viewed, but with the advent of the phar, I'm not sure how this is going to work (I don't have details on how the phar works exactly, so I don't know if the source is still viewable).

Thanks for your explanation, that makes sense of it.



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum