PHP if statement - select two different get variables? - php

Below is my example script:
<li><a <?php if ($_GET['page']=='photos' && $_GET['view']!=="projects"||!=="forsale") { echo ("href=\"#\" class=\"active\""); } else { echo ("href=\"/?page=photos\""); } ?>>Photos</a></li>
<li><a <?php if ($_GET['view']=='projects') { echo ("href=\"#\" class=\"active\""); } else { echo ("href=\"/?page=photos&view=projects\""); } ?>>Projects</a></li>
<li><a <?php if ($_GET['view']=='forsale') { echo ("href=\"#\" class=\"active\""); } else { echo ("href=\"/?page=photos&view=forsale\""); } ?>>For Sale</a></li>
I want the PHP to echo the "href="#" class="active" only when it is not on the two pages:
?page=photos&view=forsale
or
?page=photos&view=projects
I've also tried this and it doesnt work:
<li><a <?php if ($_GET['page']=='photos' && ($_GET['view']!=='projects' || $_GET['view']!=='forsale')) { echo ("href=\"#\" class=\"active\""); } else { echo ("href=\"/?page=photos\""); } ?>>Photos</a></li>

You can't do:
if ($var !== 'a' || !== 'b') ...
You have to do:
if ($var !== 'a' || $var !== 'b') ...
If you want to clean that code up I would suggest:
function active_view($content, $url, $view) {
if ($_GET['view'] == $view) {
return link($content, '#', 'active');
} else {
return link($content, $url);
}
}
function active_page_view() {
$args = func_get_args();
$content = array_shift($args);
$url = array_shift($args);
$page = array_shift($args);
if ($_GET['page'] == $page && !in_array($view, $args)) {
return link($content, '#', 'active');
} else {
return link($content, $url);
}
}
function link($content, $href, $class) {
$ret = '<a href="' . $href . '"';
if ($class) {
$ret .= ' class="' . $class . '"';
}
$ret .= '>' . $content . '</a>';
return $ret;
}
and then your code becomes:
<li><?php echo active_page_view('Photos', '/?page=photos', 'photos', 'projects', 'forsale'); ?></li>
<li><?php echo active_view('Projects', '/?page=photos&view=projects', 'projects'); ?></li>
<li><?php echo active_view('For Sale', '/?page=photos&view=forsale', 'project'); ?></li>
The above is illustrative rather than being final and complete. The point I'm trying to get across is you want to get in the habit of using some kind of templating mechanism even if you don't use a templating library (eg Smarty). You rarely want to embed complex logic into what is basically a view. If you use a library of functions (or objects) to create your markup it gives you a lot of control to escape special characters, automatically put in attributes, validate what you're putting in or whatever.
In this example, you probably want to have a data structure that represents your site navigation into which you enter what the current page is and it compares it to all the entries when dynamically constructing the navigation and automatically manipulates the links.

In addition to the problem cletus pointed out you also have an issue with the precedence of the operators. && has a higher precedence than ||. Therefore
if (
$_GET['page']=='photos'
&& $_GET['view']!=="projects"
|| $_GET['view']!=="forsale"
)
is equivalent to
if (
( $_GET['page']=='photos' && $_GET['view']!=="projects" )
|| $_GET['view']!=="forsale"
)
But you obviously want
if (
$_GET['page']=='photos'
&& ( $_GET['view']!=="projects" || $_GET['view']!=="forsale" )
)
Maybe not for two alternatives but if you have more options you might want to consider using !in_array(). e.g.
if (
'photos'=$_GET['page']
&& !in_array($_GET['view'], array("projects","forsale"))
)

<?php $view = $_GET['view'];
if($_GET['page'] == 'photos' && ($view =='projects' || $view == 'forsale'))
{
echo '<li>Photos</li>';
}
else
{
echo '<li>Photos</li>';
} ?>

if( $_GET[ 'page' ] != "photos" && $_GET[ 'view' ] != "forsale") {
...
}
else if( $_GET[ 'page' ] != "photos" && $_GET[ 'view' ] != "projects") {
...
}

Related

PHP - if statements bloated

