Switch case for array combination - php

I've written a switch which needs to match any combinations in the predefined array but now its matching only if all the combination from the given array is succeeded. But I want to match any combination from the array.
example : if my combination consists only 'man','cisman' then also my combination needs to succeed and needs to return $result = "male.png";. But if any item otherthan the given combination needs to rejected and needs to return default case.
Working demo
$menCombo = ['man','cisman','transmasculine','transman'];
$womanCombo = ['woman','ciswoman','transfeminine','transwoman'];
switch($genderdetail) {
case count(array_intersect($menCombo, $genderdetail)) === count(($menCombo)):
case "man":
case "cisman":
case "transman":
case "transmasculine":{
$result = "male.png";
break;
}
case count(array_intersect($womanCombo, $genderdetail)) === count(($womanCombo)):
case "woman":
case "ciswoman":
case "transfeminine":
case "transwoman":{
$result = "female.png";
break;
}
default: {
$result = "others.png";
break;
}
}

As mentioned in the comments, if $genderdetail isn't an array, you make it one. Now, if array difference of 2 arrays returns empty, it sure has to belong to the haystack array in comparison.
<?php
$genderdetail = ['man','cisman'];
$menCombo = ['man','cisman','transmasculine','transman'];
$womanCombo = ['woman','ciswoman','transfeminine','transwoman'];
$result = 'others.png';
if(!is_array($genderdetail)){
$genderdetail = [ $genderdetail ];
}
if(empty(array_diff($genderdetail, $menCombo))){
$result = 'male.png';
}else if(empty(array_diff($genderdetail, $womanCombo))){
$result = 'female.png';
}
echo $result;

What about changing the count condition to
case count(array_intersect($menCombo, $genderdetail)) === count(($genderdetail)):
you count the array mayches and not the long array of poszibilities. Same for the female count.

Related

Switch case does not pick up the correct case when using is_numeric

So, i have the following switch case (i've only put 3 for this example, but there are more...).
if (isset($_GET['cat'])) {
$get_category = trim($_GET['cat']);
switch ($get_category) {
case is_numeric($get_category):
echo 'is_numeric';
// execute query
break;
case 'newest':
echo 'newest';
// execute query
break;
case '':
echo 'empty';
// execute query
break;
}
}
When my $_GET['cat'] is empty, i'm getting is_numeric and i'm supposed to get empty.
I've tried looking at the $_GET['cat] array, and i get this:
Array
(
[cat] =>
)
I've also checked the type and i get string:
echo gettype($get_category); // returns: string
I've also use an if statement to verify if it picks up is numeric but it doesn't, it picks up string
if (is_numeric($get_category)) {
echo 'numeric';
} else {
echo 'string';
}
// returns: string
So, why is it that my switch statement does not pick up the correct case?

PHP - Change value of variable before inserting into sql - Without Ajax

I have the variable
$sql1 .= "Brukertype";
Which gets information set from an already-filled textbox. It can either have the value Administrator or the value Iskjører.
What is the best way to change these values before inserting them into SQL?
The Administrator value should get changed to the value 1 and Iskjører gets changed to the value 2.
I can't use a select function (dropdown list) on the question because it needs to be enabled/disabled on my command.
This is a reasonable place to use a switch statement. You want a 'marshaling' function, like this:
function marshal_input($input) {
$result = 0;
switch ($input){
case 'Administrator':
$result = 1;
break;
case 'Iskjører':
$result = 2;
break;
case 'SomethingYouHaventThoughtOfYet':
$result = 3;
break;
default:
$result = 0;
break;
}
}
However, the implementation of the marshaling function can be almost anything:
function marshal_input($input) {
$options = array("Administrator" => 1, "Iskjører" =>2);
return $options[$input];
}
The point is that you need some code that maps from the human-readable form to the numerical representation the db needs. Then you just call it like so:
$sql_version = marshal_input($sql1);//Doesn't overwrite the variable
//...or...
$sql1 = marshal_input($sql1);//Note this overwrites the variable.
Since you have stated:
It can eighter have the value "Administrator" or the value "Iskjører"...
we only check whether the value is 'Administrator' or not.
Try this:
$val = 'Administrator'; // user input variable
$sql_val = ($val == 'Administrator') ? 1 : 2;
If value is 'Administrator' set $sql_val to 1, else set $sql_val to 2

PHP Multidimensional Array Value Replacement

