Tricky verification code on a form - php

I have an implemented control check on a form coded this way:
public function checkCittaResidenza() {
if (is_string($this->citta_residenza) && (strlen($this->citta_residenza) <= 45 || strlen($this->citta_residenza == 0))) {
$this->corretti['citta_residenza'] = htmlentities($this->citta_residenza, ENT_QUOTES);
} else {
$this->ErroriTrack('citta_residenza');
}
}
In this version, it simply checks if it is a string and check its lenght that should be less than 45 chars. It puts the string in an array corretti() if positive, else it initialize an error message specified above in an abstract class parent of the checking class.
What i'd love it to do is:
1) make a check on the string to see if it's not null.
2) if it's not null, do the check (that could be even more particular than the simple one shown here, but i don't have problems on this), put it in corretti() if correct and initializing the error if it's not, as the code now says.
3) if the string is null, the program should skip the check and directly write the null value into the array corretti(), because the form is imagined to be completed in different steps over the time, so it always happen that it's not fully filled.
I'm having problem on coding the if cycle for this last condition, every cycle i tried and imagined puts the empty condition as a cause for initializing an error.
Thank you!

Try this,
public function checkCittaResidenza() {
if(isset($this->citta_residenza)){
if ((is_string($this->citta_residenza) && (strlen($this->citta_residenza) <= 45) || $this->citta_residenza == "")) {
$this->corretti['citta_residenza'] = htmlentities($this->citta_residenza, ENT_QUOTES);
} else {
$this->ErroriTrack('citta_residenza');
}
} else {
$this->corretti['citta_residenza'] = "null";
}
}

Related

Modulus of a string

I am in a very puzzling situation. Intially when an user visits a particular page, a popup is shown. User can accept it or decline it. When a user declines it, after 5 page visits, the pop up is again shown to user. This part is working perfectly. When user clicks ok, an ajax call is made and the SESSION variable is set to ok. Lets say initially $_SESSION['count'] = 0. I have two condition statements.
if($_SESSION['count']%5 === 0)
{ // do something
}
elseif($_SESSION['count'] === "ok")
{ // do something
}
Now when an user press ok, an ajax call is made updating $_SESSION['count'] = "ok".
When the user again reloads the page, condition if($_SESSION['count']%5 === 0) gets true even though $_SESSION['count'] is now ok. Later after much experimenting, i came to know that in php i am able to divide or find modulus string by number which will result in zero. How can i handle this?
You can use is_numeric to check if it is a count or 'ok'
http://php.net/manual/en/function.is-numeric.php
if(is_numeric($_SESSION['count']) && $_SESSION['count']%5 === 0)
{ // do something
}
elseif($_SESSION['count'] === "ok")
{ // do something
}
Though generally, I would set ok to be the value of a different variable in $_SESSION as a best practice. If I was looking at the code I would find it very odd to see something called count having a string value.
PHP is very good at implicit casting.
A solution to your issue is simply re-arrange your if else tree.
if($_SESSION['count'] === "ok")
{
// do something
}
elseif($_SESSION['count'] % 5 === 0)
{
// do something
}
Readability
Something to bare in mind, is that a variable count should really contain a value. Perhaps using a different variable might make your code a little less confusing to a reader.
In php, (int) "some string" == 0, so check if $_SESSION['count'] is an integer (e.g. using is_numeric()) before doing the modulus.
Check this working example. It may help:
if(!isset($_SESSION['foo'])) {
$_SESSION['foo'] = 0;
} else {
$_SESSION['foo']++;
}
var_dump($_SESSION['foo']%3);
if(is_numeric($_SESSION['count']) AND $_SESSION['count']%5 === 0)
{ // do something
}
elseif($_SESSION['count'] === "ok")
{ // do something
}

PHP validation function. Check for numeric and positive