The user gets several options which adds a different class into something that is read into PHP -
The below works, but it seems very inefficient and uses a lot of code. Is there a way I can cut this down?
<?php
if(get_sub_field('status') == "Upcoming"){
echo '<li class="upcoming">';
}
if(get_sub_field('status') == "Next"){
echo '<li class="next">';
}
if(get_sub_field('status') == "See what happened"){
echo '<li class="happened">';
}
?>
You could make a table that holds the available values for which you want. This way eliminates all of the if statements. Keep in mind thought that this is functionally equivalent to your code above.
$opt_vals = array(
"Upcoming",
"Next",
"See what happened"
);
$val_to_search = get_sub_field("status");
if(($key = array_search($val_to_search, $opt_vals)) !== FALSE) {
echo '<li class="' . strtolower($val_to_search) . '">';
}
Since array_search returns the key with the corresponding value, $key would hold the key, but as #Timur emphasized, a value at corresponding index 0, would evaluate to FALSE, 0, so in order to really check if it has the value we have to use the strict !== operator because 0 == NULL would evaluate to true.
you can do it with if...else if like this.
<?php
$status = get_sub_field('status');
if( $status == 'upcoming')
$class = 'upcoming';
else if( $status == 'Next' )
$class = 'next';
else if( $status == 'See what happened')
$class = 'happened';
?>
<li class="<?php echo $class; ?>"></li>
The only way you could change it is this:
echo '<li class="' . get_sub_field('status') . '">';
Otherwise there is no way around this! You have to use if and elseif or you make a switch statement
When you sill want to look if the value is valid you can make a array like a whitelist:
$valid = array(
"Upcoming",
"Next",
"See what happened"
);
And then you can check it like this:
if($value = array_search(get_sub_field("status"), $valid))
echo '<li class="' . strtolower($value) . '">';
else
echo '<li class="default">'; //if something fails

PHP how can I optimize this ? many if conditions strpos

