PHP Loose comparison and null on Switch - php

Today I saw a strange bug on my code.
I have a switch with comparison on case and if my variable equals null or '' it will always comes in the first case.
My code :
$sHost = filter_input(INPUT_SERVER, 'HTTP_HOST');
switch($sHost){
// Local
case strpos($sHost, "dev.localhost") !== false: $this->_sEnv = 'local';
break;
// Prod
default: $this->_sEnv = 'production';
break;
}
On an if statement it's work but on switch case it doesn't work , I don't know why .. Maybe a PHP problems ? Anyone has had a similar bug ?
$sHost can be null because sometimes I run the script with a batch.
if(strpos($sHost, "dev.localhost") !== false){
// Nothing
}
else{
return false;
}
Of course I can do an if is_null before the switch , but I want to understand why it's working like that..
Edit: I forgot to said I have 5 cases on my switch , one case by environment
Thank you for your future answer :)

If $sHost equals to null or '', then the first switch case is always true because
var_dump($sHost == (strpos($sHost, "dev.localhost") !== false));
is true. How switch work.
You can do this:
switch(true) {
// Local
case strpos($sHost, "dev.localhost") !== false:
$this->_sEnv = 'local';
break;
// Prod
default:
$this->_sEnv = 'production';
break;
}

switch(strpos($sHost, "dev.localhost")){
// Local
case -1: $this->_sEnv = 'production';
break;
// Prod
default: $this->_sEnv = 'local';
break;
}
#Leggendario, good point, fixed above.

Related

How to get everything after an '#'-selector in the url in php

