I need to validate a form therefore I am writing a php class that does just that. I need to check if a $_POST variable has been set or not in order to determine whether display an error message. So I have implemented two methods which don't seem to work as I expect, because even if I leave my form blank, it is processed as if data has been filled in, and I just don't understand.
private function isSubmitted($field) {
if (!array_key_exists($field, $_POST)) {
return false;
} else {
return true;
}
}
private function hasContent($field) {
if (!empty($_POST[$field])) {
return false;
} else {
return true;
}
}
Even when a field is left empty, it is submitted with "" (an empty string) as its content. Therefore, array_key_exists will return true.
if not empty return false is the opposite logic of what you're trying to do.
Abbreviating your boolean returns to return array_key_exists($field, $_POST); should be considered saner, at the very least more concise.
I think you can try something like this
private function isSubmitted($field) {
return isset($_POST[$field]);
}
private function hasContent($field) {
return !empty($_POST[$field]);
}
private function hasContent($field) {
if (!empty($_POST[$field])) {
return true;
} else {
return false;
}
}
I think you should do a minor change.you should also check whether the existed array have value or is it empty.
Related
I am using 2 regex functions here and I wanna make another function which returns false when the 2 regex are both false and if not, then true.
The problem here is when I wanna use the 2 regex functions in the third one, I have to give them parameters, which is not necessary I think, because the third function will only return a simple true or false. I get an undefined variable whenever I give parameters to the 2 regex functions in the 3rd one.
I tried using global variables which works but since its a bad practice I am looking for a better solution.
Code:
function regex1($input)
{
$regex= "/^[A-Za-z0-9 ]*$/";
if (!preg_match($regex, $input))
{
return false;
}
else
{
return true;
}
}
function regex2($input)
{
$regex= "/^[A-Za-z0-9 ]*$/";
if (!preg_match($regex, $input))
{
return false;
}
else
{
return true;
}
}
function checkBoth()
{
if (regex1($input) === false || regex2($input) === false)
{
return false;
}
else
{
return true;
}
}
EDIT:
The checkBoth function I am using in my other file like this together with the other 2 regex functions:
if (!regex1($input))
{
// show error at the same time
}
if (!regex2($input))
{
// show error at the same time
}
if(checkBoth())
{
// success
}
function regex2($input,$secondVar=false)
{....
Later in code in place where you need just add:
if($secondVar !== false){
// do whatever...
}
If you can't user "false" you can just empty string '' or any other value that will not appear there.
Is it possible to return an array, but also tell php it's supposed to mean false?
Example:
if ($res = a_function()) {
// all good
}
else {
echo getErrorByNumber($res['err_no']);
}
a_function:
function a_function() {
// do fancy stuff
if (xy) return true;
return array('err_no' => 1);
}
I guess its not possible, since php will always take an array for return true, right?
Lot's of ways. Probably the preferred one, compare to true with type checking ===:
if(($res = a_function()) === true) {
// all good
}
else {
echo getErrorByNumber($res['err_no']);
}
A non-empty array will always be true:
if($res = a_function() && !is_array($res)) {
// all good
}
else {
echo getErrorByNumber($res['err_no']);
}
Or flip it around:
if(is_array($res)) { //or isset($res['err_no'])
echo getErrorByNumber($res['err_no']);
}
else {
// all good
}
I would solve this problem with a byref parameter:
function foo(&$errors)
{
if (allWentWell())
{
$errors = null;
return true;
}
else
{
$errors = array('err_no' => 007);
return false;
}
}
// call the function
if (foo($errors))
{
}
else
{
echo getErrorByNumber($errors['err_no']);
}
This way you do not have to distinguish between different possible return types and you will not run into type juggling problems. It is also more readable, you know what's inside the $errors variable without documentation. I wrote a small article explaining why mixed-typed return values can be so dangerous.
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.
Is there a way I can have my PHP function return a different value type?
The following code should explain what I mean:
<?php
public function test($value){
if($value == 1){
return "SUCCESS";
} else {
return false;
}
}
?>
On one condition I'm returning a string, otherwise I'm returning a Boolean. Is that allowed/possible?
Yes. PHP is loosely typed, so any variable can take any type. Function return values are no exception.
Yes, it's possible (but not advisable).
You should at least declare it in your Javadoc comment
/**
* #param int $value
* #return mixed string|boolean
**/
public function test($value){
if($value == 1){
return "SUCCESS";
} else {
return false;
}
}
Even PHP's built in functions do it sometimes (e.g mysql_connect => boolean | resource link)
It is allowed. However, it is not advisable in the case you gave. For an example where this makes sense, take a look at e.g. strpos() function.
Yes, that's allowed, not like in C, Java, ..., where you have to define the return.
I wonder about this myself, why return something that is different? So the receiving end gets two things to check?
I think I have settled on returning an empty version of the type or an array with a status element myself.
Two examples, how things can change within a function/method, and you are basically forced to check more than expected:
<?php
function test($value) {
if ($value == 1) {
$local = successFunction($value);
return $local;
}
else {
return false;
}
}
$res = test(1);
if ($res) {
echo "Are we OK? Right? No? What is this?";
}
Version 2
function test($value) {
if ($value == 1) {
$local = successFunction($value);
return $local;
}
else {
return "";
}
}
$res = test(1);
if (!empty($res)) {
echo "More likely we are OK.";
}
?>
Is that allowed/possible?
Yep.
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';
}