if statement says true to a null variable - php

What is happening here? Is it to late for my brain?
I have a php file containing exaclty the code below.
<?php
$foo = 'foo';
$bar = null;
switch ($foo) {
default:
case 'foo':
if ($bar) {
echo 'true';
} else {
echo 'false';
}
}
Prints true when run in the browser but false when run on command line... HOW? I noticed when I remove the line default: it works, but how should this whole switch statement be related to this? It's still a simple if (null) { doing this anyway }
PHP 7.0.13
Apache/2.4.18
And yes... I cleared my browser cache, hit ctrl+f5... I even changed the scripts file name.
UPDATE:
After making changes to this simple file... (just adding whitespaces to the end) and hitting f5 in the browser it says false once but than true again... no matter what I do. I really don't get it.
UPDATE:
My PHP version just got updated from 7.0.13 to 7.0.15. Guess what... still the same output:
Apache/Browser: true
Console: false

For this you can use isset
<?php
$foo = 'bar';
$bar = null;
switch ($foo) {
default:
case 'bar':
if (isset($bar)) {
echo "true";
die();
} else {
echo "false";
die();
}
}
This code will echo false.
You could also use a double not operator:
<?php
$foo = 'bar';
$bar = null;
switch ($foo) {
default:
case 'bar':
if (!!$bar) {
echo "true";
die();
} else {
echo "false";
die();
}
}
The problem with your default case
In the code you provided (and the code I re-quoted), you will be hitting case 'bar' every time, no matter what $foo is set to.
<?php
$foo = 'notbar';
$bar = null;
switch ($foo) {
default:
case 'bar':
if (!!$bar) {
echo "true";
die();
} else {
echo "false";
die();
}
}
This code will still echo false.
What you should do is include a break in the default case.
<?php
$foo = 'notbar';
$bar = null;
switch ($foo) {
default:
echo "default";
break;
case 'bar':
if (!!$bar) {
echo "true";
die();
} else {
echo "false";
die();
}
break;
}
This code will echo default and nothing else.

Related

PHP: Is there an alternative to using multiple if-statements?

I am in the making of some code that needs to check if a users login details are correct, and I therefore need a lot of if-statements inside each other. If any of the conditions in the if-statements are not true, they should alle return the same value. Is there an easy way of doing this, instead of writing the same multiple times? I have made an example below to visualize my problem. As you can see here I write " else { return false; }" multiple time, and this is what I am wondering if you are able to do more efficiently. Maybe so I only have to write "or else return false" once.
//some code
if (/*some condition*/) {
//some code
if (/*some new condition*/) {
//some code
if (/*some new condition*/) {
//some code
} else {
return false;
}
} else {
return false;
}
} else {
return false;
}
I am having a hard time finding a good way to explain my problem, so if you have a more elegant way of explaining it, do not hesitate to edit my post. I am also not quite sure that the title is as good as it could be, so if you have any ideas to an alternativ please say so :)
Lets say you have something like that (I added No):
if ( condition1 ) {
//some code 1
if ( condition2 ) {
//some code 2
if ( condition3 ) {
//some code 3
} else {
return false;
}
} else {
return false;
}
} else {
return false;
}
Since each time a condition is false, you exit the function returning false, you can directly test if the condition is false using a negation (if the negated condition is true):
if ( !condition1 ) {
return false;
}
//some code 1
if ( !condition2 ) {
return false;
}
//some code 2
if ( !condition3 ) {
return false;
}
//some code 3
This doesn't reduce the number of if statements, but you avoid many nesting levels and the else statements.
You can also try the switch statement. For many situations it will produce cleaner code.
<?php
if ($i == 0) {
echo "i equals 0";
} elseif ($i == 1) {
echo "i equals 1";
} elseif ($i == 2) {
echo "i equals 2";
}
switch ($i) {
case 0:
echo "i equals 0";
break;
case 1:
echo "i equals 1";
break;
case 2:
echo "i equals 2";
break;
}
?>
The switch statement is also compatible with using strings:
<?php
switch ($i) {
case "apple":
echo "i is apple";
break;
case "bar":
echo "i is bar";
break;
case "cake":
echo "i is cake";
break;
}
?>
Good luck! :)

Turn php loop output to variable?