Little confused about how to code this. User inputs numbers, then the validation checks to make sure it is numeric and positive. The user can also leave this field blank.
This is what i have so far, it just checks to see that something was inserted.
$error_blue = check_blue($phone);
if($error_blue !=''){
print "<p>Blue: $error_blue";
}
Is where the item is validated at the top of the page.
function check_blue($blue){
if(! is_numeric($blue)){
return'Please Enter a valid number for Blue.';
}}
Is where the function is.
Any help on what to do here would be much appriciated.
Something like this?
function check_blue($blue) {
if (is_numeric($blue) && $blue > -1) {
return 1;
}
else {
return 0;
}
}
if(!check_blue($phone)) {
return'Please Enter a valid number for Blue.';
}
See the demo
Assuming it's an integer you expect,
if ((int)$blue==abs($blue) || empty($blue)) $error = false;
else $error = true;
Then you use $error to decide what to do.
Everyone here was using if else. It is not that this is wrong, but just to show you another idea, which might be useful for other type of validation, take a look at validate filters :
http://www.php.net/manual/en/filter.filters.validate.php
For this purpose you might use FILTER_VALIDATE_INT
You might want to use something simple as
function check_blue($phone) {
return (empty($phone) || (is_numeric($phone) && $phone >= 0));
}
First check if the field is blank, nothing to do if it is.
If it is not blank it will be checked for numericality and to being greater or equal zero.

!is_null() not working as expected

