PHP how can I optimize this ? many if conditions strpos - php

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

Related

PHP unreachable if statement in foreach

I have this code I have set up that is supposed to read from JSON and output each array. Except when I use my foreach loop, I have an unreachable if statement. It's supposed to reach it if "type" is "rawbr".
I have confirmed that this has nothing to do with foreach by placing the same message in a row.
I wish to output this:
UnknownUser3: hey hxor? [To you]
Welcome to chat!
Here is my code:
innerchat.php:
<?php
session_start();
function tf($oz){
if($oz == 0){
return false;
} else if($oz == 1){
return true;
}
}
if(isset($_GET["room"]) && file_exists("data/".$_GET["room"].".json")){
$jsonF = file_get_contents("data/".$_GET["room"].".json");
$jsonD = json_decode($jsonF, true);
echo count($jsonD["msg"]);
// echo $jsonD["msg"][1]["type"];
foreach($jsonD["msg"] as $key => $message){
if($message["visibility"] !== "all"){
if(isset($_SESSION["ts_user"]) && $_SESSION["ts_user"] == $message["visibility"] && $message["type"] != "rawbr"){
echo "<font color='".$message["color"]."'><b><u>".$message["from"].":</u></b></font> ".htmlspecialchars($message["cont"])." [To you]<br />";
} else if($message["type"] === "message" && $message["visibility"] === "all"){
echo "<font color='".$message["color"]."'><b><u>".$message["from"].":</u></b></font> ".htmlspecialchars($message["cont"])." [normal message]<br />";
} else if($message["type"] === "rawbr" && $message["visibility"] === "all"){
echo $message["cont"]."<br />";
}
}
}
}
kb6k.json (the room we're working with)
{"name":"KillerBot 6000","desc":"A room with very harsh moderation. Proceed with caution!","max":600,"color":"#e0e0e0","whispersenabled":true,"forbiddenCommands":["/milk", "/bal"],"msg":[{"cont":"hey, hxor?","time":1,"color":"black","type":"message","visibility":"HxOr1337","from":"UnknownUser1"},{"cont":"Welcome to the chat!","time":0,"type":"message","color":"black","visibility":"HxOr1337","from":"Test"}]}
I know it couldn't possibly do anything to do with the JSON itself, since the other values are nearly identical apart from "visibility"
Ok, so I figured out that I put those if statements in $message["visibility"] !== "all"
The code:
<?php
session_start();
if(isset($_GET["room"]) && file_exists("data/".$_GET["room"].".json")){
$jsonF = file_get_contents("data/".$_GET["room"].".json");
$jsonD = json_decode($jsonF, true);
// echo $jsonD["msg"][1]["type"];
foreach($jsonD["msg"] as $key => $message){
if($message["visibility"] !== "all"){
if(isset($_SESSION["ts_user"]) && $_SESSION["ts_user"] == $message["visibility"] && $message["type"] != "rawbr"){
echo "<font color='".$message["color"]."'><b><u>".$message["from"].":</u></b></font> ".htmlspecialchars($message["cont"])." [To you]<br />";
}
} else {
if($message["type"] === "message" && $message["visibility"] === "all"){
echo "<font color='".$message["color"]."'><b><u>".$message["from"].":</u></b></font> ".htmlspecialchars($message["cont"])." [normal message]<br />";
} else if($message["type"] === "rawbr" && $message["visibility"] === "all"){
echo $message["cont"]."<br />";
}
}
}
}

if condition with foreach loop for array in php

is it any way to stop this repeated data.
if ($employees_csa[0]->csa_taken == 2 && $employees_csa[1]->csa_taken == 2 && $employees_csa[2]->csa_taken == 2 && $employees_csa[3]->csa_taken == 2 && $employees_csa[4]->csa_taken == 2 && $employees_csa[5]->csa_taken == 2 && $employees_csa[6]->csa_taken == 2 && $employees_csa[7]->csa_taken == 2) {
echo "data";
}
i tried for key range(0 , 8)
like this
foreach (range(0, count($employees_csa)) as $number) {
if ($employees_csa[$number]->csa_taken == 2) {
echo "data";
}
}
i tried that way not get any succes. i any another way to write easy condition.
You can loop arrays out of the box:
$all_taken = true;
foreach ($employees_csa as $employee) {
if ($employee->csa_taken != 2) {
$all_taken = false;
break;
}
}
if ($all_taken) {
echo 'data';
}
Another approach would be array_reduce() but this doesn't abort looping when there's already an answer:
$all_taken = array_reduce($employees_csa, function ($all_taken, $employee) {
if ($employee->csa_taken != 2) {
return false;
}
return $all_taken;
}, true);
if ($all_taken) {
echo 'data';
}
Alternatively, you could do it like this using array_column to pull out all the csa_taken properties, then reducing to 1 item if they are all the same with array_unique() and then checking that the same value is the expected number 2 with reset().
$csa_taken = array_column($employees_csa, 'csa_taken');
if (reset($csa_taken) === 2 && count(array_unique($csa_taken)) === 1) {
echo 'data';
}
Reusable function version: https://3v4l.org/4kYiE
A simple for-loop could work
$condition_met=true;
for($i=0;$i<8;++$i){
if( $employees_csa[$i]->csa_taken != 2){
$condition_met=false;
break;
}
}
if($condition_met===true){
//success
}
else{
//fail
}
A simple method could be done like
foreach($employees_csa as $singleEmployee){
if($singleEmployee->csa_taken == 2){
echo "data";
}
}

OO way or functional way of string comparison conditionals in php

I am curling on a specific page that returns only html. To determine what page it returns, I simply try to stripos the result of the curl
Like so:
$result = curl_exec($ch);
if(stripos($result, 'success') !== false) {
// do something
} else {
if (stripos($result, 'foo') !== false) {
// do something
} else if (stripos($result, 'foo') !== false) {
// do something
} else if (stripos($result, 'bar') !== false) {
// do something
} else if (stripos($result, 'bazz') !== false) {
// do something
} else {
// do something
}
}
This is quite messy I think, is there an OO way or functional way to solve this kind of problem if I were looking at minimal if statements or ultimately an if-less code.
What you are searching for a ways of abstraction. In this example you are repeating yourself in case analysis and this might be the best approach if the "do something" is very different and not consistent.
$map = [ 'success' => function () { return 1; },
'foo' => function () { return 2; },
'bar' => function () { return 3; },
'bazz' => function () { return 4; } ];
foreach ( $map as $search => $value )
{
if (stripos($result, $search) !== false )
{
return call_user_func($value);
}
}
In my example these could just have been constants and we could just return them instead of applying a function. In a functional pattern this would be like the function any in Scheme SRFI-1 except it returns it's true value:
// This function uses PHP 5.6 ellipsis
function array_any(callable $callable, ...$arrays) {
if( count($arrays) == 1 ) {
$args_zipped = array_map( function ($x) { return [$x]; }, $arrays[0]);
} else {
array_unshift( $arrays, null);
$args_zipped = call_user_func_array( "array_map", $arrays);
}
foreach ( $args_zipped as $args ) {
$result = call_user_func_array($callable, $args);
if( $result !== false )
return $result;
}
return false;
}
array_any( function ($search, $value) {
if ( stripos($result, $search) !== false )
return $value;
return false;
},
array_keys($map),
array_values($map));
The function in itself uses linear update, but as you can see it works similar to array_map.
This simple function would do that work:
function checkWord ($haystack,$needle){
foreach ($needle as $word) {
if (stripos($haystack, $word) !== false) {
echo $word." was found!<br/>";
}
else{
echo $word." wasn't found<br/>";
}
}
}
checkWord("Hello what's up?",array('Hello','Huhud','up','?'));
This will output:-
Hello was found!
Huhud wasn't found
up was found!
? was found!

How to do a OR statement for stripos?

How do i add another condition to the same snippet below? I need to add a "OR" condition where $variable = $variable?
if ( stripos($userallowed, $sid) !== false ) {
echo("allowed");
} else {
echo("not allowed");
die();
}
if ( stripos($userallowed, $sid) !== false OR $variable == $variable )

PHP if statement - select two different get variables?

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") {
...
}

Categories