I am still learning php and this is how i convert php loop statement output to variable::
ob_start();
if 2 > 1 {
echo 'It is OK';
} else {
echo 'It is not OK';
}
$myvar = ob_get_clean();
echo $myvar;
Now the $myvar will output above if result, but is there better approach in doing this?
First, there is no looping in your code: if/else blocks are executed once, not in a loop.
Second, if you want to save the string, you can assign it to your variable directly, using many approaches:
if/else
if(2 > 1) $myVar = 'it is OK';
else $myVar = 'it is not OK';
switch case
switch (2>1):
case true:
$myVar = 'it is OK';
break;
default:
$myVar = 'it is not OK';
endswitch;
ternary operator
$myVar = 2>1 ? 'it is OK' : 'it is not OK';

SWITCH returns TRUE when comparing letters to numbers. WHY?

Short question: WHY?!?
The below class returns ALL ALLRIGHT when calling:Status::validate('ab')
class Status
{
const FRESH = 0;
const PENDING = 25;
const CANCELLED = 50;
public static function validate($status)
{
switch ($status) {
case self::FRESH:
case self::PENDING:
case self::CANCELLED:
echo 'ALL ALLRIGHT';
default:
echo 'ERROR!';
}
die;
}
}
I believe it's because your $status is being casted to int.
$value = 'abc';
$other_value = '21abc';
echo (int)$value;
echo '<br>';
echo (int)$other_value;
Will return:
0
21
And that would cause it to think that ab value is equal to Status::FRESH
I'm not sure though if switch statement does this type of typecasting.
Edit
And I think I was right. More info here PHP Manual - switch.
Reference on typecasting strings to integers here PHP Manual - Strings.
break the case
switch($condition){
case "options": blah(); break;
}

Switch statement using strstr always validates as true?

I have the following switch statement.
The URL contains a referral ID e.g twitter, facebook or an email e.g mail#mail.com. This is stored as $ref
I have the following switch statement:
switch ($ref) {
case "twitter":
echo "twitter";
break;
case "facebook":
echo "facbeook";
break;
case "blog":
echo "blog";
break;
case strstr($ref,'#'):
echo "email = ".$ref;
default:
echo "no referral found";
break;
}
However if URL is passed with nothing (e.g just www.mything.co.uk) then I wish to go to the default case.
Instead, I get the following output:
email = no referral found
Why does the default also include the text I set for case strstr($ref,'#') ?
OP question: "Why does the default also include the text I set for case strstr($ref,'#') ?"
Answer: there's no break; following the output, and thus falls through to the default case.
UPDATE: Addressing the issue of putting a statement within a case, I'm also including an easy work-around:
switch ($ref) {
case "twitter":
echo "twitter";
break;
case "facebook":
echo "facbeook";
break;
case "blog":
echo "blog";
break;
default:
if (strstr($ref,'#')) {
echo "email = ".$ref;
} else {
echo "no referral found";
}
break;
}
When $ref is an empty String, then strstr($ref,'#'); returns an empty string too, this is why the case strstr($ref,'#'): matches the switch input $ref.
The problem is, you can't even use a email validation function like
filter_var($ref, FILTER_VALIDATE_EMAIL)
That would return false in case of an empty input instead of an empty string, but switch does loose comparison, meaning that an "" == false would return true:
http://php.net/manual/en/types.comparisons.php#types.comparisions-loose
Thus the only solution I see is to use an if statement using the === operator:
if($ref == 'twitter') {
echo "twitter";
} else if($ref == 'facebook') {
echo "facbeook";
} else if($ref == 'blog') {
echo "blog";
} else if($ref === filter_var($ref, FILTER_VALIDATE_EMAIL)) {
echo "email = ".$ref;
} else {
echo "no referral found";
}
That's because your test is performed like if ($ref == strstr($ref, '#')), where strstr returns false which equals an empty string. You cannot really use dynamic comparisons in switch statements. Use if..else if you need that. Alternatively, abuse switch a bit:
switch (true) {
case $ref == 'twitter':
..
case strstr($ref, '#'):
..
}
That will work:
case (strstr($ref, '#') ? true : false):
But it's not really good of practice.

php switch am I doing it wrong?

I'm trying to make multiple pages in 1 file and i have this
<?
switch($action){
case "add":
add();
break;
default:
hello();
break;
}
function add() {
echo "hello";
}
function hello() {
echo "hello1";
}
?>
but when I got to ****.php?action=add I still get "hello1"
what am I doing wrong with this to where I get hello
switch on $_GET['action'] instead.
<?php
$action= $_GET['action']
//$_REQUEST, by default, contains the contents of $_GET, $_POST and $_COOKIE.
// $action= $_REQUEST['action'];
switch($action){
case "add":
add();
break;
default:
hello();
break;
}
function add() {
echo "hello";
}
function hello() {
echo "hello1";
}
?>

Categories