dispatch_address_postcode
isn't mandatory and it will still run even if it's blank:
if (!is_null($_POST['personal_info_first_name']) &&
!is_null($_POST['personal_info_surname']) &&
!is_null($_POST['personal_info_email']) &&
!is_null($_POST['personal_info_telephone']) &&
!is_null($_POST['dispatch_address_country']) &&
!is_null($_POST['dispatch_address_first_name']) &&
!is_null($_POST['dispatch_address_surname']) &&
!is_null($_POST['dispatch_address_address']) &&
!is_null($_POST['dispatch_address_town']) &&
!is_null($_POST['dispatch_address_postcode']) &&
!is_null($_POST['dispatch_address_county']) &&
( ($_POST['payment_method'] == "Pay by credit card.") ||
(
($_POST['payment_method'] == "Pay by new credit card.") &&
!is_null($_POST['card_number']) &&
!is_null($_POST['expiration_date']) &&
!is_null($_POST['security_code'])
)
)
)
What gives?
"dispatch_address_postcode isn't mandatory and it will still run even if it's blank…"
Just look at that sentence again. If the field is not mandatory, it is perfectly okay if the code runs if the field is blank. If a field isn't mandatory, don't test it as mandatory.
The real problem is though, is_null only tests if the variable is null. POSTed values will never be null, if they're empty they will be '' (an empty string). All your !is_null tests will always be true, and you will get a warning if the variable isn't set (something you don't want to happen). The more appropriate test would be !empty.
Even more appropriate tests would include a test if the value appears to be valid (does email look like an email address, does telephone have at least x digits in it?). You should also loop through the fields to make your code more readable, endless nested and chained if conditions are no joy to look at.
$mandatoryFields = array('foo' => 'email', 'bar' => 'telephone');
foreach ($mandatoryFields as $field => $rule) {
if (empty($_POST[$field]) || !validateByRule($_POST[$field], $rule)) {
raiseHell();
}
}
It looks like you're trying to make sure all post variables are submitted. Would you like help with that?
Using !empty() may not be the answer to your specific question, but it would definitely help with what it looks like you're trying to do.
empty() returns TRUE if the $_POST key isn't set, if its an empty array, or even if its an empty string, so using !empty() is a good way to make sure that the user has filled in the information.
Try writing your own is_valid function and use that rather than is_null.
For example (and this is by no means comprehensive):
function is_valid(&$array, $key, $required=false) {
if(!array_key_exists($array))
return false;
$value = trim($array[$key]);
if(empty($value) && $required)
return false;
return true;
}
Use like so:
if(is_valid($_POST, 'personal_info_first_name', true) && ...)
!is_null($_POST['personal_info_first_name']) && !isset($_POST['personal_info_first_name'])
use array_key_exists('card_number', $_POST) && !empty($_POST['card_number'])
Edit: Please consider this before a downvote. I'm leaving this here to serve as a "what not to do". I would delete it because it's bad, but then nobody would learn from my mistakes.
DO NOT DO THIS - read the comments for great info on why this is bad
My answer is going to be wildly different, but I am a wildly different guy...
I JUST found that this will work. Instead of all that isset and things, just assign the variables programmatically! I think I have some refactoring to do... y'know on all my code...
if (!is_array($_POST)){exit "$_POST isn't an array";}
foreach ($_POST as $param => $value){
${$param} = secure($value);
}
//now you have a set of variables that are named exactly as the posted param
//for example, $_POST['personal_info_first_name'] == $personal_info_first_name
if ($payment_method == "Pay by credit card."){
//do stuff that you were gonna do anyways
} else if ($payment_method == "Pay by new credit card.") {
if ($card_number && $expiration_date && $security_code){
//do stuff that you were gonna do anyways
} else {
exit("info missing for credit card transaction");
}
} else {
exit("unknown payment method")
}
function secure($input){
//sanitize user input
}
If you use this code, then it doesn't matter what is null and what isn't within the foreach because anything that's null just won't be made. Then you can use nicer looking code (and probably faster code) to check for anything that is required.

Once I determine a var exist in PHP do I need to keep checking it in that page?

I have a basic PHP question, take the code below for example, let's say I need to use this 10 times on a page, is there a better way to do it?
I realize I could wrap it in a function and just keep calling that function but is there a better way then to keep on checking if the item is set and equals a a certain value. After finding this out the first time is there some other way of remembering the result from the first time instead of doing it 10 different times?
Hope that makes sense.
<?PHP
if (isset($_SESSION['auto_id']) && $_SESSION['auto_id'] == "1") {
//do something
}
// do other code here that breaks these up
if (isset($_SESSION['auto_id']) && $_SESSION['auto_id'] == "1") {
//do something else
}
// do other code here that breaks these up
if (isset($_SESSION['auto_id']) && $_SESSION['auto_id'] == "1") {
//do something else
}
// do other code here that breaks these up
if (isset($_SESSION['auto_id']) && $_SESSION['auto_id'] == "1") {
//do something else
}
...ect
?>
In this case, yes you have to, although you could do it once and assign the result to a variable.
how about...
<?PHP
$myCheck = (isset($_SESSION['auto_id']) && $_SESSION['auto_id'] == "1") ;
if($myCheck) {
//do something
}
// do other code here that breaks these up
if($myCheck) {
//do something else
}
// do other code here that breaks these up
if($myCheck) {
//do something else
}
// do other code here that breaks these up
if($myCheck) {
//do something else
}
etc.
?>
Syntax may be off - it's a long time since I've done any PHP work...
Sure. Just save the value of the boolean expression in another variable.
<?php
$auto_id_is_one = ($_SESSION['auto_id']) && $_SESSION['auto_id'] == "1");
// ...
if ($auto_id_is_one) {
// do something
}
// ...
if ($auto_id_is_one) {
// do something else
}
// ...
?>
You probably want to give it a more meaningful name than $auto_id_is_one, though.
Maybe a better approach is to use isset once at the top of the function, and set the variable to a default value there. Then you can simply use the value through the rest of the function.
In your example, you could set it to "0", though I realize that may not be the real code...
It depends what the "do something" block of code is, and whether or not the auto_id index of $_SESSION is changed in the other code. You can be certain that, in the body of the first if, the variable exists and is 1. Once that if concludes, you can no longer be certain - you'll have to check again later unless all the rest of the code is executed in a context that only exists if the first test succeeds (i.e. there's an else clause that terminates the script), and you are sure you don't change the value (and no external code you call changes it).
A better way to check the sanity might be to ensure most of the environment is as you expect it just once, then just check specific values at various places. However, if you're constantly rechecking this, it might indicate a design flaw, where similar logic (i.e. that dependent on auto_id = 1) is not well isolated and grouped.
In the example you provided, PHP will just issue an E_NOTICE that the index is not found in the $_SESSION super global (It will not throw the notice if you turned off strict mode). The best practice would be to go and set the value to a default so that you know for sure that the variable is set.
ex
<?php
$myVar = isset($_SESSION['auto_id']) ? $_SESSION['auto_id'] : FALSE;
if (false !== $myVar)
{
//do something
}
//do something not realated to myVar being set
if (false !== $myVar)
{
//do somethign else
}
?>
<?PHP
if (isset($_SESSION['auto_id']) && $_SESSION['auto_id'] == "1") {
$sessionOK = TRUE;
}
if ($sessionOK) {
//do this
}
if ($sessionOK) {
//do that
}

