Reference expression in switch - php

In PHP, is it possible to get a reference to the expression used in the switch statement?
For example:
switch ($_POST['id']) {
case 0:
$id = <switch expression>
break;
case 1:
$id = <switch expression>
break;
default
$id = null;
}
so if $_POST['id'] = 1, then $id = 1
Then I can test for if (! $id) {}
Obviously you are probably thinking why not just use $id = $_POST['id'] but in the real example it looks like this
switch (strtolower($load->post('payment_method')))
{
case 'paypal':
$payment_method = <switch/case expression>;
$payment_type = 'ewallet';
break;
case 'bitcoin':
$payment_method = <switch/case expression>;
$payment_type = 'ecurrency';
break;
default:
//$payment_method = null; // taken from card number
$payment_type = 'card';
}
I dont want $payment_method assigned.
HAD A EUREKA MOMENT WHILST WRITING THIS
Well, that works for what I was trying to achieve anyway.
switch (($payment_method = strtolower($load->post('payment_method'))))
{
case 'paypal':
$payment_type = 'ewallet';
break;
case 'bitcoin':
$payment_type = 'ecurrency';
break;
default:
unset($payment_method); // taken from card number
$payment_type = 'card';
}

There are no way
use for example such way
$cases = array(0, 1, 3 ,5);
$defaultVal = 1;
$id = in_array($_POST['id'], $cases) ? $_POST['id']: $defaultVal;

AFAIK there is no such feature in PHP.
But you can do what you are looking for as easy as this:
switch (strtolower($load->post('payment_method')))
{
case 'paypal':
$payment_method = 'paypal';
$payment_type = 'ewallet';
break;
case 'bitcoin':
$payment_method = 'bitcoin';
$payment_type = 'ecurrency';
break;
default:
$payment_method = null; // taken from card type
$payment_type = 'card';
}

Actually I just realize that this probably is possible using a simple workaround:
switch ($switch_value = strtolower($load->post('payment_method')))
{
case 'paypal':
$payment_method = $switch_value;
$payment_type = 'ewallet';
break;
case 'bitcoin':
$payment_method = $switch_value;
$payment_type = 'ecurrency';
break;
default:
$payment_method = null; // taken from card type
$payment_type = 'card';
}
;-)

Related

After adding detection of browser language, the language href anchor (hl) stops working

I know how to detect language browser in PHP and also how to detect the language href anchor for switching to another.
My old codes which doesn't have locale_accept_from_http($_SERVER['HTTP_ACCEPT_LANGUAGE']);:
if (isset($_GET['hl']))
{
$langOption = $_GET['hl'];
}
else
{
$langOption = '';
}
switch ($langOption):
case 'ca':
$language = 'cat';
break;
case 'el':
$language = 'el';
break;
case 'en':
$language = 'en';
break;
case 'en_GB':
$language = 'en_GB';
break;
case 'es':
$language = 'es';
break;
case 'fr':
$language = 'fr';
break;
case 'ka':
$language = 'ka';
break;
case 'nl':
$language = 'nl';
break;
case 'pt_PT':
$language = 'pt_PT';
break;
case 'pt_BR':
$language = 'pt_BR';
break;
case 'ro':
$language = 'ro';
break;
default:
$language = 'pt_BR';
break;
endswitch;
require_once("idiomas/{$language}.php");
These old codes worked very for language href anchors. Like:
<a class="waves-effect" href="?hl=en_GB" name="en">English</a>
<a class="waves-effect" href="?hl=pt_BR" name="pt_BR">Português Brasileiro</a>
I changed to codes to condense, economise and shorten the codes. Here are new codes:
$language = locale_accept_from_http($_SERVER['HTTP_ACCEPT_LANGUAGE']);
if (isset($_GET['hl']))
{
$lang = $_GET['hl'];
}
else
{
$lang = '';
}
switch ($lang):
case $language:
$language = $language;
break;
default:
$language = $language;
break;
endswitch;
require_once("idiomas/{$language}.php");
Only the detection of browser language worked very well, but the language href anchors (hl) do not work, because if you switch to Portuguese, the page still in English.
Similar like:
switch ($lang):
case "en":
$language = "en";
break;
case "en_GB":
$language = "en_GB";
break;
case "pt_BR":
$language = "pt_BR";
break;
case "pt_PT":
$language = "pt_PT";
break;
endswitch;
But I wouldn't like to repeat these old codes. I want to keep condensing and shortening the same new codes.
I don't understand what the switch statement is doing here?
The reason it's not working is because you're not using the $lang variable for anything, it's just setting $language to itself for all cases.
I think this would do what you want :
$language = locale_accept_from_http($_SERVER['HTTP_ACCEPT_LANGUAGE']);
if (isset($_GET['hl']))
{
$language = $_GET['hl'];
}
As query params can be modified by the user, I'd also suggest using in_array to check that the value is something expected.

