php conventions in conditions - php

I have system, that using keywords for some data
There are normal keywords and meta keywords - To:all, Tomember: and Togroup:
and I have following condition to check meta keywords:
if ((strpos($kwd, 'To:all') === 0) ||
(strpos($kwd, 'Tomember:') === 0) ||
(strpos($kwd, 'Togroup:') === 0))
{
/* ... */
}
I think this way of identifying meta keywords is incorrect.
One more incorrect way is like this:
if ((strpos($kwd, 'To:all') !== FALSE) ||
(strpos($kwd, 'Tomember:') !== FALSE) ||
(strpos($kwd, 'Togroup:') !== FALSE))
{
/* ... */
}
And in my opinion the correct way is:
if ((substr($kwd,0,6) == 'To:all') ||
(substr($kwd,0,9) == 'Tomember:') ||
(substr($kwd,0,8) == 'Togroup:'))
{
/* ... */
}
Any thoughts?

Of the solutions you propose, the second is wrong because it will return true even if the meta-keywords do not appear in the beginning of $kwd. The other two work correctly.
An even better way would be:
function str_starts_with($haystack, $needle) {
return substr($haystack, 0, strlen($needle)) == $needle;
}
if (str_starts_with($kwd, 'To:all') ||
str_starts_with($kwd, 'Tomember:') ||
str_starts_with($kwd, 'Togroup:'))
{
// ...
}

strpos($kwd, 'To:all') === 0
will check if the $kwd string begins with To:all -- it'll check if the position of To:all in $kwd is 0.
strpos($kwd, 'To:all') !== FALSE
will check if the $kwd string contains To:all -- no matter at which position.
substr($kwd,0,6) == 'To:all'
whill check if the first 6 characters of $kwd are To:all -- which is equivalent to the first solution.
If you want to test the begins with case, you'll use the first or third solution.
Personnaly, I'd go with the strpos-based : I find it easier to read/understand ; but it's mainly a matter of personnal preferences.
If you want to test the contains case, you'll need to use the second solution.

Related

Complicated `if`case, correct?

I'm trying really hard to figure out how to solve this problem. Please be gentle, i'm still learning!
There are four workplaces named: B.Avf, R.Avf, Office and Production. Products is passing theese workplaces. Now i'm building a script that can alert if the same product is passing the same workplace twice. Now, this is the hard part: If the product has passed "B.Avf" it can't pass "R.Avf" whitout an alert, same if the product has passed "R.Avf" it can't pass "B.Avf" whitout and alert. But if the product has passed for ex. "R.Avf" it´s ok to pass "Office" whitout an alert.
This is what i got so far: (It's like example number 5 =)
Maby should i create nested ifstatements instead?
This code will turn true all times!
PHP
if($_SESSION['user']['usr_workplace'] == "R.Avf" ||
$_SESSION['user']['usr_workplace'] == "B.Avf" &&
strpos($history, "R.Avf") !== FALSE ||
strpos($history, "B.Avf") !== FALSE)
Your if condition should be :
//IF this session user workplace is "B.Avf" or "R.Avf"
//AND "B.Avf" or "R.Avf" excist in history, then alert!
if(($_SESSION['user']['usr_workplace'] == "R.Avf" || $_SESSION['user']['usr_workplace'] == "B.Avf") && (strpos($history, "R.Avf") !== FALSE || strpos($history, "B.Avf") !== FALSE))
Your if statement can be made a lot simpler by removing one condition and still getting the desired result like so:
if(
($_SESSION['user']['usr_workplace'] == "R.Avf" || $_SESSION['user']['usr_workplace'] == "B.Avf")
&&
strpos($history, $_SESSION['user']['usr_workplace']) !== false
)
Notice how you don't need two strpos checks, as the first part of the if statement will only allow the second part to run if it was true.
It would be better to extract this to a method or simplify it further, but for what you've asked this will do :).
This works, it has the right braces:
if($_SESSION['user']['usr_workplace'] == "R.Avf" || ($_SESSION['user']['usr_workplace'] == "B.Avf" && (strpos($history, "R.Avf") !== FALSE || strpos($history, "B.Avf") !== FALSE)))
It checks for r.Avf first, OR and then checks all the conditions within the braces
you should break this if into 2 methods.
one should be called:
isUserSessionRBAvf($_SESSION['user']['usr_workplace'])
the other should check the strpos pos:
isHistoryAvf($history, "R.Avf")
and you would end up with just:
if(isUserSessionRBAvf(...) && isHistoryAvf(...))
this way you have a more readable code and easier to debug.
P.S. consider a different method naming
what you need to do is simply check with session value to $history so you will avoid checking two strpos() where you are doing static string checking:
here you are checking with static string:
strpos($history, "R.Avf") !== FALSE ||
strpos($history, "B.Avf") !== FALSE)
make it dynamic like this:
if($_SESSION['user']['usr_workplace'] == "R.Avf" || $_SESSION['user']['usr_workplace'] == "B.Avf" && strpos($history, $_SESSION['user']['usr_workplace']) !== FALSE )

Display HTML if two conditions are true or another two are true or third part of conditions are true