I have been working on a project recently for fun.
It retrieves JSON from a game server, decodes it into an array, and then saves the array values into a SQLite DB (for display / manipulation later). I am new to programming in general, and have never touched PHP prior to this.
My question: Is there a better, more efficient way to handle this?
Basically, this section of code, loops through the large multidimensional array, and replaces values that are equal to a string. It does this prior to insertion into the DB so that I can have fields formatted to be more readable.
The problem is that in the actual script I have a huge list of defined variables now, and like 3 foreach loops with a combined 15 or so if/else if/else statements.
$sr = "Summoners Rift";
$rs = "Ranked Solo";
$rt = "Ranked Team";
$nr = "Normal";
foreach ($history['games'] as &$typeMode)
{
if ($typeMode['subType'] == 'RANKED_SOLO_5x5')
{
$typeMode['gameMode'] = $sr;
$typeMode['subType'] = $rs;
}
elseif ($typeMode['subType'] == 'RANKED_TEAM_5x5')
{
$typeMode['gameMode'] = $sr;
$typeMode['subType'] = $rt;
}
elseif ($typeMode['subType'] == 'NORMAL')
{
$typeMode['gameMode'] = $sr;
$typeMode['subType'] = $nr;
}
}
The problem is that in the actual script I have a huge list of defined
variables now, and like 3 foreach loops with a combined 15 or so IF /
ELSEIF / ELSE statements.
The best solution I can recommend based on the data your are showing is to just create a basic array of structures connected to the data you have and then just use the foreach loop to assign values based on that initial array structure:
// Set structured array values.
$array_values = array();
$array_values['RANKED_SOLO_5x5']['gameMode'] = "Summoners Rift";
$array_values['RANKED_SOLO_5x5']['subType'] = "Ranked Solo";
$array_values['RANKED_TEAM_5x5']['gameMode'] = "Summoners Rift";
$array_values['RANKED_TEAM_5x5']['subType'] = "Ranked Team";
$array_values['NORMAL']['gameMode'] = "Summoners Rift";
$array_values['NORMAL']['subType'] = "Normal";
// Set structured array values based on the sub type.
foreach ($history['games'] as &$typeMode) {
$typeMode['gameMode'] = $array_values[$typeMode['subType']]['gameMode'];
$typeMode['subType'] = $array_values[$typeMode['subType']]['subType'];
}
That way $array_values always has the preset values in place to begin with. And the assignment just happens via an array key access of $typeMode['subType'] in the foreach loop.
For things like this I prefer to use the switch control structure instead of if/elseif/else, although your approach is perfectly fine, if a little verbose maybe:
foreach ($history['games'] as &$typeMode)
{
$typeMode['gameMode'] = $sr;
switch($typeMode['subType'])
{
case 'RANKED_SOLO_5x5':
$typeMode['subType'] = $rs;
break;
case 'RANKED_TEAM_5x5':
$typeMode['subType'] = $rt;
break;
case 'NORMAL':
$typeMode['subType'] = $nr;
break;
}
}
Also if $typeMode['gameMode'] always equals $sr; then you only need that line once.

php: looping thru results from mysql query to increment counter (associative array)

