Converting If/Else to Switch [duplicate] - php

This question already has answers here:
switch statement with two variables at a time
(6 answers)
Closed 8 years ago.
How do I convert the below to a switch instead of If/Else? I read that if I have more than if/elseif/else that i should use a switch instead
$domain = ($_SERVER['HTTP_HOST']);
if ($_SERVER['HTTP_HOST']=="domain1.com" && strpos($_SERVER['REQUEST_URI'], 'ab03') !== false ) {
codeblock();
$tlink = "http://google.com";
} elseif ($_SERVER['HTTP_HOST']=="domain1.com" && strpos($_SERVER['REQUEST_URI'], 'ab05') !== false ) {
$tlink = "http://cnn.com";
} elseif ($_SERVER['HTTP_HOST']=="domain2.com" && strpos($_SERVER['REQUEST_URI'], 'ab05') !== false ) {
$tlink = "http://yahoo.com";
} elseif ($_SERVER['HTTP_HOST']=="domain3.com" && strpos($_SERVER['REQUEST_URI'], 'ab05') !== false ) {
$tlink = "http://example.com";
} else {
$tlink = "http://cbs.com";
}

You could have found this yourself in a 5 sec Google search...
switch($i){
case 0:
break;
}
Simply replace $i with $_SERVER['HTTP_HOST'] to compare and 0 with the wanted value example domain1.com.
http://php.net/manual/en/control-structures.switch.php
However the switch is not really adapted to your code as you have multiple conditions in your if. Since the second condition seems to be always the same, you could simply put the switch in the if of the second condition or use the clause inside each case but this would be redundant code.

try use code
switch ($domain) {
case 'domain1.com':
if(strpos($_SERVER['REQUEST_URI'], 'ab03') !== false) {
codeblock();
$tlink = "http://google.com";
} elseif(strpos($_SERVER['REQUEST_URI'], 'ab05') !== false ) {
$tlink = "http://cnn.com";
}
break;
case 'domain2.com':
if(strpos($_SERVER['REQUEST_URI'], 'ab05') !== false) {
$tlink = "http://yahoo.com";
}
break;
case 'domain3':
if(strpos($_SERVER['REQUEST_URI'], 'ab05') !== false ) {
$tlink = "http://example.com";
}
break;
default:
$tlink = "http://cbs.com";
break;
}

Related