Should I always use isset() for URL arguments?

Here is my code:
$order_newest = $order_votes = $order_featured = $order_frequent = '';
switch ($_GET['o']) {
case 'newest':
$order_newest = 'order_active';
break;
case 'votes':
$order_votes = 'order_active';
break;
case 'featured':
$order_featured = 'order_active';
break;
case 'frequent':
$order_frequent = 'order_active';
break;
default:
$order_newest = 'order_active';
break;
}
It throws following error when o argument isn't exist in the URL:
Notice: Undefined index: o in C:\xampp\htdocs... on line 71
I can fix the problem by adding this condition:
$order_newest = $order_votes = $order_featured = $order_frequent = '';
if ( isset($_GET['o']) ) {
switch ($_GET['o']) {
.
.
.
}
} else {
$order_newest = 'order_active';
}
But I guess this isn't the right way. Because in this case I have to add lots of conditions contain isset() function.
Anyway, is there any better approach to handle that?
Use filter_input(). As example:
$order = filter_input(INPUT_GET, 'o');
switch ($order) {
// ...

How to employ the factory pattern where the constructor arguments vary

I'm writing a package where I need to have PHP objects represent MySQL data types.
For example, I have classes for IntType, VarCharType, BlobType, etc.
Each of these have different constructor arguments. I.e. IntType has a signed property, VarChar has collation, etc.
The source for which of these types I need to construct from from the database. So I may have "INT(10) UNSIGNED", "VARCHAR(255)", and "BLOB".
So currently I have a method that examine and pull apart these strings, and it uses a lot of IF and SWITCH statements to determine which class needs to be constructed.
I know this is ugly but I'm not sure on the best way around it. All textbook examples of the Factory pattern are based on producing classes that have identical constructor arguments.
Currently I have two ideas to solve this:
Use something like the Chain Of Responsibility pattern, where I have a factory per data type, and each will decide if it can handle the data type string, and if it can't it will be passed onto the next factory.
Have a factory per data type, and a super factory that would examine the data type string to determine the correct data type factory to handle the string.
Because I have not see much theory on this, I'm a little unsure of the most ideal direction.
The following is the offending code to show exactly how ugly it is...
<?php
class Factory
{
// ...
/**
* #param string $dataTypeString Data type string as reported by MySQL when executing SHOW FULL COLUMNS FROM table;
* #param null $collation
*/
public function createDataType($dataTypeString, $collation = null)
{
$dataType = null;
if (preg_match('/^(tiny|small|medium|big)?int(eger)?\((\d+)\)( unsigned)?/i', $dataTypeString, $matches)) {
$displayWidth = $matches[3];
$signed = empty($matches[4]);
switch (strtolower($matches[1])) {
case 'tiny':
$dataType = new TinyIntType($displayWidth, $signed);
break;
case 'small':
$dataType = new SmallIntType($displayWidth, $signed);
break;
case 'medium':
$dataType = new MediumIntType($displayWidth, $signed);
break;
case 'big':
$dataType = new BigIntType($displayWidth, $signed);
break;
default:
$dataType = new IntType($displayWidth, $signed);
break;
}
} elseif (preg_match('/^(decimal|float|double)\((\d+),(\d+)\)( unsigned)?/i', $dataTypeString, $matches)) {
$precision = $matches[2];
$scale = $matches[3];
$signed = empty($matches[4]);
switch (strtolower($matches[1])) {
case 'decimal':
$dataType = new DecimalType($precision, $scale, $signed);
break;
case 'double':
$dataType = new DoubleType($precision, $scale, $signed);
break;
case 'float':
$dataType = new FloatType($precision, $scale, $signed);
}
} elseif (preg_match('/^(var)?binary\((\d+)\)$/i', $dataTypeString, $matches)) {
$isVarBinary = !empty($matches[1]);
$length = $matches[2];
if (strtolower($isVarBinary)) {
$dataType = new VarBinaryType($length);
} else {
$dataType = new BinaryType($length);
}
} elseif (preg_match('/^bit\((\d+)\)$/i', $dataTypeString, $matches)) {
$dataType = new BitType($matches[1]);
} else {
$characterSet = !empty($collation) ? $this->getCharacterSet($collation) : null;
if (preg_match('/^(var)?char\((\d+)\)$/i', $dataTypeString, $matches)) {
$isVarChar = !empty($matches[1]);
$length = $matches[2];
if ($isVarChar) {
$dataType = new VarCharType($length, $characterSet, $collation);
} else {
$dataType = new CharType($length, $characterSet, $collation);
}
} elseif (preg_match("/(set|enum)(\('.+'\))/i", $dataTypeString, $matches)) {
$options = $this->parseOptions($matches[2]);
switch (strtolower($matches[1])) {
case 'set':
$dataType = new SetType($options, $characterSet, $collation);
break;
case 'enum':
$dataType = new EnumType($options, $characterSet, $collation);
break;
}
} else {
switch (strtolower($dataTypeString)) {
case 'text':
$dataType = new TextType($characterSet, $collation);
break;
case 'tinytext':
$dataType = new TinyTextType($characterSet, $collation);
break;
case 'mediumtext':
$dataType = new MediumTextType($characterSet, $collation);
break;
case 'longtext':
$dataType = new LongTextType($characterSet, $collation);
break;
case 'blob':
$dataType = new BlobType();
break;
case 'tinyblob':
$dataType = new TinyBlobType();
break;
case 'mediumblob':
$dataType = new MediumBlobType();
break;
case 'longblob':
$dataType = new LongBlobType();
break;
}
}
}
return $dataType;
}
}
Update: This has been reposted at https://codereview.stackexchange.com/questions/134709/a-pattern-to-clean-up-this-factory-method

Php slice last item in an array not working

<?php
$current_store_type = get_field("valj_typ");
$last_type = array_slice($current_store_type, -1, 1, true);
$type_title = "";
switch($last_type){
case "Butik":
$type_title = "Alla butiker";
break;
case "Cafe":
$type_title = "Alla caféer";
break;
case "Restaurang":
$type_title = "Alla restauranger";
break;
case "Service":
$type_title = "Alla Serviceställen";
break;
}
?>
I want to slice out the last item in the $current_store_type array. But it only works if the field is having one variable, as soon as I get it into an array it does not work.
Update: not working either
$current_store_type = get_field("valj_typ");
$last_type = end($current_store_type);
$type_title = "";
switch($last_type){
case "Butik":
$type_title = "Alla butiker";
break;
case "Cafe":
$type_title = "Alla caféer";
break;
case "Restaurang":
$type_title = "Alla restauranger";
break;
case "Service":
$type_title = "Alla Serviceställen";
break;
}
I think this is what you want to achive. It doesn't use array_slice but will function properly. If you insist on using array_slice check out #Random's comment in your question.
$last_type = end($current_store_type);
This code did the trick for me:
$last_type = end($current_store_type);

PHP Switch using it with Functions

I have this switch and I do certain things based on the selection of the action with the switch. Based on my testing, function thats in the switch is not even taking place when the page runs.
I am interested in being able to running the sortby action for now. when I go to the page, switch puts me in the first case but does not run the function.Why? How do I fix it?
switch ($_GET['action']) {
case 'sortby':
sort_by($_GET['sortby']);
break;
case 'add':
resident_add($_GET['residentID']);
include('inc/modify/add.php');
break;
case 'edit':
resident_edit($_GET['residentID']);
include('inc/modify/edit.php');
break;
case 'delete':
resident_delete($_GET['residentID']);
include('inc/modify/delete.php');
break;
case 'search':
echo "";
break;
default:
resident_default($_GET['sortby']);
}
function sort_by($sortby) {
if ($sortby == "last_name") {
$sort_db_field = "Last Name";
$sort_order = "ASC";
} elseif ($sortby == "lot") {
$sort_db_field = "Lot";
$sort_order = "ASC";
} elseif ($sortby == "date_added") {
$sort_db_field = "No";
$sort_order = "DESC";
} else {
include('inc/error.php?error_code=100');
}
return $sort_db_field;
return $sort_order;
}
$data = mysqli_query($dbcon, "SELECT * FROM `residents` ORDER BY `residents`.`".$sort_db_field."` ".$sort_order."") or die(mysqli_error());
You can't have 2 return statements in a function, the second one will never be executed.
Declare two variable before your switch:
$sort_db_field = "";
$sort_order = "";
switch ($_GET['action']) {
/*snip*/
}
Then in the function drop the returns. This function will now set the values in the two variables you declared.

Categories