This is the worlds easiest php if statement ever created, how ever ever I cannot figure out how to do it, in one. Essentially I am having a stumped moment and require the communities help .
This is my function:
protected function _traverse_options($name, $type = ''){
if(isset($this->_options[$name][$type])){
echo $this->_options[$name][$type];
}
}
The if statement I need is to check for three things:
If type is not null but type is not 'before'
if type is not null but type is not 'after'
I tried doing:
if($type != '' && $type != 'before' || $type != '' && $type != 'after'){}
How ever that doesn't work.
I know this is simple, but I cannot figure it out? should || be && ??
This'll do the job:
if( $type != '' && $type != 'before' && $type != 'after'){}
So any non-empty string that is neither before nor after.
if ('' !== $type && !in_array($type, array('before', 'after')))
{
}
If I understood it correctly you dont need OR on that statement.
Try with:
if (!is_null($type) && strlen($type) > 0 && $type !== 'before' && $type !== 'after') { ... }
Use parentheses so that you can see what belongs to what.
if ($type != null && ($type !== 'before' && $type !== 'after')) {
// ...
}
If you are not careful you can end up with problems, such as in math, where a calculation can give two different results depending on what operation you do first. For example 2*5-10 which can be either 0 or -10 depending on the order in which you multiply or subtract: (2*5)-10 or 2*(5-10).
You can also make it a little easier to follow by breaking up the logic into variables, making the if statement simpler:
$notNull = ($type != null);
$notBeforeAndAfter = ($type !== 'before' && $type !== 'after');
if ($notNull && $notBeforeAndAfter) {
// ...
}
If you know exactly what the $type variable must contain then you can also use a switch statement. It is a lot easier to understand:
switch ($type) {
case 'before':
echo '$type is "before"';
break;
case 'after':
echo '$type is "after"';
break;
// $type is not 'before' or 'after', which means that
// it is something else which we cannot use...
default:
echo '$type is an unknown value. Error maybe?';
break;
}
Related
I have to evaluate a very long condition in PHP, so, to avoid errors and trying to write more readable code, I did the following:
//this returns 1 when true, and nothing when false, although expected TRUE or FALSE
$isNameValid=strlen($dataDecoded['nombre'])>=3;
$isDescriptionValid=(strlen($dataDecoded['descripcion'])>=10) && strlen($dataDecoded['descripcion'])<=300;
$isPriceValid=$dataDecoded['precio'] >0;
$isImageValid=(($dataDecoded['imagen'] != "") && ($dataDecoded['imagen'] != NULL) );
And now, I can make the following:
if($isNameValid==1 && $isDescriptionValid==1 && $isPriceValid==1 && $isImageValid==1)
{
echo "ok";
}
else{
echo "no";
}
It seems to work fine, but maybe is a weird way of doing things. I wanted to avoid the following, which I find more confusing and easy to make a mistake
if(strlen($dataDecoded['nombre'])>=3 && ... && ...)
Is there a better way to do that? Is wrong what I did? Thanks
I don't care for creating extra variables here; this makes code difficult to maintain and unreusable. I'd recommend breaking your validation logic into easy-to-read, maintainable, reusable functions:
function valid($data) {
return validName($data['nombre']) &&
validDescription($data['descripcion']) &&
validPrice($data['precio']) &&
validImage($data['imagen']);
}
function validName($name) {
return strlen($name) >= 3;
}
function validDescription($desc) {
return strlen($desc) >= 10 && strlen($desc) <= 300;
}
function validPrice($price) {
return $price > 0;
}
function validImage($image) {
return $image !== "" && $image != NULL;
}
$dataDecoded = [
"nombre" => "foo",
"descripcion" => "foo bar foo bar",
"precio" => 15,
"imagen" => "foo.png"
];
// now your main code is beautiful:
echo (valid($dataDecoded) ? "ok" : "no") . "\n";
Yes, that is acceptable. However, your variables there are all boolean, so you don't even need the ==1.
if($isNameValid && $isDescriptionValid && $isPriceValid && $isImageValid)
It really depends on how you want to handle it.
Is switch an option or a viable one?
Is ternary if prettier or handy?
From what I see, I'm guessing you have a validation purpose and a operating incoming depending on the validation. Why not create a function or a class that handles your input and validates? And in there, you can have all the dirty code you'd want. On your logical code, you'd just have to do (e.g of a class)
$someClass = new SomeClass();
$someClass->validate($fields);
if ($someClass->isValidated()) ...
This way, you'd actually follow some standards whereas the purpose of it would be to work as a validator for (all of? depends on your needs) your data
E.g of ternary ifs
$isNameValid = count($dataDecoded['nombre'])>=3 ? true : false;
$isDescriptionValid = count($dataDecoded['descripcion']) >= 10 && count($dataDecoded['descripcion']) <= 300 ? true : false;
$isPriceValid = count($dataDecoded['precio']) > 0 ? true : false;
$isImageValid = empty($dataDecoded['imagen']) === false ? true : false;
if ($isNameValid && $isDescriptionValid && $isPriceValid && $isImageValid) ...
I have this if statement but how can I add more conditions to it?:
if($row['Type']==$rtype){
}
I would like to have two conditions so when $row['Type']=A and $rtype=B and vise versa all others should be match exact but in case when Type A and B comes together I want to allow the statement display result.
I tried by adding:
($row['Type']=='A' && $rtype=='B') || ($row['Type']=='B' && $rtype=='A')
as:
if(...&& (($row['Type']==$rtype) || ($row['Type']=='A' && $rtype=='B') || ($row['Type']=='A' && $rtype=='B'))) {
}
What is the best way to approach this?
From your comment above, it sounds like you may need more clearly define when to "show" and when to "not show". Typically, if there are only two scenarios — either show or don't show — then you wouldn't need two if conditions.
However, with what you describe above, this should work:
if (($rtype == 'A' && $row['Type'] == 'B') || ($rtype == 'B' && $row['Type'] == 'A')) {
return true;
}
if (($rtype == 'D' && $row['Type'] == 'D') || ($rtype == 'E' && $row['Type'] == 'E') || ($rtype == 'F' && $row['Type'] == 'F') {
return false;
}
Note that each group is contained within its own ( and ). That does the AND you're looking for. Outside of each group, the || will do the OR.
If you know that you don't want to "show" if the first if doesn't evaluate to true, then you can simply do:
if (($rtype == 'A' && $row['Type'] == 'B') || ($rtype == 'B' && $row['Type'] == 'A')) {
return true;
}
return false;
I'm not sure what "show" and "don't show" mean so I'm just assuming a true/false will do for you.
Also check out the Operator Precedence link that abhishek posted above. That might give you some more general knowledge about how to group your logical expressions.
Why this condition passes even if I change the $_GET variable?
I've this code
elseif(isset($_GET['results']) && $_GET['results'] == 'reorder' &&
isset($_GET['sort_column']) && $_GET['sort_column'] != '' && isset($_GET['sort_order'])
&& $_GET['sort_order'] != '' && $_GET['sort_order'] == 'asc'
|| $_GET['sort_order'] == 'desc') { /*rest goes here*/ } else {redirect}
Link returns like this
http://localhost/system/results.php?script_id=2&results=reorder&sort_column=supplier_address&sort_order=desc
But when I change this sort_column=supplier_address to say for example sorcodsalumn=supplier_address it doesn't redirect, instead goes ahead, any idea why? But if I simply remove few letters and dont replace with something else it does redirect...
How come if am using this isset($_GET['sort_column'] and am modifying sort_column to something else still passes this condition
Basic PHP operator precedence... && evaluates before ||, so your entire statement boils down to:
(x && y && z && ....) || ($_GET['sort_order'] == 'desc')
You need to simplify that if(), add some () to enforce your own evaluation order, and then things should start working a bit better.
your AND's and OR's need to be bracketed properly.
else if (isset($_GET['results']) &&
$_GET['results'] == 'reorder' &&
isset($_GET['sort_column']) &&
$_GET['sort_column'] != '' &&
isset($_GET['sort_order']) &&
$_GET['sort_order'] != '' &&
($_GET['sort_order'] == 'asc' || $_GET['sort_order'] == 'desc'))
{
/*rest goes here*/
} else {
redirect
}
More specifically your last || needs its own brackets, as shown above.
You need to put a bracket around your || (OR) statement like this:
elseif(isset($_GET['results']) && $_GET['results'] == 'reorder' &&
isset($_GET['sort_column']) && $_GET['sort_column'] != '' && isset($_GET['sort_order'])
&& $_GET['sort_order'] != '' && ($_GET['sort_order'] == 'asc'
|| $_GET['sort_order'] == 'desc')) { /*rest goes here*/ } else {redirect}
Otherwise your statement will return true anytime sort_order is set to 'desc'.
I have if statement with multiple condition,
what is the differece between this two conditon:
1.
if($province=="AB" || "NT" || "NU" || "YT")
{
$GST=5;
}
else if($province=="BC" || "MB")
{
$GST=5;
$PST=7;
}
else if($province=="NB" || "NF" || "ON")
{
$HST=13;
}
and second is:
2.
if($province=="AB" || $province=="NT" || $province=="NU" || $province=="YT")
{
$GST=5;
}
else if($province=="BC" || $province=="MB")
{
$GST=5;
$PST=7;
}
else if($province=="NB" || $province=="NF" || $province=="ON")
{
$HST=13;
}
The difference between the two is that the first one won't work as expected, and the second is technically correct.
The code:
if($province=="AB" || "NT" || "NU" || "YT")
will always evaluate to true and execute the code in that conditional block.
The reason is because you are only checking if $province == "AB" and then you are checking if "NT" == true which will evaluate to true.
To check province against all of those values (AB, NT, NU, YT) you need to explicitly check $province against each value, not just the first, which is what you are correctly doing in the second example.
I add to drew010 answer that you can do this too (wich is simpler) :
if(in_array($province,array("AB","NT","NU","YT"))
{
$GST=5;
}
else if(in_array($province,array("BC","MB"))
{
$GST=5;
$PST=7;
}
else if(in_array($province,array("NB","NF","ON"))
{
$HST=13;
}
The first one will always evaluate to true. In the second, third, and forth OR clauses in the first example you are basically asking PHP to convert the strings to Boolean values, and non-empty strings will always evaluate as true.
Just for fun, my favorite way to handle conditionals like this is with a switch statement. It's a lot easier for me to read, but it's really a personal preference thing.
switch ( $province ) {
case 'AB' :
case 'NT' :
case 'NU' :
case 'YT' :
$GST = 5;
break;
case 'BC' :
case 'MB' :
$GST = 5;
$PST = 7;
break;
case 'NB' :
case 'NF' :
case 'ON' :
$HST = 13;
break;
}
I'm creating an edit page which should get called this way:
users.php?action=edit&id=5
This is my code for this:
} elseif (isset($_GET['action']) && $_GET['action'] == 'edit' && isset($_GET['id']) && is_numeric($_GET['id']) && $_GET['id'] > 0) {
As you see it's long. First a check with isset is needed. I know you can leave that out, but that way I'll get PHP notices when error reporting is set to 'E_ALL'.
I can create a function to make it shorter but that way I'll need to create too many functions as I have such code on different places in my scripts, each requiring different information.
Is there any way to make this code shorter?
Thanks!
Since action and id both are probably going to be used might as well set them at the top of the script:
$action = !empty($_GET['action'])?$_GET['action']:false;
$id = !empty($_GET['id'])?$_GET['id']:false;
switch ($action) {
case 'edit':
if ($id !== false) {
//processing here
}
break;
default:
echo 'No known action was passed through';
}
The initial variable declaration uses the ternary operator which is a shortened if/else as an fyi.
Extra Information
I prefer this method as appose to insane if/elseif/else statements, given that it is much easier to read and you do not have to think about your logic nearly as much, so it would make it less prone to errors.
You could write a function that takes an array of keys:
function check_get_params($keys) {
foreach ($keys as $key) {
if (! isset($_GET[$key]) ) {
return false;
}
}
return true;
}
Then your line above would be:
} elseif (check_get_params(array('action', 'id')) && $_GET['action'] == 'edit' && is_numeric($_GET['id'])) {
which would be cleaner as:
} elseif (check_get_params(array('action', 'id'))) {
if ($_GET['action'] == 'edit' && is_numeric($_GET['id'])) {
I would check parameters first:
$action = (isset($_GET['action']) && !empty($_GET['action'])) ? $_GET['action'] : false;
$id = (isset($_GET['id']) && !empty($_GET['id'])) ? $_GET['id'] : false;
settype($id, 'int'); // "123" became 123(int)
And then go with:
} elseif ($action && $id && $action == 'edit' && $id > 0) {
// here we are
}