I'm coding a CDN in PHP, it works this far, but I want to choose different versions by adding an '#' with the version behind it. How do I get the version String after the '#'.
Example: https://cdn.steven2105.de/jquery#3.3.0
<?php
$error = false;
$path = str_replace("/", "", $_SERVER['REQUEST_URI']);
switch($path) {
case "jquery":
$toOpen = "jquery/3.3.1/jquery.min.js";
break;
case "jquery#3.3.0":
$toOpen = "jquery/3.3.0/jquery.min.js";
break;
case "vue":
$toOpen = "vue/2.6.10/vue.min.js";
break;
case "bootstrap-css":
$toOpen = "bootstrap/4.3.1/bootstrap.min.css";
break;
case "bootstrap-js":
$toOpen = "bootstrap/4.3.1/bootstrap.min.js";
break;
case "baguettebox-css":
$toOpen = "baguettebox/1.11.0/baguettebox.min.css";
break;
case "baguettebox-js":
$toOpen = "baguettebox/1.11.0/baguettebox.min.js";
break;
case "popper":
$toOpen = "popper/1.14.7/popper.min.js";
break;
default:
$error = true;
break;
}
if (!$error) {
header("Location: https://cdn.steven2105.de/libs/$toOpen");
} else {
include_once "website.php";
}
EDIT: What should I do now? It doesn't work.
I have different libaries in the path https://cdn.steven2105.de/libs/ e.g. https://cdn.steven2105.de/libs/jquery with files in it such like https://cdn.steven2105.de/libs/jquery/3.3.1/jquery.min.js. I'd like to access these links with a shorter prefix like https://cdn.steven2105.de/jquery#3.3.1. If I use the '#' character it should redirect to the version in the directory https://cdn.steven2105.de/libs/jquery/ and if it's without the '#' it should redirect to the latest version.
What is the easiest way?
You can use explode function for this. It Outputs as an array and fetch it.
<?php
$URL = ' https://cdn.steven2105.de/jquery#3.3.0';
$Result = explode('#', $URL);
echo("<pre>");print_r($Result[1]);
?>
Instead of using PHP you could probably fix this with webserver configuration.
Rewrite rules in Apache (https://httpd.apache.org/docs/2.4/rewrite/remapping.html) should do the trick. I would expect Nginx to offer similar functionality.
If you use Apache or Nginx to do this for you it will be way faster as you won't have the overhead of running a PHP script.

Switch and if statement returns the first case condition regardless if it is true or not

I am working on a , project which i have configured to serves multiple pages from one index.php file using a switch statement like this:
switch(isset($_GET['q']{
case 'page':
require 'link_to_page.php';
break;
case 'login':
require = 'link_to_login.php';
break;
default:
require = 'link_to_404.php';
break;
}
As time goes by and more pages are added, i decided to move it to a selectPage() function which i now called and assigned to a variable $page and required it in my index.php file to make things simpler like this:
myFunctions.php
selectPage()
{
switch(isset($_GET['q']{
case 'page':
$output = 'link_to_page.php';
break;
case 'login':
$output = 'link_to_login.php';
break;
default:
$output = 'link_to_404.php';
break;
return $output;
}
}
My index.php looks like this:
require 'myFunctions.php';
$page = selectPage();
require $page;
Now the problem here is, regardless of which case is true case page: or case 'login':, $output returned is always equal to the first line of case condition checked, for example when case page: is the first line of case statement and $_GET['q'] == 'login', case page: $output value is returned, when i swapped the case 'login': with case page: for it to be the first condition checked, case 'login': $output value which is now the first line of condition is returned even if $_GET['q'] == 'page'.
i have also tried it with an if(statement) and the same thing happened.
How do i fix this, is there something am doing wrong?
Syntax error your Switch statement.
Right SYNTAX :
switch (n) {
case label1:
code to be executed if n=label1;
break;
case label2:
code to be executed if n=label2;
break;
case label3:
code to be executed if n=label3;
break;
...
default:
code to be executed if n is different from all labels;
}
So, myFunctions.php Page
function selectPage()
{
$page = isset($_GET['q']) ? $_GET['q'] : null;
switch ($page) {
case "page":
return 'link_to_page.php';
break;
case "login":
return "link_to_login.php";
break;
default:
return "link_to_404.php";
}
}
index.php page
require 'myFunctions.php';
$page = selectPage();
require $page;
Try this:
switch($_GET['q']){
....
}
You try to check $_GET['q'] but really you check isset($_GET['q']), so when PHP gets true it tries to compare values you give in case statement with true. And as your value are not empty or false values, that condition is true, and code under it will execute.

Syntax for multiple switch statement to detect server environment [duplicate]

This question already has answers here:
Switch case with three parameters?
(7 answers)
Closed 8 years ago.
I need to detect different server environments in my site's config file. Up until now I was fine with detecting them using only the server's address.
switch ( $_SERVER['SERVER_ADDR']){
case '127.0.0.1':
// stuff
break;
case '111.222.333.444';
// stuff
break;
}
But I now need to test my environment against both the SERVER_ADDR and SERVER_NAME. I'm no php'er, so I've had a stab at
switch ( $_SERVER['SERVER_ADDR'] && $_SERVER['SERVER_NAME'] ){
case ('127.0.0.1','local'):
// stuff
break;
case ('111.222.333.444','gimmesomefunk.com');
// stuff
break;
}
But it's obviously wrong. Any clues?
If you want to keep using switch, you'll have to combine both to one variable like this:
switch (array($_SERVER['SERVER_ADDR'], $_SERVER['SERVER_NAME'])){
case array('127.0.0.1', 'local'):
// stuff
break;
case array('111.222.333.444', 'gimmesomefunk.com'):
// stuff
break;
}
However, the more normal way would be to use if, elseif:
if ( $_SERVER['SERVER_ADDR'] == '127.0.0.1' && $_SERVER['SERVER_NAME'] == 'local' ) {
// stuff
} elseif ( $_SERVER['SERVER_ADDR'] == '111.222.333.444' && $_SERVER['SERVER_NAME'] == 'gimmesomefunk.com' ) {
// stuff
}
I'm not sure it s the best method but you can concatenate values like this :
switch ( $_SERVER['SERVER_ADDR'].$_SERVER['SERVER_NAME'] ){
case ('127.0.0.1local');
// stuff
break;
case ('111.222.333.444gimmesomefunk.com');
// stuff
break;
}
You can't do this, as what you're actually entering the switch statement with is a boolean (true) because you're saying "is this string truthy, and this string truthy":
var_dump($_SERVER['SERVER_ADDR'] && $_SERVER['SERVER_NAME']) // bool(true)
You could simply do the following by using an if statement instead (you don't have to use $address and $name, but in my opinion it becomes more readable):
$address = $_SERVER['SERVER_ADDR'];
$name = $_SERVER['SERVER_NAME'];
if ($address === '127.0.0.1' && $name === 'local') {
// Stuff
} else if ($address === '111.222.333.444' && $name === 'gimmesomefunc.com') {
// Other stuff
}

switch using $_SERVER['HTTP_HOST'] always defaults to first

I have the following code:
<?php
echo $_SERVER['HTTP_HOST'];
// CONFIGURATION ITEMS
$captcha_private_key = '';
$captcha_public_key = '';
switch ($_SERVER['HTTP_HOST']) {
case 'earth-neighbours.com' || 'www.earth-neighbours.com':
$captcha_private_key = '6Lcb_t4SAAAAALkdH4njSny2HYbrmGKS_G84kM_d';
$captcha_public_key = '6Lcb_t4SAAAAAPEtqJEcWXuo0zmRD5PxYkXx84R4';
echo 'live';
break;
case 'earth-neighbours.projects.mi24.net':
$captcha_private_key = '6Lca_t4SAAAAAJb5L4sA7fEHxDFA0Jl8jFw-h3hE';
$captcha_public_key = '6Lca_t4SAAAAAFd-Q2k8esFa9U8nQ2rirEZHFtAH';
break;
case 'earth-neighbours.local':
$captcha_private_key = '6LcZ_t4SAAAAAGc1_S9ahxo-Vg-e7QgHg4yAWBVU';
$captcha_public_key = '6LcZ_t4SAAAAAPHQDb_f-g4mS6mpmc0heustHQ60&hl';
echo 'local';
break;
}
?>
It's running on the local server (earth-neighbours.local) so should output 'local'. Instead it outputs 'live'. The echo at the top however (echo $_SERVER['HTTP_HOST'];) returns the url earth-neighbours.local so it should be 'local' that is echoed. This has me stumped. I had it working before and now I've shifted it to the top of the page and it doesn't work. Weird! Anyone?
PHP does not do switch case or statements like other programming languages.
When you write the following:
switch ($test) {
case 1 || 2:
$blah();
break;
}
This is what actually happens:
switch ($test) {
if (true == $test) {
}
}
The reason this happens is because the case content actually gets evaluated, and in PHP, 1 || 2 === true. PHP then does a typecast on $test to boolean, and $test, unless empty, comes out true.
The PHP "correct" syntax is:
switch ($test) {
case 1:
case 2:
$blah();
break;
In PHP (and a few other languages, actually), once the interpreter gets in the switch, the only way it will come out is by break. Not breaking at the end of a case tells it to continue.
Use:
case 'earth-neighbours.com':
case 'www.earth-neighbours.com':
instead of:
case 'earth-neighbours.com' || 'www.earth-neighbours.com':
As that is an incorrect syntax for the switch statement

PHP Switch ID error in Navigation

I’m working on a site and I kept getting a
Notice: Undefined index: id in file root on line 3
I know its something simple but can’t figure out where the problem lies exactly.
here is the code:
<?php
switch($_GET['id']) {
default:
include('pages/hello.php');
break;
case "testimonials":
include('pages/testimonials.php');
break;
case "faq":
include('pages/faq.php');
break;
case "raq":
include('pages/raq.php');
break;
case "contact":
include('pages/contact.php');
break;
}
?>
line 3 would be <?php switch($_GET['id']) {
any help would be greatly appreciated!
This is because in your url id=x is not always set, so when your trying to switc hthe value its not there. what you should do is like so:
<?php
$id = isset($_GET['id']) ? $_GET['id'] : ''; //This is just a short if-else
switch($id)
{
default:
include('pages/hello.php');
break;
case "testimonials":
include('pages/testimonials.php');
break;
case "faq":
include('pages/faq.php');
break;
case "raq":
include('pages/raq.php');
break;
case "contact":
include('pages/contact.php');
break;
}
?>
Basciall $id = isset($_GET['id']) ? $_GET['id'] : ''; what this says is, IF id is within the url then use that, otherwise use an empty string, the reason for the empty string is it will trigger the default: within the switch statement
this way $id will always be set to something.
Make sure that id is set and the default should go at the end:
if (!isset($_GET['id'])) {
include('pages/hello.php');
}
else{
switch($_GET['id']) {
case "testimonials": include('pages/testimonials.php'); break;
case "faq": include('pages/faq.php'); break;
case "raq": include('pages/raq.php'); break;
case "contact": include('pages/contact.php'); break;
default: include('pages/hello.php'); break;
}
}
For security reasons, make sure to sanitalize yor $_GET['id']. I would suggest you to setup an array of allowed pages and include those that are in the array. You can use in_array function for that.
It seems that the url parameter 'id' is not defined, that's the cause of the notice.
You should first check for its existence, eg.
if (isset($_GET['id'])) {
your code here
}

Categories