Thank you so much for reading and responding if you can.
In one function I test a condition and make a string 'true' or 'false', which then I make a global variable.
Then I call another function with that string as the parameter
Within that function's if statement, I want to test based off the strings boolean value of 'true' or 'false'
$email_form_comments = $_POST['comments']; // pull post data from form
if ($email_form_comments) $comments_status = true; // test if $email_form_comments is instantiated. If so, $comments_status is set to true
else $error = true; // if not, error set to true.
test_another_condition($comments_status); // pass $comments_status value as parameter
function test_another_condition($condition) {
if($condition != 'true') { // I expect $condition to == 'true'parameter
$output = "Your Condition Failed";
return $output;
}
}
My thinking is that $condition will hold a 'true' value, but this is not so.
I think the key here is PHP will evaluate empty strings as false and non-empty strings as true, and when setting and comparing booleans make sure to use constants without quotes. Use true or false not 'true' or 'false'. Also, I suggest writing your if statements so they will set alternate values on a single variable, or in the case of a function return an alternate value when the condition fails.
I made some small modifications to your code so that your function will evaluate true
// simulate post content
$_POST['comments'] = 'foo'; // non-empty string will evaluate true
#$_POST['comments'] = ''; // empty string will evaluate false
$email_form_comments = $_POST['comments']; // pull post data from form
if ($email_form_comments) {
$comments_status = true; // test if $email_form_comments is instantiated. If so, $comments_status is set to true
} else {
$comments_status = false; // if not, error set to true.
}
echo test_another_condition($comments_status); // pass $comments_status value as parameter
function test_another_condition($condition)
{
if ($condition !== true) {
return 'Your Condition Failed';
}
return 'Your Condition Passed';
}
Related
Got an interesting issue. In some legacy code we have following statements.
if (empty($result['email_address']) && empty($result['mobile_number'])) {
$token = '';
} else {
$tokenFinder = new TokenFinder();
$tokenFinder->setEmailAddress($result['email_address']);
$tokenFinder->setMobileNumber($result['mobile_number']);
$token = $tokenFinder->generate();
}
The relevant bits of the token finder look like the following:
class TokenFinder{
public function setEmailAddress($email) {
$this->email = $email;
}
public function setMobileNumber($mobile) {
$this->mobile = $mobile;
}
public function generate(){
if ($this->email == '' && $this->mobile == ''){
Throw new Exception('TokenFinder: You cannot fetch a token with no email or mobile number');
}
Yesterday, for the first time ever, the exception in the generate() method was triggered. I have run all of the recipients in the failed message through this block of code and the exception doesn't trigger. The data has not changed since the Exception was thrown. It is a strange one.
Does anyone know any values which will lead empty($var) to evaluate to false and $var == '' to evalute to true.
empty() returns true in case of:
empty string
0 integer
0.0 float
0 as string
null
false
empty array
empty variable
(see http://php.net/empty)
The error must lie in php's tricky type juggling. It could be, that $result['email_address'] or $result['mobile_numer'] contain an object which __toString implementation return an empty string. emtpy will see an object and == '' sees an empty string.
There could be dozens of other cases though. So your best possibility is to get rid of the logic duplication (the if statements) and implement maybe a static method in TokenFinder like isDataValid and use it to check the array outside of the class.
PHP manual:
empty() Returns FALSE if var exists and has a non-empty, non-zero
value. Otherwise returns TRUE.
For some odd reason my PHP is not seeing the value of the second parameter.
My code:
PHP function:
public function getVacs($key, $id = null, $deleted = null, $deleted_key = null) {
if(!$id) {
$data = $this->_db->getAll('vacatures', $key);
} elseif(!empty($deleted)) {
$data = $this->_db->getAll('vacatures', $key, $id, $deleted, $deleted_key);
} else {
$data = $this->_db->getAll('vacatures', $key, $id);
}
if($data->count()) {
$this->_data = $data->results();
$this->_count = $data->count();
return true;
}
}
Calling the function:
} elseif(isset($_POST['all'])) {
$vacs = $v->getVacs('delete', '0');
echo json_encode($v->data());
exit();
}
The problem is, the function does not see the value of $id.
It's running the first if while it should be running the else.
In php the string "0" evaluates to false.
This means your check if(!$id) will evaluate to true and by your logic id won't be set in $data.
If the string "0" is legitimate option, then check for null explicitly instead:
if(is_null($id)){
This will
It is seeing the value of $id, but your if statement is set up wrong. 0 will evaluate to false on a check like that. So you really need to make sure that it's not null:
if($id != null) {
If you want the first if to run only if there is NOT a valid id, then you need to check if it's empty (i.e. not null, 0, false, or an empty string)
if(empty($id)) {
Using the strict comparison operator might be a good idea in these cases (and I would say in most cases):
0 == null; // evaluates to true
0 === null; // evaluates to false
Useful with strpos also (returns 0 means searched term at position 0 of haystack string, returns false means searched term not found).
I have this simple function:
function isMember($uID, $pdo) {
$status = getUserStatus($uID, $pdo);
if(isAllowed($status['status']))
return $status['status'];
return false;
}
Now I am looking for a way to return false yes, but to return also the value of the variable.
I tried the following, but it makes it empty anyway:
return $status['status'] == false;
So the logi is return false anyway but give me back also the value of the variable, even if it's false, because false should not mean empty :)
Return an array, and use the list() method to get your results:
function isMember($uID, $pdo) {
$status = getUserStatus($uID, $pdo);
$statusString = $status['status'];
$statusFlag = false;
if(isAllowed($status['status']))
$statusFlag = true;
return array($statusFlag,statusString);
}
//usage
list($flag,$msg) = isMember(5,"whatever");
echo "Access: $flag, with message $msg";
A function can not return multiple values, but similar results can be obtained by (1) returning an array or by (2) passing a variable by reference and storing the value you want returned in that variable.
You will need to write your function in a way that it returns an array containing the following:
The value you wan't returned
A flag that signifies true/false
Pass a variable by reference into your function and store the value of the status in that variable.
function isMember($uID, $pdo, &statByRef) {
$status = getUserStatus($uID, $pdo);
if(isAllowed($status['status'])) {
return $status['status'];
}
$statByRef = $status['status'];
return false;
}
False returns empty in PHP, see http://php.net/manual/en/function.empty.php
From documentation:
Determine whether a variable is considered to be empty. A variable is considered empty if it does not exist or if its value equals FALSE. empty() does not generate a warning if the variable does not exist.
Try using something like this:
function isMember($uID, $pdo) {
$status = getUserStatus($uID, $pdo);
if(isAllowed($status['status'])){
return $status['status'];
}
return false;
} // If isAllowed returns true, then PHP will return $Status['Status'];, if not then PHP will by default return false.
I have noticed you haven't used braces which makes the code a little awkward to debug. Then validate like:
if (isMember($Var,$AnotherVar) !== false){
//isMember has not returned false, so PHP is operating within these braces
}
Such a simple thing, which should be most effective.
If your wanting to assign true/false to $status['status']; then you are performing the right method, but wrong operator.
== is a comparision operator. Not assignment
= is an assignment operator, so your assignment should be:
$status['status'] = false;
How can I quickly validate if a GET or POST variable in CodeIgniter is both set and numeric for use as error or status messages in views?
It is very tedious to do something like this each time each time I want to check variables:
if ($this->input->get('error', True)) {
if (is_numeric($this->input->get('error', True))) {
$data['error'] = $this->input->get('error', True);
}
}
get_numeric_input() for CodeIgniter
mixed get_numeric_input ( string $name [, bool $required = True [, string $source = "GET" [, bool *$xss_clean* = True ]]] )
Below is a function that I created because I was tired of checking if GET and POST variables existed and were numeric.
This was mainly used when handling errors or status messages, because I could use redirect("original_page.php?error=1"); to pass an error to the original page. On the original page, I could simply do if (isset($error)) { … } and display a message depending on the value. However, it was necessary to check these variables before sending them to the view in the interest of security. This process proved to be quite repetitive and tedious.
This function below is to be added to the bottom of wwwroot/application/system/core/Input.php
It is to be used as follows:
Example 1:
function index() {
if ($error = $this->input->get_numeric_input('error', True, "GET", True)) {
$data['error'] = $error;
}
}
In this example, if $_GET['error'] is both set and numeric, it will set $data['error'] to that value. If it is either not set and/or not numeric, it will terminate the script.
Example 2:
function index() {
if ($error = $this->input->get_numeric_input('error', False, "POST", True)) {
$data['error'] = $error;
}
}
In this example, if $_POST['error'] is both set and numeric, it will set $data['error'] to that value. If it is either not set and/or not numeric, it will continue and not set any values in the $data array.
The first argument is the variable name to be checked. The second variable is the boolean that makes the check required or not. If you have this set to TRUE, then if the variable is not set OR if it is not numeric, it will show an error and immediately terminate the script. If set to False, then it will will simply return False, and the script will move on. The third variable is either POST or GET, and will determine if the function looks for the variable in the $_GET or $_POST arrays. Finally, the fourth variable indicated whether or not the values will be XSS_CLEAN when returned.
NOTE: Both the second, third, and fourth arguments are optional, and default to True, “GET,” and True, respectively.
Here is the code:
function get_numeric_input($name, $required = True, $source = "GET", $xss_clean = True) {
if ($source === "GET") {
if ($this->get($name, $xss_clean)) {
if (is_numeric($this->get($name, $xss_clean))) {
return $this->get($name, $xss_clean);
} else {
if ($required) {
show_error("$source variable $name is not numeric!");
log_message('error', "$source variable $name is not numeric!");
return False;
} else {
return False;
}
}
} else {
if ($required) {
show_error("$source variable $name is not set!");
log_message('error', "$source variable $name is not set!");
return False;
} else {
return False;
}
}
} elseif ($source === "POST") {
if ($this->post($name, $xss_clean)) {
if (is_numeric($this->post($name, $xss_clean))) {
return $this->post($name, $xss_clean);
} else {
if ($required) {
show_error("$source variable $name is not numeric!");
log_message('error', "$source variable $name is not numeric!");
return False;
} else {
return False;
}
}
} else {
if ($required) {
show_error("$source variable $name is not set!");
log_message('error', "$source variable $name is not set!");
return False;
} else {
return False;
}
}
}
}
A possible alternative is to extend the form validation so that you would have a way to validate $_GET aswell. Using the form validation library does save time imo (an extended version - fit to your needs - is advisable).
CodeIgniter Validation: possible to validate GET query strings? talks about this.
Just use an intermediary variable, for a short and fast code:
$input_error = $this->input->get('error');
$data['error'] = ctype_digit($input_error) ? $input_error : FALSE;
If you really want a one-liner:
function validate_integer_input($input) {
return ctype_digit($input) ? $input : FALSE;
}
$data['error'] = validate_integer_input($this->input->get('error'));
$data['error'] will always be set, which is a good thing, because $data will always be set in your view, so you can simply do if ($data) instead of if (isset($data)).
When dealing with GET and POST input you have to know some aspects of typing. For the most important:
A GET/POST input, of course if it is set, is always of type string.
Only '' (empty) and '0' strings evaluate to FALSE, all other values evaluate to TRUE.
ctype_digit() expects a string, but this code may pass it FALSE (from CI->input). But it's fine, as FALSE casts to an empty string.
As a side note, XSS filtering is not needed for this case.
XSS filtering has quite a performance impact and should be activated only when needed. A rule of thumb is that the filtering is needed for data which is displayed or included wherever in the HTML source.
For this case, we already made sure the input can only contain digits, so we're safe.
I am looking for the correct way to handle a return statement with a bool/string. For example I do all my checking inside the function and return true if it all passes. However if something went wrong I would like to return a string of what went wrong rather than just return false; with a general string. Does php assume false if a var is set to anything besides true? What is the correct way to handle this? Here's an example of what I'm doing
<?php
$a = 2;
$result = CheckVar($a);
if ($result)
{
echo 'Correct!';
}
else
{
echo $result;
}
function CheckVar($var)
{
if ($var == 1)
{
return true;
}
else
{
return 'This is not the correct answer. You supplied '.$var;
}
}
?>
It seems this method works, however is this good programming etiquette? Or is there another way I should be doing this? Thank you for your time.
Does php assume false if a var is set to anything besides true?
Not at all. PHP will return whatever the variable was set to. And actually since you have a non-empty string, that's a "truthy" value (ie: true in a boolean context). Since you used if ($result) as your check and you return a "truthy" value, the condition is always true. You need to change that check to:
if ($result === true) {
...
What is the correct way to handle this?
I think it's a good enough way to handle it. An alternative would be to pass an error string variable by reference, and have the fail part of your code fill that, eg:
function check($var, &$error) {
if ($var == 1) {
return true;
} else {
$error = 'This is not the correct answer. You supplied ' . $var;
return false;
}
}
Some native PHP functions behave like this (eg: exec().) Yet another alternative is to return an array with the errors, like Jared suggested. I personally use this option when I expect multiple errors (eg: a form validation routine):
function check_stuff($stuff) {
$errors = array();
if (!$condition1) {
$errors[] = 'Condition 1 failed';
}
if (!$condition2) {
$errors[] = 'Condition 2 failed';
}
return $errors;
}
Now you can also take advantage of the fact that empty arrays are falsy:
$errors = check_stuff($your_stuff);
if (!$errors) {
echo 'No errors!';
} else {
print_r($errors);
}
You can use === to check if the returned value is boolean true. === checks the type as well the value.
if ($result === true)
{
echo 'Correct!';
}
else
{
echo $result;
}
I came up against this recently, my function would either return an error message as a string or return true like this:
function check_something(){
if(condition){
return 'error message';
}
// if we got this far all is good!
return true;
}
I would call it and check the outcome like this:
$var = check_something();
if($var !== true){
// $var is not boolean true, so it must be a string
echo $var;
}
This checks that the outcome of the function is not just a truthy string, but is explicitly a boolean true
This could be useful to someone returning true or returning false as a string.
if (is_bool($result))
{
echo 'Result is a true bool';
}
else
{
echo $result.'returning a string';
}