Better way to check variable for null or empty string?

Since PHP is a dynamic language what's the best way of checking to see if a provided field is empty?
I want to ensure that:
null is considered an empty string
a white space only string is considered empty
that "0" is not considered empty
This is what I've got so far:
$question = trim($_POST['question']);
if ("" === "$question") {
// Handle error here
}
There must be a simpler way of doing this?
// Function for basic field validation (present and neither empty nor only white space
function IsNullOrEmptyString($str){
return ($str === null || trim($str) === '');
}
Old post but someone might need it as I did ;)
if (strlen($str) == 0){
do what ever
}
replace $str with your variable.
NULL and "" both return 0 when using strlen.
Use PHP's empty() function. 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; (a variable declared, but without a value)
For more details check empty function
I'll humbly accept if I'm wrong, but I tested on my own end and found that the following works for testing both string(0) "" and NULL valued variables:
if ( $question ) {
// Handle success here
}
Which could also be reversed to test for success as such:
if ( !$question ) {
// Handle error here
}
Beware false negatives from the trim() function — it performs a cast-to-string before trimming, and thus will return e.g. "Array" if you pass it an empty array. That may not be an issue, depending on how you process your data, but with the code you supply, a field named question[] could be supplied in the POST data and appear to be a non-empty string. Instead, I would suggest:
$question = $_POST['question'];
if (!is_string || ($question = trim($question))) {
// Handle error here
}
// If $question was a string, it will have been trimmed by this point
There is no better way but since it's an operation you usually do quite often, you'd better automatize the process.
Most frameworks offer a way to make arguments parsing an easy task. You can build you own object for that. Quick and dirty example :
class Request
{
// This is the spirit but you may want to make that cleaner :-)
function get($key, $default=null, $from=null)
{
if ($from) :
if (isset(${'_'.$from}[$key]));
return sanitize(${'_'.strtoupper($from)}[$key]); // didn't test that but it should work
else
if isset($_REQUEST[$key])
return sanitize($_REQUEST[$key]);
return $default;
}
// basics. Enforce it with filters according to your needs
function sanitize($data)
{
return addslashes(trim($data));
}
// your rules here
function isEmptyString($data)
{
return (trim($data) === "" or $data === null);
}
function exists($key) {}
function setFlash($name, $value) {}
[...]
}
$request = new Request();
$question= $request->get('question', '', 'post');
print $request->isEmptyString($question);
Symfony use that kind of sugar massively.
But you are talking about more than that, with your "// Handle error here
". You are mixing 2 jobs : getting the data and processing it. This is not the same at all.
There are other mechanisms you can use to validate data. Again, frameworks can show you best pratices.
Create objects that represent the data of your form, then attach processses and fall back to it. It sounds far more work that hacking a quick PHP script (and it is the first time), but it's reusable, flexible, and much less error prone since form validation with usual PHP tends to quickly become spaguetti code.
This one checks arrays and strings:
function is_set($val) {
if(is_array($val)) return !empty($val);
return strlen(trim($val)) ? true : false;
}
to be more robust (tabulation, return…), I define:
function is_not_empty_string($str) {
if (is_string($str) && trim($str, " \t\n\r\0") !== '')
return true;
else
return false;
}
// code to test
$values = array(false, true, null, 'abc', '23', 23, '23.5', 23.5, '', ' ', '0', 0);
foreach ($values as $value) {
var_export($value);
if (is_not_empty_string($value))
print(" is a none empty string!\n");
else
print(" is not a string or is an empty string\n");
}
sources:
https://www.php.net/manual/en/function.is-string.php
https://www.php.net/manual/en/function.trim.php
When you want to check if a value is provided for a field, that field may be a string , an array, or undifined. So, the following is enough
function isSet($param)
{
return (is_array($param) && count($param)) || trim($param) !== '';
}
use this :
// check for null or empty
if (empty($var)) {
...
}
else {
...
}
empty() used to work for this, but the behavior of empty() has changed several times. As always, the php docs are always the best source for exact behavior and the comments on those pages usually provide a good history of the changes over time. If you want to check for a lack of object properties, a very defensive method at the moment is:
if (is_object($theObject) && (count(get_object_vars($theObject)) > 0)) {

Categories