I have a 3-part registration form using PHP:
page 1 : collects info - has client & server side validation (for blank and invalid fields)
page 2 : collect more info - has server side validation (for blank and invalid fields)
page 3 : saves (db) and sends (email) the registration information
More info:
page 1 : saves all form information into session[registration] before going to page 2
page 2 : redirects to page 1 if session[registration][email] is blank
page 3 : redirects to page 1 if session[registration][email] is blank; destroys session after registration is successful
This has been working fine for the past months until yesterday when around 25 emails were sent to me, with few seconds interval for each. I also checked the database and those registrations were saved. And the registration information are all BLANK (except the auto generated fields like date_added)
I'm puzzled because the email sending and db saving are not supposed to work because of the redirection.
Do you have any idea as to what just happened?
Thanks
How are you checking that the data fields aren't blank before inserting them into the db. Make sure to use empty() to check that the field is blank. If you're using string comparison operator (ie. if ($str != "") ), it can cause unexpected results if the value of $str is false, null, 0, etc...
Edit:
empty() description from manual: http://us.php.net/manual/en/function.empty.php
Return Values
Returns FALSE if var has a non-empty and non-zero value.
The following things are considered to be empty:
* "" (an empty string)
* 0 (0 as an integer)
* "0" (0 as a string)
* NULL
* FALSE
* array() (an empty array)
* var $var; (a variable declared, but without a value in a class)
edit2:
isset() only checks if a variable was assigned a value. If the variable contains an empty string, isset() will return true, because even an empty string has a value ('\0' marks the end of a string in php).
isset() description from manual : http://us3.php.net/manual/en/function.isset.php
isset() will return FALSE if testing a variable that has been set to NULL. Also note that a NULL byte ("\0") is not equivalent to the PHP NULL constant.
comment from manual :
isset doesn't reliably evaluate variables with blank strings (not necessarily NULL).
i.e.
$blankvar = ""; // isset will return true on this.
This is a very common pitfall when handling HTML forms that return blank text fields to the script. You're better off doing this:
if ($var != "")
return true;
else
return false;
This more of a programming practice rather than the function's shortcomings. So if you have a habit of initializing variables you're likely to run into problems with isset() if your code or php project become very large.
The problem is definitely in page 3. As an educated guess I would say, that your "blank"-check if flawed.
You should use ie. a good regexp to test if the email is valid and make sure to remove whitespace before checking the length of the fields (ie - a space is not the same as an empty/blank field)
Is it possible that all those emails were generate by a bot crawling your site?
Can you reproduce the problem by calling curl on any of your pages?
Do any actions require a POST, or are you taking action with a GET?
Related
I was recently placed on a project with some PHP, and I don't know much about PHP. There are a couple instances in the site where upon clicking a button, the user is redirected to another page with some URL parameters. The next page then uses $_GET to get those parameters and move on.
Another issue in the code caused the page to reload the second page without the parameters, so using $_GET would return errors, but with the other issue fixed, I can't think of a reason why the parameters wouldn't be there.
While debugging, I came across advice to always check $_GET using isset(), but theoretically there should never be an instance when those parameters aren't there (otherwise something else is really wrong with the server or the code).
Is it still worth putting in the checks and working out a backup solution, even though there shouldn't be a need for it? I want to make sure I'm not ignoring some other potential issue that I may not be aware of.
It is always good practice+recommended to check your variables before applying any logic.
!empty() is recommended to use instead of isset() because it check both that variable is initialized and have some values too.
In case of array count($array)>0 can be used as a check.
Why to use !empty() check here:- !empty() Vs isset()
If you are expecting or requiring data to be sent via $_GET you should check if it's set. Especially since that data can be easily manipulated. Also like #Alive to Die said !empty() is better.
isset() checks if a variable has a value including ( False , 0 , or
empty string) , but not NULL. Returns TRUE if var exists; FALSE
otherwise. On the other hand the empty() function checks if the
variable has an empty value empty string , 0, NULL ,or False.
This is a bit of a tricky one to explain but I've never come across this before so I've got no idea how to properly approach it. I'm writing a web app that when a form is submitted, it takes two values, the current value and the submitted value.
When the form is submitted, it checks that the new value is not the same as the current value. If that is true, then go through the rest of the process. This is so I'm not updating the database with values that already exist in there.
Problem is I have an assigned to select box. One of the options is unassigned which has a value of 0. But in the following if statement, zero is not treated as a proper value and thus fails the check.
( $newtaskassignee != $taskassignid ) { ... do something ... }
So when $newtaskassignee is 0, the following if statement should be true and carry on what is inside the immediate curly brackets.
However in this statement, zero is ignored and doesn't pass the check. How can I change this so it accepts numbers from 1 to 9 including 0. This checks user IDs so they could be anything so I can't select a range as it increments by 1 per user obviously.
( $newtaskassignee !== $taskassignid )
The extra = will do an exact match and won't take 0 as false but 0.
As PHP has not strong types, there are two sets of equality operators.
one set that focus on value only : == and !=
and
one that focus on value AND type : === and !==
When you compare '' and 0, == will return true as, for PHP, these are same values.
So you may use === comparison operator to ensure that both operands are same value AND type.
Have a look on http://php.net/manual/en/language.operators.comparison.php, and particularly the difference between "equal" and "identical".
Hope this help
I have created a page like account_details.php in which I'm counting the number of times the user visits the page. So for that I have created a file called count_session.php in which the code is like:
<?php
session_start();
if(!isset($_SESSION['counter'])){
$_SESSION['counter'] = 0;
}else{
$_SESSION['counter'] = $_SESSION['counter'] + 1;
}
?>
I include the above file in account_details.php page in which I want the user to see how many times he has visited and it works fine but I don't understand how does it work? I have checked using the echo message inside the first 'if' condition that is if(!isset) and it seems it does not enter that condition instead it enters the else part but then how come it's getting initialized by 0, but when the user visits the account_details.php page the message pops up like "You have visited this page for 1 times". How come it's calculating 0 + 1 when it's not yet initialized anywhere in the count_session.php file. Can anyone please tell me?
This has nothing to do with session variables, as it works the same way for regular variables.
If you write something like $a = $a + 1 and $a is not declared anywhere, PHP considers it as not set, which translates to 0 if cast to int (the same way it translates to false if cast to bool, but that's not relevant in this case). The reason why your variable is cast to int, is that PHP feels the need to, because you are trying to perform a mathematical operation on that variable.
To sum up: PHP detects that you want to add up 2 values, does something like intval($a) (but internally of course) and adds 1 to that. In addition, if you have notices enabled, this should throw you a notice.
Sessions are global to a site (as in hostname) because they are identified by an ID stored in cookies, which are by default sent back to to all URLs under a single domain name. You can restrict that further, but this is the default behavior.
I noticed this weird evaluation yesterday after searching for a few hours in my code for an error. i am passing scores into php, sometimes the score=0 which causes an issue.
send php ?blah=blah&score=0
if(!empty($_REQUEST['score']){
//do database update stuff
}else{
// show entire webpage
}
It works great unless the score=0 the if() will evaluate to false and return the entire webpage to my ajax handler and error. I have temporarily changed !empty to isset but this will cause problems in the future because isset evaluates to true even if the score key is in the url string without a value.
ex: (?blah=blah&score=&something=else)
my question is: what is the best way to recode this to work correctly now and in the future?
edit: there are a few working answers here, i appreciate everyones time. it was difficult to choose an answer
As the manual says, a variable is considered empty() if it has an empty or zero value.
So it will treat your variable wrongly as empty even though 0 is a perfectly acceptable value in your case.
If you need score to be a number, you could use isset() in combination with a is_numeric() check instead:
if((isset($_REQUEST['score']) and (is_numeric($_REQUEST['score'])){
Check out the manual page to see the kinds of values is_numeric() accepts. If score is always an integer, you can also use is_int((int)$_REQUEST['score']) but that will convert invalid input values to 0.
Additionally, as #sightofnick says, it's better to use explicit $_GET or $_POST instead of $_REQUEST.
Re your update:
In that case I would
Do check whether the variable is "0" (string "zero")
If it is "0", make it 0 (integer "zero")
If it is not 0, convert it to an integer (int)$_REQUEST["score"])
If the conversion resulted in 0, it was invalid input - exit
You have a valid integer variable.
empty() will return false if a value is zero. Use isset() or array_key_exists() instead, if you want to check if a variable in an array is set:
if (array_key_exists('score', $_REQUEST)) {...}
Try doing
if (isset($_REQUEST['score']) && ($_REQUEST['score'] !== '')) {
...
}
The isset will handle the presence/absence of the query parameter, and the strict string (!==) comparison will handle the case where the 'score' query is present but has no value. PHP treats all data coming from _GET/_POST/_REQUEST as strings, so this test is 100% reliable.
if(isset($_REQUEST['score']) && $_REQUEST['score'] != ''){
//do database update stuff
}else{
// show entire webpage
}
You may be able to solve that with
if (isset($_REQUEST['score']) && is_numeric($_REQUEST['score'])) {}
That of course if scrore can only contain numeric value
I am new to the concept of empty and null. Whilst I have endeavoured to understand the difference between them, I am more confused. I came across an article at http://www.tutorialarena.com/blog/php-isset-vs-empty.php however I still don't see when you would use isset and empty when validating forms. Seeing that I don't grasp the difference, I don't want to be using the incorrect functions as well as not be able to use the functions in other areas. Can someone give examples that will help me understand? I am very new to coding so would appreciate if someone could give me real world examples and at the same time keep it simply enough for noob to follow.
A variable is NULL if it has no value, and points to nowhere in memory.
empty() is more a literal meaning of empty, e.g. the string "" is empty, but is not NULL.
The following things are considered to
be empty:
"" (an empty string)
0 (0 as an integer)
0.0 (0 as a float)
"0" (0 as a string)
NULL
FALSE
array() (an empty array)
var $var; (a variable declared, but without a value in a class)
Source.
Example
$a is NULL.
$a = '' is empty, but not NULL.
Update
If $a='' is empty but not NULL, when do I use the empty() function and when do I use the isset() function.
isset() will return FALSE is the variable is pointing to NULL.
Use empty() when you understand what is empty (look at the list above).
Also when you say it points nowhere in memory, what does that mean exactly?
It means that $str = '' will be in memory as a string with length of 0.
If it were $str = NULL, it would not occupy any memory.
Null is a placeholder that generally means "no data about this is available".
The use of null for this is just a convention, but a rather widespread one, to the point where some programming languages support the convention directly. The reason this convention exists has IMHO historically to do with "pointers";
many times a procedure will be defined to return a pointer to an answer, and will return what is traditionally called a Null pointer if it could not produce an answer for some reason.
Empty means (if this is a set) that it has no members. That's an explicit answer, and it is very different than "no data about this is available".
In the PHP world, apparantly uninitialized variables have the Null value, and isset on such a variable returns FALSE.
For arrays and strings, PHP follows the convention that "empty" means "has no members" although arrays and strings are not technically sets.
PHP apparantly has this funny idea that 0 and 0.0 are also "empty", by PHP design. That's abusive of the concept of "empty" IMHO: Individual numbers are not sets, so 0 can't reasonably by "empty". THis just leads to obscure programming because it violates the principle of least surprise. I'm sure the PHP designers would are that "zero is the empty number" as some kind of vague analogy; but the if analogy is vague, why bother with it? But then PHP is full of silly ideas.
The table below is an easy reference for what these functions will return for different values. The blank spaces means the function returns bool(false).
refer this link for more https://www.virendrachandak.com/techtalk/php-isset-vs-empty-vs-is_null/
NULL is a special value which explicitly states that the variable has not been set to any value yet. Be careful with using the empty() function as you can't just determine that a variable is exactly NULL using it. For example the empty() function will return true if an int is set to 0. If you need to make sure a variable is exactly NULL use if($variable == NULL).
For more info on empty() see http://php.net/manual/en/function.empty.php
There are some good answers here, which I won't repeat. In the case of validating forms, though, when a form is submitted, the value of each form input element is sent to the server in the $_POST variable. You can check for the existence of a particular input by using isset().
isset($_POST['username'])
If this returns true, then this request to the server was the result of posting a form containing an input element named "username". Now that we know that we have a value for that form element, we can see if it has a valid value. empty() will tell us whether the user actually entered any data in the field, or whether they left it empty.
empty($_POST['username'])
If that returns true then the form submitted to the server had a field named "username" but the user didn't enter anything into before submitting the form.
Been awhile since i used PHP but if other languages are anything to go by empty will indicate an existing object/map/array that has no contents while null would indicate a variable that has no meaning/definition at all (uninitialised).
In database SQL, NULL means "no value".
The empty() is a nice fast way to see if the variable holds any useful info... that is for strings empty() returns true for a string of "" as well as a null string.
So you can write something like this:
if (! empty($name)) echo $name;
More info see here: PHP: empty()
isset() returns true if both these conditions are met:
The variable has been defined and has not yet been unset.
The variable has a non-null value in it.
A variable is automatically defined when it gets set to something (including null). This has a direct implication in arrays.
$a=array();
$a['randomKey']=true;
$a['nullKey']=null;
var_dump(isset($a['randomKey'])); // true
var_dump(isset($a['nullKey'])); // true, the key has been set, set to null!
var_dump(isset($a['unsetKey'])); // false !
unset($a['randomKey']);
var_dump(isset($a['randomKey'])); // false ! it's been unset!
From above, you can check if various $_POST fields have been set. For example, a page that has been posted to, stands to reason, has the submit button name in the $_POST field.
empty() on the other hand, tests if the variable holds a non zero value. This means that values that (int) cast to 0, return false too. You can use this to see if a specific $_POST field has data in it.
This concept can be better understood from mathematics. Have you ever tried dividing a number (not zero) by 0 using a calculator e.g 7/0? You will get a result that looks like something this: undefined, not a number, null etc. This means that the operation is impossible, for some reasons (let's leave those reasons to be discussed another day).
Now, perform this: 0/7. You will get the output, 0. This means that the operation is possible and can be executed, but you the answer is just 0 because nothing is left after the division. There is a valid output and that output is zero.
In the first example, not only was the output invalid, the operation was not possible to execute. This is akin to null. The second example is akin to empty.