I have the following code which checks if some variables contain some specific words.
I'm sure there is a way to really shorter this. I'm a total noob so I can't know for sure how I can optimise this piece of code. Any help would be great..!
<?php
if (in_array(1259, $_product->getCategoryIds()) && (strpos($fabriquant,'word') !== false)) {
echo "Doh";
} elseif (in_array(1259, $_product->getCategoryIds()) && (strpos($fabriquant,'wurd') !== false)) {
echo "Bam";
} elseif (in_array(1259, $_product->getCategoryIds()) && (strpos($fabriquant,'ward') !== false)) {
echo "Yes";
} elseif (in_array(1259, $_product->getCategoryIds()) && (strpos($fabriquant,'wierd') !== false)) {
echo "No";
}
endif;
?>
if (in_array(1259, $_product->getCategoryIds())) {
$words = array(
'word' => 'Doh',
'wurd' => 'Bam',
'ward' => 'Yes',
'wierd' => 'No',
);
foreach ($words as $word => $message) {
if (false !== strpos($fabriquant, $word)) {
echo $message;
break;
}
}
}
A first optimization could be to do nested if statements:
if (in_array(1259, $_product->getCategoryIds()) {
if(strpos($fabriquant,'wurd') !== false) {
} elseif ....
}
Then you shold test for the most likely condiction as the first check, then the second most likely condition and so on ...
Because all the if blocks have a common component, it would be good to extract it and only test it once. The other unique points can be checked individually.
if ( in_array(1259, $_product->getCategoryIds()) )
{
if ( strpos($fabriquant,'word') !== false ) {
echo "Doh";
} elseif ( strpos($fabriquant,'wurd') !== false ) {
echo "Bam";
} elseif ( strpos($fabriquant,'ward') !== false ) {
echo "Yes";
} elseif ( strpos($fabriquant,'wierd') !== false ) {
echo "No";
}
}

I can´t transform this if statement into an if/elseif one. It won´t work. What am I doing wrong?

I´m experimenting with if/elseif, and can´t understand why it won´t work this in a Drupal 6 template.
This code works:
<?php
if ((arg(0) == 'node') && (arg(1) == 'add') || (arg(1) == 'edit')){
$node = node_load(array('nid' => arg(1)));
print '<h2>' . $title . '</h2>'; }
?>
In case I´m in node/add/whatever or node/nid/edit it shows the title variable wrapped into h2´s.
Now, I want to show something slightly different in case node/add and node/edit.
So, I´ve tried this:
<?php
if ((arg(0) == 'node') && (arg(1) == 'edit')) {
$node = node_load(array('nid' => arg(1)));
print '<h3>' . $title . '</h3>';
} elseif ((arg(0) == 'node') && (arg(1) == 'add')) {
$node = node_load(array('nid' => arg(1)));
print '<h2>' . $title . '</h2>'; }
} else {
echo ""; //it shows nothing
}
?>
And it won´t work (won´t show anything).
So, I´ve tried this:
<?php
if ((arg(0) == 'node') && (arg(1) == 'add')){
$node = node_load(array('nid' => arg(1)));
print '<h2>' . $title . '</h2>'; }
?>
<?php
if ((arg(0) == 'node') && (arg(1) == 'edit')){
$node = node_load(array('nid' => arg(1)));
print '<h3>' . $title . '</h3>';
}
?>
And in this case, it works only with node/add, but completely ignores node/edit.
What am I doing wrong?
Thanks for your advice!
The path for a node edit page is node/[nid]/edit...you need to use arg(2) instead:
if ((arg(0) == 'node') && is_numeric(arg(1)) && (arg(2) == 'edit')){

Shorthand to check value in array

Is there a short way of doing this?
if ((isset($a['key']) && ($a['key'] == 'value')) {
echo 'equal';
// more code
}
else {
echo 'not equal';
// more code
}
I need to test lots of values on an array that can or cannot exist. I feel that this method is too verbose.
I could remove the isset() and mute the notices... but then I feel dirty.
Edit:
Answering Jack's question: "Could you give an example how you would test lots of values in an array?"
example:
if (isset($_GET['action']) && $_GET['action'] == 'view') {
//code
}
if (isset($_GET['filter']) && $_GET['filter'] == 'name') {
//code
}
if (isset($_GET['sort']) && $_GET['sort'] == 'up') {
//code
}
if (isset($_GET['tag']) && $_GET['tag'] == 'sometag') {
//code
}
etc...
For anyone still stumbling upon this question...
You could use PHP's coalescing operator:
if (($a['key'] ?? '') === 'value') {
echo 'equal';
// more code
}
else {
echo 'not equal';
// more code
}
See this question: using PHP's null coalescing operator on an array
I don't like to answer my own questions but I feel that the best and cleaner way to do this kind of checkings is to write a "helper funcion" like:
function iskeyval(&$a, $k, $v) {
return isset($a['key']) && ($a['key'] == 'value');
}
and then:
if (iskeyval($a, 'key', 'value')) {
...
}
else {
...
}
I have added comments to explain the code. Here is the code :
//this array maps the function with the get parameters
$functions = array (
"action" => "do_actions" ,
"filter" => "do_filters"
);
foreach ($_GET as $key=>$value) {
//check if this field is corresponding functions or not
if ( array_key_exists($key , $functions) ) {
call_user_func($functions[$key] , $key,$value);
}
}
function do_actions ($key , $value) {
//place your code here to play with this value
echo 'do_actions is called with ' . $key . 'and' . $value . "</br>";
}
function do_filters ($key , $value) {
//place your code here to play with this value
echo 'do_filters is called with ' . $key . ' and ' . $value . "</br>";
}
?>
$list = array(
0 => 'one',
1 => 'two',
2 => 'one',
3 => 'three',
4 => 'one',
);
if( #$list['xxx'] !== 'three')
echo 'Not ';
echo 'Equal';
Suppress the error reporting.

Making code more efficient and less a copy and paste

I've been working on a piece of code that that pulls the name of a guild and with it the information of boss/monsters said guild has killed in an online game. There are many many monsters in this game and every one has three difficulty settings. I have managed to get the code to do what i want however it has an enormous amount of copy and paste and ive only done about 1/5 of the total amount of enteries. I really cant think how to make this code less of a giant bloat. This is the code for just one monster for the 3 difficulty settings as you can see it's alot just for one. there are probably another 60 of these!. Can anybody help me understand better ways to do this. Thanks!
$sql = 'SELECT * FROM `phpbb_profile_fields_data`';
$result = $db->sql_query($sql);
while ($row = $db->sql_fetchrow($result))
{
/////////////////////////////////// START - 8 MAN BONETHRASHER
$normal = '';
$hard = '';
$nightmare = '';
/////// START - CHECK NORMAL
if ($row['pf_kp_em_no_bonethr'] == '1')
{
$normal = ' <img src="/styles/subsilver2/theme/images/soap/no.png" />';
}
else if ($row['pf_kp_em_no_bonethr'] == '2')
{
$normal = '';
}
else if (is_null($row['pf_kp_em_no_bonethr']))
{
echo "Boss was set as NULL This should not happen!";
}
else
{
echo "Sosia messed up go hit him in the face.";
}
/////// END - CHECK NORMAL
/////// START - CHECK HARD
if ($row['pf_kp_em_ha_bonethr'] == '1')
{
$hard = ' <img src="/styles/subsilver2/theme/images/soap/ha.png" />';
}
else if ($row['pf_kp_em_ha_bonethr'] == '2')
{
$hard = '';
}
else if (is_null($row['pf_kp_em_ha_bonethr']))
{
echo "Boss was set as NULL This should not happen!";
}
else
{
echo "Sosia messed up go hit him in the face.";
}
/////// END - CHECK HARD
/////// START - CHECK NIGHTMARE
if ($row['pf_kp_em_kn_bonethr'] == '1')
{
$nightmare =' <img src="/styles/subsilver2/theme/images/soap/kn.png" />';
}
else if ($row['pf_kp_em_kn_bonethr'] == '2')
{
$nightmare = '';
}
else if (is_null($row['pf_kp_em_kn_bonethr']))
{
echo "Boss was set as NULL This should not happen!";
}
else
{
echo "Sosia messed up go hit him in the face.";
}
/////// END - CHECK NIGHTMARE
if ($normal == '' && $hard == '' && $nightmare == '')
{
}
else
{
$template->assign_block_vars('8m_bonethrasher', array(
'VAR1' => $row['pf_guild_name'],
'VAR2' => $normal,
'VAR3' => $hard,
'VAR4' => $nightmare,
));
}
}
$db->sql_freeresult($result);
I'm still slightly fuzzy at what you are trying to do, but I'll give helping you out a shot.
You could probably get away will creating a class that does all of this.
For example:
class checks {
public function checkBosses($normalBoss, $hardBoss, $nightmareBoss) {
$difficulties = array();
$difficulties['normal'] = array('boss' => $normalBoss);
$difficulties['hard'] = array('boss' => $hardBoss);
$difficulties['nightmare'] = array('boss' => $nightmareBoss);
foreach ($this->difficulties as $difficulty -> $boss) {
$this->difficulties[$difficulty]['result'] = checkDifficulty($boss['boss'], $difficulty);
}
$normal = $this->difficulties['normal']['result'];
$hard = $this->difficulties['hard']['result'];
$nightmare = $this->difficulties['nightmare']['result'];
if ($normal == '' && $hard == '' && $nightmare == '') {
return null;
} else {
return array(
'normal' => $normal,
'hard' => $hard,
'nightmare' => $nightmare,
);
}
}
protected function checkDifficulty($boss, $difficulty) {
if ($difficulty == 'normal') {
$image = ' <img src="/styles/subsilver2/theme/images/soap/no.png" />';
} else if ($difficulty == 'hard') {
$image = ' <img src="/styles/subsilver2/theme/images/soap/ha.png" />';
} else if ($difficulty == 'nightmare') {
$image = ' <img src="/styles/subsilver2/theme/images/soap/kn.png" />';
}
if ($boss == '1') {
return $image;
} else if ($boss == '2') {
return '';
} else if (is_null($boss)) {
echo "Boss was set as NULL This should not happen!";
} else {
echo "Sosia messed up go hit him in the face.";
}
}
}
Then all you would need to do is call:
$checkResult = checks::checkBosses($row['pf_kp_em_no_bonethr'], $row['pf_kp_em_ha_bonethr'], $row['pf_kp_em_kn_bonethr']);
if ($checkResult != null) {
$template->assign_block_vars('8m_bonethrasher', array(
'VAR1' => $row['pf_guild_name'],
'VAR2' => $normal,
'VAR3' => $hard,
'VAR4' => $nightmare,
));
}
If you can retrieve an array of bosses, you can do a foreach loop on them to run that same bit of code for each boss like this:
foreach ($bosses as $boss) {
//Full code to be repeated for each boss here
}

Categories