I'm retrieving data from a MySQL db and creating reports from it. I need to get counts when certain conditions are met, and since db queries are rather expensive (and I will have a lot of traffic), I'm looping thru the results from a single query in order to increment a counter.
It seems like it's working (the counter is incrementing) and the results are somewhat close, but the counters are not correct.
At the moment, there are 411 records in the table, but I'm getting numbers like 934 from a ['total'] counter and 927 for ['males'], and that definitely can't be right. However, I get 4 from ['females'], which is correct…
I'm pretty sure it was working last night, but now it's not—I'm quite baffled. (there are still just 411 records)
$surveydata = mysql_query("SELECT `age`,`e_part`,`gender` FROM $db_surveydata;") or die(mysql_error());
$rowcount = mysql_num_rows($surveydata);
$age=array('18+'=>0,'<18'=>0,'total'=>0);
$e_part=array('yes'=>0,'no'=>0,'total'=>0);
$genders=array('male'=>0,'female'=>0,'trans'=>0,'don\'t know'=>0,'total'=>0);
while ($responses = mysql_fetch_assoc($surveydata)) {
foreach ($responses as $response){
switch ($response){
case $responses['age']:
if ($responses['age'] > 18) {$age['18+']++;$age['total']++;}
// i tried putting the ['total'] incrementer in the if/else
// just in case, but same result
else {$age['<18']++;$age['total']++;}
break;
case $responses['e_part']:
if ($responses['e_part']) {$e_part['yes']++;}
else {$e_part['no']++;}
$e_part['total']++;
break;
case $responses['gender']:
switch ($responses['gender']){
case 1:$genders['male']++;break;
case 2:$genders['female']++;break;
case 3:$genders['trans']++;break;
case 9:$genders['don\'t know']++;break;
default:break;
}
$genders['total']++;
break;
default:break;
} // end switch
} //end for
} // end while
thanks!
this is the problem:
foreach ($responses as $response){
switch ($response){
case $responses['age']:
switch $responses looks for match
foreach ($responses as $k=>$v){
switch ($k){
case 'age':
if ($v > 18) ....
mysql_fetch_assoc() retrieves a single row from the table. You then loop over that row, processing each individual field. Then the long set of if() checks to determine which field you're on. That entire structure could be changed to:
while($response = mysql_fetch_assoc($surveydata)) {
if ($responses['age'] > 18) {
$age['18+']++;
} else {
$age['<18']++;
$age['total']++;}
if ($responses['e_part']) {
$e_part['yes']++;
} else {
$e_part['no']++;
}
$e_part['total']++;
switch ($responses['gender']){
case 1:$genders['male']++;break;
case 2:$genders['female']++;break;
case 3:$genders['trans']++;break;
case 9:$genders['don\'t know']++;break;
default:break;
}
$genders['total']++;
}
There's no need for the switch ($response); you can't really switch on an array like that. And even if you could, the 'values' you get wouldn't make any sense -- i'm thinking if it works at all, the value you're switching on would be either 'Array' or the length of the array. (I forget how PHP handles arrays-as-scalars.)
You'll want something like this...
$total = 0;
while ($response = mysql_fetch_assoc($surveydata))
{
if (isset($response['age']))
{
++$age[($response['age'] < 18) ? '<18' : '18+'];
++$age['total'];
}
if (isset($response['e_part']))
{
++$e_part[($responses['e_part']) ? 'yes' : 'no'];
++$e_part['total'];
}
if (isset($response['gender']))
{
switch ($response['gender'])
{
case 1: ++$genders['male']; break;
case 2: ++$genders['female']; break;
case 3: ++$genders['trans']; break;
case 9: ++$genders["don't know"]; break;
}
++$genders['total'];
}
++$total;
}
The benefit of the if (isset(...)) is that if 'age', 'e_part', or 'gender' is null, the corresponding code to count it won't get activated. It does about the same thing as your code, minus the embarrassing loop -- and minus the counting of the field even though it is null, because every row will have the same fields.

Badge system and storing conditions as variables?

I'm trying to write a piece of code that checks a users stats, be that their points, rank or num_friends and in turn awards them a badge similar to that used in SO. The system is set so when a task (vote up, comment, etc.) is completed by a user, their user_id is recorded and queued to be evaluated at 5 min intervals by a cron job. Is this the most efficient way of doing this? I saw the other post about badges but am not sure if this is the method that was selected as the preferred way.
Another question I have is about actually checking these variables (points, rank, num_friends) against the user. I have a number of badges and want to allow admins to add their own where they select a variable, the operator (==, >=, etc.) and the value it's set to. How do I evaluate that in an IF conditional statement? I tried using SWITCH for the operators but can't get the variables to be evaluated correctly, like:
function checkbadges($userid,$points,$rank,$friends){
global $database;
$q = $database->db_query("SELECT * FROM badges");
while($bq = $database->db_fetch_assoc($q)) {
switch($bq[badge_sign]) {
case "1":
if($bq[badge_var] == $bq[badge_value])
givebadge($userid, $bq[badge_id]);
break;
case "2":
if($bq[badge_var] >= $bq[badge_value]))
givebadge($userid, $bq[badge_id]);
break;
case "3":
if($bq[badge_var] <= $bq[badge_value]))
givebadge($userid, $bq[badge_id]);
break;
case "4":
if($bq[badge_var] != $bq[badge_value]))
givebadge($userid, $bq[badge_id]);
break;
}
}
}
I think I have to use eval() but I'm not sure how, any help would be appreciated!
If $bq['badge_var'] is a string which is a valid variable name in the current scope, you can just do this:
$value = ${ $bq['badge_var'] };
It might be safer and easier to extend if you pass an array to checkbadges() instead:
function checkbadges($userid,$userdata){
global $database;
$q = $database->db_query("SELECT * FROM badges");
while($bq = $database->db_fetch_assoc($q)) {
$currentValue = $userdata[ $db['badge_var'] ];
$requiredValue = $db['badge_value'];
$issueBadge = false;
switch($bq['badge_sign']) {
case "1":
$issueBadge = ( $currentValue == $requiredValue );
break;
case "2":
$issueBadge = ( $currentValue >= $requiredValue );
break;
case "3":
$issueBadge = ( $currentValue <= $requiredValue );
break;
case "4":
$issueBadge = ( $currentValue != $requiredValue );
break;
}
if ($issueBadge) {
givebadge($userid, $bq['badge_id']);
}
}
}
where $userdata is something like this:
array( 'points' => 1 , 'friends' => 10, 'rank' => 10 );
You can then extend the available variables without modifying the function
Which is the expected value and the observed value of the variable you are not getting the right value for?
Additionally, its better practice to use:
$arr['key']
instead of
$arr[key]
as PHP will evaluate it first as a constant which is bad practice, see PHP Reference: Arrays

Categories