How can I reduce lines of code in PHP? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I am a web developer and I write code in PHP/Laravel framework. I've been tying to follow best practice for writing code and I know it's a good practice to write 15-20 lines of code in functions and maximum 200 lines of code in Classes. But every time I end up writing minimum 40-50 lines in a function. for example here the code snippet which I wrote to get details of client and assigned users.
public function preMessageSend($client, $assigned)
{
$ticket_number = $client->ticket_number;
$title = $client->title;
$department = $client->department;
$priority = $client->priority;
if ($client->first_name !== null || $client->first_name !== '') {
$client_name = $client->first_name." ".$client->last_name;
} else {
$client_name = $client->username;
}
if ($client->email !== '' || $client->email !== null) {
$client_email = $client->email;
} else {
$client->email = 'Not available';
}
if($client->mobile !== null || $client->mobile !== '') {
$client_mobile = $client->code."".$client->mobile;
} else {
$client_mobile = 'Not available';
}
if($assigned != null) {
if ($assigned->first_name !== null || $assigned->first_name !== '') {
$assigned_name = $assigned->first_name." ".$assigned->last_name;
} else {
$assigned_name = $assigned->username;
}
if ($assigned->email !== '' || $assigned->email !== null) {
$assigned_email = $assigned->email;
} else {
$assigned->email = 'Not available';
}
if($assigned->mobile !== null || $assigned->mobile !== '') {
$assigned_mobile = $assigned->code."".$assigned->mobile;
} else {
$assigned_mobile = 'Not available';
}
if ($assigned->address !== null || $assigned->address !== '') {
$assigned_address = $assigned->address;
} else {
$assigned_address = 'Not available';
}
$this->sendMessageWithAssigned($ticket_number, $title, $department, $priority, $client_name, $client_email, $client_mobile, $assigned_name, $assigned_email, $assigned_mobile, $assigned_address);
} else {
$this->sendMessageWithoutAssigned($ticket_number, $title, $department, $priority, $client_name, $client_email, $client_mobile);
}
Please tell me how can I reduce the loc in my class and functions and what are the best practices to avoid writing such long functions.
TIA
First of all, null and '' is true for empty() so you could do:
if (!empty($client->first_name)) { // if not empty
$client_name = $client->first_name." ".$client->last_name;
} else {
$client_name = $client->username;
}
Then you could also use the ternary operator:
$client_name = !empty($client->first_name) ? $client->first_name." ".$client->last_name : $client->username;
Then for some statements there is also the or statement available:
$client_email = $client->email or 'Not available';
$client_mobile = $client->code . $client->mobile or 'Not available';
$assigned_address = $assigned->address or 'Not available';
These or statements are only equal to:
if(!empty($assigned->address)){
$assigned_address = $assigned->address;
} else {
$assigned_address = 'Not available';
}
// Or the equivalent ternary
$assigned_address = !empty($assigned->address) ? $assigned->address : 'Not available';
And what I mean for "some" is that:
$client->first_name = null;
$client->last_name = null;
echo empty($client->first_name." ".$client->last_name); // false
echo isset($client->first_name." ".$client->last_name); // true
is not empty even if both variables are null, due to the " " space which would make it isset()
Now be careful with those or statements because !empty() does not always give the opposite results as isset() where isset([]) is true and where empty([]) is also true.
Instead of
if ($client->first_name !== null || $client->first_name !== '') {
$client_name = $client->first_name." ".$client->last_name;
} else {
$client_name = $client->username;
}
You could do:
$client_name = ($client->first_name !== null || $client->first_name !== '') ? $client->first_name." ".$client->last_name : $client->username;
As others already suggested, you can use empty() instead of the != null and != '' checks. Furthermore, you could omit the else part in most statements, e.g.:
$assigned_name = $assigned->username;
if (!empty($assigned->first_name)) {
$assigned_name = $assigned->first_name." ".$assigned->last_name;
}
This sets $assigned_name to your former else value by default and if the condition is met $assigned_name gets overwritten. I don't recommend using ternary operator because it's not that readable IMO.
I wouldn't worry too much about lines of code anyway as long as the code is readable and efficient.

Check if two vars are set?

Depending on whether 2 vars are set ($skip and $take) I want to do different things. I have a large if else statement, is there a more efficient way to write this?
if (isset($skip) && !isset($take)) {
//skip only
} elseif (!isset($skip) && isset($take)) {
//take only
} elseif (isset($skip) && isset($take)) {
//skip and take
} else {
//default
}
Edit
It should also be noted that this is to sit in a method where the vars will be set to null if not specified:
getAll($skip = null, $take = null)
You can simplify the logic a bit:
if (isset($skip) && isset($take)) {
// skip and take
} elseif (isset($skip)) {
// only skip
} elseif (isset($take)) {
// only take
} else {
// default
}
Since the OP clarified in a comment that this is inside a method, and both $skip and $take are arguments with default values, one might favor === over isset. Furthermore, you can re-arrange the logic a bit:
function getAll($skip = null, $take = null) {
if ($skip !== null && $take !== null) {
// both
} elseif ($skip !== null) {
// skip only
} elseif ($take !== null) {
// take only
} else {
// none
}
}
The === operator enforces an equality check with type safety.
The way default values for arguments work, the arguments are always guaranteed to be null if you don't pass them, so the equality check is a good way to check them here.
if you dont like if else
$switch = (int)isset($skip) + (int)isset($take)*2;
switch($switch){
case 0:
//default
break;
case 1:
//only skip
break;
case 2:
//only take
break;
case 3:
//skip and take
break;
}

Prestashop remove one checkout step

I'm new to prestashop and I'm having major trouble removing the address(I want to have only Summary=Shrnutí, Login/Guest Checkout=Přihlásit se, Delivery=Doručení and Payment=Platba here https://www.enakupak.cz/objednavka?step=1) step,. I am using prestashop 1.6.1.5
I know I have to modify order-carrier.tpl file and have followed several posts here and there but couldn't get it done right.
Does any of you have any actual idea on how to do this ?
I think that it will be change in this part of OrderController.php but dont know how to concretly change it
switch ((int)$this->step) {
case OrderController::STEP_SUMMARY_EMPTY_CART:
$this->context->smarty->assign('empty', 1);
$this->setTemplate(_PS_THEME_DIR_.'shopping-cart.tpl');
break;
case OrderController::STEP_DELIVERY:
if (Tools::isSubmit('processAddress')) {
$this->processAddress();
}
$this->autoStep();
$this->_assignCarrier();
$this->setTemplate(_PS_THEME_DIR_.'order-carrier.tpl');
break;
case OrderController::STEP_PAYMENT:
// Check that the conditions (so active) were accepted by the customer
$cgv = Tools::getValue('cgv') || $this->context->cookie->check_cgv;
if ($is_advanced_payment_api === false && Configuration::get('PS_CONDITIONS')
&& (!Validate::isBool($cgv) || $cgv == false)) {
Tools::redirect('index.php?controller=order&step=2');
}
if ($is_advanced_payment_api === false) {
Context::getContext()->cookie->check_cgv = true;
}
// Check the delivery option is set
if ($this->context->cart->isVirtualCart() === false) {
if (!Tools::getValue('delivery_option') && !Tools::getValue('id_carrier') && !$this->context->cart->delivery_option && !$this->context->cart->id_carrier) {
Tools::redirect('index.php?controller=order&step=2');
} elseif (!Tools::getValue('id_carrier') && !$this->context->cart->id_carrier) {
$deliveries_options = Tools::getValue('delivery_option');
if (!$deliveries_options) {
$deliveries_options = $this->context->cart->delivery_option;
}
foreach ($deliveries_options as $delivery_option) {
if (empty($delivery_option)) {
Tools::redirect('index.php?controller=order&step=2');
}
}
}
}
$this->autoStep();
// Bypass payment step if total is 0
if (($id_order = $this->_checkFreeOrder()) && $id_order) {
if ($this->context->customer->is_guest) {
$order = new Order((int)$id_order);
$email = $this->context->customer->email;
$this->context->customer->mylogout(); // If guest we clear the cookie for security reason
Tools::redirect('index.php?controller=guest-tracking&id_order='.urlencode($order->reference).'&email='.urlencode($email));
} else {
Tools::redirect('index.php?controller=history');
}
}
$this->_assignPayment();
if ($is_advanced_payment_api === true) {
$this->_assignAddress();
}
// assign some informations to display cart
$this->_assignSummaryInformations();
$this->setTemplate(_PS_THEME_DIR_.'order-payment.tpl');
break;
default:
$this->_assignSummaryInformations();
$this->setTemplate(_PS_THEME_DIR_.'shopping-cart.tpl');
break;
}
What if you cann this code after first case - break:
case OrderController::STEP_SUMMARY_EMPTY_CART:
$this->context->smarty->assign('empty', 1);
$this->setTemplate(_PS_THEME_DIR_.'shopping-cart.tpl');
break;
After this case add this case:
case OrderController::STEP_ADDRESSES:
$this->_assignAddress();
$this->processAddressFormat();
if (Tools::getValue('multi-shipping') == 1) {
$this->_assignSummaryInformations();
$this->context->smarty->assign('product_list', $this->context->cart->getProducts());
$this->setTemplate(_PS_THEME_DIR_.'order-address-multishipping.tpl');
} else {
$this->autoStep();
$this->_assignCarrier();
$this->setTemplate(_PS_THEME_DIR_.'order-carrier.tpl');
}
break;
Check, is it work.

Comparisons in switch cases, are they valid?

Thats the code:
switch (true)
{
case (isset($_REQUEST['a']) && is_numeric($_REQUEST['a']) && ($_REQUEST['a'] > 0)):
case (isset($_REQUEST['b']) && is_string($_REQUEST['b']) && in_array($_REQUEST['b'], $barray)):
case (isset($_REQUEST['c']) && is_numeric($_REQUEST['c']) && ($_REQUEST['c'] > 0) && ($_REQUEST['c'] <= $cbase)):
try { echo "Foo"; }
catch(Exception $e) { echo $e->getMessage(); }
break;
default:
echo "Bar"; break;
}
I'm wondering if these are allowed for use in switch cases?
Very soon I must use switch because of many comparisons and willing to try it. In this case 3rd case gives me always correct output, even when $_REQUEST['c'] is bigger than $cbase, while should fall to default :|
Yes this is valid. Using switch(TRUE) enables you to have strict comparisons in a switch statement. check this examples:
Not typesafe:
$a = '1';
switch($a) {
case 1 :
// do something (will get executed)
break;
case '1' :
// do something:
break;
}
Better:
$a = '1';
switch(TRUE) {
case $a === 1 :
// do something; (will not get executed)
break;
case $a === '1' :
// .. do something;
break;
}
Also this usage allows for more complex case statements, like this:
switch(TRUE) {
case strpos($input, 'a') === 0 :
// do something
break;
case strpos($input, 'b') === 0 :
// do something
break;
}

Cannot figure out how to create this if statement

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;
}

Categories