I have php if statement that should display certain HTML code if two conditions are true or another two are true or third part of conditions are true.
I have several arrays - $Options_arr, $MoreOptions_arr, $Special_arr .
To explain in the easiest possible way I want to do this:
if(!empty($Options_arr[0]) && $Options_arr[0]!="") or
(!empty($MoreOptions_arr[0]) && $MoreOptions_arr[0]!="") or
(!empty($Special_arr[0]) && $Special_arr[0]!="")
{?> some HTML here
All help will be appreciated thank you.
empty() already checks for empty string "" so it's shorter:
if(!empty($Options_arr[0]) || !empty($MoreOptions_arr[0]) || !empty($Special_arr[0])) {
//some HTML here
}
BragG, you can use elseif
Like:
if((!empty($Options_arr[0]) && $Options_arr[0]!="") ||
(!empty($MoreOptions_arr[0]) && $MoreOptions_arr[0]!="") ||
(!empty($Special_arr[0]) && $Special_arr[0]!=""))
{
// some html or any code
}
I hope that is what you were looking for..
Feel free to ask any question.
You are just missing some brackets. Also || is more frequently used than OR
if((!empty($Options_arr[0]) && $Options_arr[0]!="") || (!empty($MoreOptions_arr[0]) && $MoreOptions_arr[0]!="") || (!empty($Special_arr[0]) && $Special_arr[0]!="")){
echo '<p>hello</p>';
}
You're basically already there...
if (
(!empty($Options_arr[0]) && $Options_arr[0]!="")
|| (!empty($MoreOptions_arr[0]) && $MoreOptions_arr[0]!="")
|| (!empty($Special_arr[0]) && $Special_arr[0]!="")
){
...do something
Basically you write an if statement that resolves if any of the sub-statements are true by joining the sub-statements together with ORs

Comparing $foo is_array or $foo is false

I am trying to compare the following: if the value is not an array or the value does not equal false, return.
if (is_array($value) != true || $value != false) return;
This, and any other variation I am trying doesnt seem to work. However, when I compare these individually in their own if statements they return the correct results.
Any help would be greatly appreciated!
You originally said "if it's not an array or not false". You're thinking backwards. You want "if the value is an array or false continue, else return".
So:
// This says: "if it's not (an array or false)"
if(!(is_array($value) || $value === FALSE)) return;
Using De Morgan's laws, we can convert this to
// This says: "if it's not an array and not false"
if(!is_array($value) && $value !== FALSE) return;
I would write it like this:
if (!is_array($value) || $value !== false)
Many things in php can be == false, but only boolean false can be === false.
Check out boolean type manual page and comparison operators manual page

PHP - not operator, any other aliases?

if(!($whatever && what()) do_stuff...
Can this be replaced with something more intuitive like:
if(not($whatever && what()) do_stuff...
?
function not($OriginalCheck)
{
return !$OriginalCheck;
}
function is($OriginalCheck)
{
return !!$OriginalCheck;
}
should do exactly that :)
There are several ways to write checks:
if(!($whatever && what()) do_stuff...
if(!$whatever || !what()) do_stuff...
if(($whatever && what()) === false) do_stuff...
if((!$whatever || !what()) === true) do_stuff...
if($whatever === false || what() === false) === true) do_stuff...
all these ways are intuitive and known through out the programming world.
No it can't. See http://www.php.net/manual/en/language.operators.logical.php for the language reference about logical operators, and navigate to find other aliases.
Note however that the precedence of && and || is not the same as and and or.
One option is to make the boolean expression more explicit:
if(($whatever && what()) == false) // do_stuff...
Or alternatively, by implementing a custom not():
function not($expr) {
return $expr == false;
}
if(not($whatever && what())) // do_stuff...
Actually, I don't like the ! operator as well. Although it was understood by every developers but it took me a bit of time every time I read the code. So I prefer do not use the ! operator. But it depends on also.
For php built-in function, I created almost the helper functions for not operator.
https://github.com/vuvanly/not-operators-helpers
There is no alternative !, but it could be written less intuitive:
if ($whatever - 1) {
}
Should the question cause be that ! is too easy to overlook, but not more visible; then another alternative notation would be:
if (!!! $whatever) {
If this still looks to simple, just use:
if (~$whatever & 1) {
Binary operations always look professional ;)

Using OR in a IF

Any ideas why this isn't working?
if($page->Slug != 'water-filters' || $page->Slug != 'pet-care' || $page->Slug != 'books') {
//do something
}
I think you mean AND instead of OR because you're using not equals.
By using not equals in the way you are the statement will always be true, if $page->Slug equals 'water-filters' it doesn't equal 'pet-care' and hence the if statement as a whole returns true.
if($page->Slug != 'water-filters' && $page->Slug != 'pet-care' && $page->Slug != 'books')
{
//do something
}
I'm guessing that "do something" is always getting executed?
if($page->Slug != 'water-filters' || $page->Slug != 'pet-care' || $page->Slug != 'books')
{
//do something
}
For any value of $page->Slug, it will always be not equal to ONE of those three conditions, therefore at least one (technically, at least two) of the statements will always be true. Since you're using an 'OR' as long as one of the three statements is true, the whole thing will be true.
Therefore, this is essentially saying
if (true) {
//do something
}
$page->Slug is either 'water-filters' or 'pet-care' or 'books'
Try
== or == or ==
or
!= and != and !=
:-D
If the Slug is not "water-filters" or is not "pet-care" or is not "books"...
Well, if it's one of those, or any other value, it's by definition not the other two (or not all three). So this condition is always true.
Aside from what the others have said above, which are correct also, try this syntax for readability.
if(!in_array($page->Slug, array('water-filters', 'pet-care', 'books')) {
// Do something
}

Categories