Is this a proper way to say: if something is the case, do nothing?
if ( ($hostNameInfo == $hostNameInput) && ($hostAddressInfo == $hostAddressInput) )
{
return;
}
Update:
I'm not inside a function. :(
So the return is just nonsense.
Here is more code:
//if the input fields are equal to database values, no need to update and waste resources,hence, do nothing:
if ( ($hostNameInfo == $hostNameInput) && ($hostAddressInfo == $hostAddressInput) )
{
//do nothing
}
//If, however, (they are NOT equal and) input fields are not empty:
elseif (!empty($hostNameInput) && (!empty($hostAddressInput)))
{
//do something.
}
Thanks in advance,
MEM
For do nothing you simply can type:
function relax() {
;
}
if (($hostNameInfo == $hostNameInput) && ($hostAddressInfo == $hostAddressInput)) {
relax();
}
Maybe you should do the opposite, do something if your condition is not verified
if($hostNameInfo != $hostNameInput || $hostAddressInfo != $hostAddressInput) {
// do something
}
I assume you're inside a function in which case it does what you expect, although multiple return statements within a function can lead to confusion and a lack of readability. (Apparently I was wrong.)
Instead, I prefer to let all conditional blocks (my description for the code between in the if's {...} block) contain the relevant code, i.e., write the conditional check in such a way that the total condition evaluates to true when additional processing (sub-flow) is needed:
if ($hostNameInfo != $hostNameInput || $hostAddressInfo != $hostAddressInput) {
// do stuff, else skip
}
Furthermore, you can extract the conditional statement in order to improve both readability and simplicity of control flow:
$hostInfoEqualsInput = ($hostNameInfo == $hostNameInput && $hostAddressInfo == $hostAddressInput);
if (!$hostInfoEqualsInput) {
...
}
UPDATE (based on updated question). Consider this instead:
$fieldsAreFilled = (!empty($hostNameInput) && !empty($hostAddressInput));
$hostInfoEqualsInput = ($hostNameInfo == $hostNameInput && $hostAddressInfo == $hostAddressInput);
if ($fieldsAreFilled && !$hostInfoEqualsInput) {
...
}
ERGO
Minimize branch rate and avoid empty blocks by writing conditions you want to be met, not all the exceptions you want to ignore (subjective).
You're talking about best practices here..
One of best practice things is that routine shall have single exit point, though it is widely discussed and is up to developer/style.
UPDATE:
New answer, since the question was changed:
Don't see any reason to add additional checks if the code should run only under some circustances. To make the code more readable, you should stuck to whatever you accept as easy-maintainable, like this (or something similar):
// Do something only if required
if (($hostNameInfo != $hostNameInput) || ($hostAddressInfo != $hostAddressInput)) &&
!empty($hostNameInput) && !empty($hostAddressInput))
{
echo 'place some code here';
}
A native do_nothing() function would be very nice and readable sometimes.
To avoid stressing alerts from syntax checkers & linters, that go crazy when you have an empty if block, I use:
echo(null);
The other possibility is to throw a new exception, which you can later catch in your application.
UPDATE: not inside the function this is probably a bad idea.
Related
I have a long if condition as follows. There are two conditions that both have to not be met, for the statement to evaluate. I did have it as a one liner with a lot of && and ! but it became unreadable. I have tried splitting it into an if elsif else, which is more readable but doesn't read well, as the first if elsif blocks have no code in them.
What would be the best practice to tidy this code block?
if ($instructionObject->instruction=='nesting_grammar' && $instructionObject->match=='>'){ //if instruction is a '>' child indicator
//don't change the child depth
}else if ($instructionObject->instruction=='selector' && is_object($this->instructions[$key+1]) && $this->instructions[$key+1]->instruction == 'nesting_grammar' && $this->instructions[$key+1]->match == '>'){ //if instruction is a selector followed by a '>'
//don't change the child depth
}else{
$insertOffset += $childDepth;
unset($childDepth);
}
You can use "extract method" refactoring. Replace your conditions to new methods.
if ($this->isInstructionNestingGrammar($instructionObject)){
//don't change the child depth
}else if ($this->isIntructionSelect($instructionObject)){
//don't change the child depth
}else{
$insertOffset += $childDepth;
unset($childDepth);
}
In new methods put every compare to separate line.
P.S. Don't be afraid of long name of methods.
Just negate the conditions and skip the if and else if parts as the two initial conditions don't do anything...
if (
!($instructionObject->instruction=='nesting_grammar' &&
$instructionObject->match=='>')
|| !($instructionObject->instruction=='selector'
&& is_object($this->instructions[$key+1])
&& $this->instructions[$key+1]->instruction == 'nesting_grammar'
&& $this->instructions[$key+1]->match == '>')
) {
$insertOffset += $childDepth;
unset($childDepth);
}
Not directly answering your question, but what about something like:
if (my_check($instructionObject) || $instructionObject->instruction=='selector' && my_check($this->instructions[$key+1])) {
} else {
$insertOffset += $childDepth;
unset($childDepth);
}
function my_check($obj) {
return is_object($obj) && $obj->instruction == 'nesting_grammar' && $obj->match == '>';
}
-- you are basically doing the same thing twice, time to think about a function for that.
Personally if i'm going to span the check across multiple lines i lay it out similar to how i'd lay out a JavaScript object;
if (
great big long check line goes in here &&
another really long ugly check line goes in here too
) {
// Do this code
}
else if (
check 3 &&
check 4
) {
//Do this code
}
Pull out sub-expressions into variables. Pseudo-example:
flibjit = FlibjitManager.FlibjitInstance(this);
isFrob =
(flibjit.Froblocity >= FlibjitManager.FrobThreshold) &&
(flibjit.Type == FlibjitTypes.Frobby);
if (isFrob) {
// ...
This question already has answers here:
Closed 11 years ago.
Possible Duplicates:
php multiple if conditions
What is better ? Multiple if statements, or one if with multiple conditions
So I was working on a segment of code in which I ended up using two different styles of if statements. That got me wondering - which one is more efficient in PHP? Are there times when one might be better than the other, despite general differences (if present)? Is there a certain level of complexity where the benefits become clear (if close) or close (if originally clear)? Also, are there other benefits of one method over the other, other than aesthetic or subjective differences?
if ($value == 'someval') {
if($otherval == 'someval') {
// do stuff
} else if ($otherval == 'otherval') {
// do same stuff
}
}
vs
if (($value == 'someval') && ($otherval == 'someval' || $thirdval == 'someval') {
// do stuff
}
Note - I don't care what works for C# or Java or whatever other language, unless someone can show that they handle the construct exactly the same.
So long as you're executing the same code in each block (as you've indicated by your comments) then they'll both do the trick (and no, there's really not much of a performance difference).
However, typically it's not the case that you'd execute the same code both ways, so logically the first block is actually different from the second in that case. Here's an example:
if($value == 'someval') {
if($otherval == 'someval') {
doSomething();
}
else if ($otherval == 'otherval') {
doSomethingElse();
}
}
versus:
if(($value == 'someval') && ($otherval == 'someval' || $otherval == 'otherval')) {
//we now still need to evaluate $otherval in order to determine which func to execute...
//this adds bloat...
if($otherval == 'someval') {
doSomething();
}
else if ($otherval == 'otherval') {
doSomethingElse();
}
}
So as you can see in the case above the second block is actually less efficient than the first.
There is no real difference, you should use whichever is more readable.
Nested or not nested if-blocks?
dispatch_address_postcode
isn't mandatory and it will still run even if it's blank:
if (!is_null($_POST['personal_info_first_name']) &&
!is_null($_POST['personal_info_surname']) &&
!is_null($_POST['personal_info_email']) &&
!is_null($_POST['personal_info_telephone']) &&
!is_null($_POST['dispatch_address_country']) &&
!is_null($_POST['dispatch_address_first_name']) &&
!is_null($_POST['dispatch_address_surname']) &&
!is_null($_POST['dispatch_address_address']) &&
!is_null($_POST['dispatch_address_town']) &&
!is_null($_POST['dispatch_address_postcode']) &&
!is_null($_POST['dispatch_address_county']) &&
( ($_POST['payment_method'] == "Pay by credit card.") ||
(
($_POST['payment_method'] == "Pay by new credit card.") &&
!is_null($_POST['card_number']) &&
!is_null($_POST['expiration_date']) &&
!is_null($_POST['security_code'])
)
)
)
What gives?
"dispatch_address_postcode isn't mandatory and it will still run even if it's blankā¦"
Just look at that sentence again. If the field is not mandatory, it is perfectly okay if the code runs if the field is blank. If a field isn't mandatory, don't test it as mandatory.
The real problem is though, is_null only tests if the variable is null. POSTed values will never be null, if they're empty they will be '' (an empty string). All your !is_null tests will always be true, and you will get a warning if the variable isn't set (something you don't want to happen). The more appropriate test would be !empty.
Even more appropriate tests would include a test if the value appears to be valid (does email look like an email address, does telephone have at least x digits in it?). You should also loop through the fields to make your code more readable, endless nested and chained if conditions are no joy to look at.
$mandatoryFields = array('foo' => 'email', 'bar' => 'telephone');
foreach ($mandatoryFields as $field => $rule) {
if (empty($_POST[$field]) || !validateByRule($_POST[$field], $rule)) {
raiseHell();
}
}
It looks like you're trying to make sure all post variables are submitted. Would you like help with that?
Using !empty() may not be the answer to your specific question, but it would definitely help with what it looks like you're trying to do.
empty() returns TRUE if the $_POST key isn't set, if its an empty array, or even if its an empty string, so using !empty() is a good way to make sure that the user has filled in the information.
Try writing your own is_valid function and use that rather than is_null.
For example (and this is by no means comprehensive):
function is_valid(&$array, $key, $required=false) {
if(!array_key_exists($array))
return false;
$value = trim($array[$key]);
if(empty($value) && $required)
return false;
return true;
}
Use like so:
if(is_valid($_POST, 'personal_info_first_name', true) && ...)
!is_null($_POST['personal_info_first_name']) && !isset($_POST['personal_info_first_name'])
use array_key_exists('card_number', $_POST) && !empty($_POST['card_number'])
Edit: Please consider this before a downvote. I'm leaving this here to serve as a "what not to do". I would delete it because it's bad, but then nobody would learn from my mistakes.
DO NOT DO THIS - read the comments for great info on why this is bad
My answer is going to be wildly different, but I am a wildly different guy...
I JUST found that this will work. Instead of all that isset and things, just assign the variables programmatically! I think I have some refactoring to do... y'know on all my code...
if (!is_array($_POST)){exit "$_POST isn't an array";}
foreach ($_POST as $param => $value){
${$param} = secure($value);
}
//now you have a set of variables that are named exactly as the posted param
//for example, $_POST['personal_info_first_name'] == $personal_info_first_name
if ($payment_method == "Pay by credit card."){
//do stuff that you were gonna do anyways
} else if ($payment_method == "Pay by new credit card.") {
if ($card_number && $expiration_date && $security_code){
//do stuff that you were gonna do anyways
} else {
exit("info missing for credit card transaction");
}
} else {
exit("unknown payment method")
}
function secure($input){
//sanitize user input
}
If you use this code, then it doesn't matter what is null and what isn't within the foreach because anything that's null just won't be made. Then you can use nicer looking code (and probably faster code) to check for anything that is required.
I have a basic PHP question, take the code below for example, let's say I need to use this 10 times on a page, is there a better way to do it?
I realize I could wrap it in a function and just keep calling that function but is there a better way then to keep on checking if the item is set and equals a a certain value. After finding this out the first time is there some other way of remembering the result from the first time instead of doing it 10 different times?
Hope that makes sense.
<?PHP
if (isset($_SESSION['auto_id']) && $_SESSION['auto_id'] == "1") {
//do something
}
// do other code here that breaks these up
if (isset($_SESSION['auto_id']) && $_SESSION['auto_id'] == "1") {
//do something else
}
// do other code here that breaks these up
if (isset($_SESSION['auto_id']) && $_SESSION['auto_id'] == "1") {
//do something else
}
// do other code here that breaks these up
if (isset($_SESSION['auto_id']) && $_SESSION['auto_id'] == "1") {
//do something else
}
...ect
?>
In this case, yes you have to, although you could do it once and assign the result to a variable.
how about...
<?PHP
$myCheck = (isset($_SESSION['auto_id']) && $_SESSION['auto_id'] == "1") ;
if($myCheck) {
//do something
}
// do other code here that breaks these up
if($myCheck) {
//do something else
}
// do other code here that breaks these up
if($myCheck) {
//do something else
}
// do other code here that breaks these up
if($myCheck) {
//do something else
}
etc.
?>
Syntax may be off - it's a long time since I've done any PHP work...
Sure. Just save the value of the boolean expression in another variable.
<?php
$auto_id_is_one = ($_SESSION['auto_id']) && $_SESSION['auto_id'] == "1");
// ...
if ($auto_id_is_one) {
// do something
}
// ...
if ($auto_id_is_one) {
// do something else
}
// ...
?>
You probably want to give it a more meaningful name than $auto_id_is_one, though.
Maybe a better approach is to use isset once at the top of the function, and set the variable to a default value there. Then you can simply use the value through the rest of the function.
In your example, you could set it to "0", though I realize that may not be the real code...
It depends what the "do something" block of code is, and whether or not the auto_id index of $_SESSION is changed in the other code. You can be certain that, in the body of the first if, the variable exists and is 1. Once that if concludes, you can no longer be certain - you'll have to check again later unless all the rest of the code is executed in a context that only exists if the first test succeeds (i.e. there's an else clause that terminates the script), and you are sure you don't change the value (and no external code you call changes it).
A better way to check the sanity might be to ensure most of the environment is as you expect it just once, then just check specific values at various places. However, if you're constantly rechecking this, it might indicate a design flaw, where similar logic (i.e. that dependent on auto_id = 1) is not well isolated and grouped.
In the example you provided, PHP will just issue an E_NOTICE that the index is not found in the $_SESSION super global (It will not throw the notice if you turned off strict mode). The best practice would be to go and set the value to a default so that you know for sure that the variable is set.
ex
<?php
$myVar = isset($_SESSION['auto_id']) ? $_SESSION['auto_id'] : FALSE;
if (false !== $myVar)
{
//do something
}
//do something not realated to myVar being set
if (false !== $myVar)
{
//do somethign else
}
?>
<?PHP
if (isset($_SESSION['auto_id']) && $_SESSION['auto_id'] == "1") {
$sessionOK = TRUE;
}
if ($sessionOK) {
//do this
}
if ($sessionOK) {
//do that
}
Below is a snippet of PHP that I need to get working, I need to make sure that 3 items are not set already and not === ''
I have the part to make it check if not set but when I try to see if the values are empty as well (I might not even be thinking clearly right now, I might not need to do all this) But I need to make sure that redirect, login_name, and password are all not already set to a value, if they are set to a value I need to make sure that the value is not empty.
Can someone help, when I add in check to see if values are empty, I get errors with my syntax, also not sure if I should have 5-6 checks like this in 1 if/else block like that, please help
I need to check the following:
- $_GET['redirect'] is not set
- $_REQUEST['login_name'] is not set
- $_REQUEST['login_name'] is not != to ''
- $_REQUEST['password'] is not set
- $_REQUEST['password'] is not != to ''
if (!isset($_GET['redirect']) && (!isset($_REQUEST['login_name'])) && (!isset($_REQUEST['password']))){
//do stuff
}
UPDATE
Sorry It is not very clear, I was a bit confused about this. Based on Hobodaves answer, I was able to modify it and get it working how I need it. Below is the code how I need it, it works great like this... So if that can be improved then that is the functionality that I need, I just tested this.
if (!isset($_GET['redirect'])
&& empty($_GET['redirect'])
&& isset($_REQUEST['login_name'])
&& !empty($_REQUEST['login_name'])
&& isset($_REQUEST['password'])
&& !empty($_REQUEST['password'])
) {
echo 'load user';
}
if this was loaded then it will run the login process
login.php?login_name=test&password=testing
If this is loaded then it will NOT run the login process
login.php?login_name=test&password=
if (!isset($_GET['redirect'])
&& !isset($_REQUEST['login_name'])
&& empty($_REQUEST['login_name'])
&& !isset($_REQUEST['password'])
&& empty($_REQUEST['password'])
) {
// do stuff
}
This is exactly what you describe, (not != empty === empty). I think you should edit your question though to explain what you're triyng to do, so we can suggest better alternatives.
Edit:
Your updated question can be simplified as:
if (empty($_GET['redirect'])
&& !empty($_REQUEST['login_name'])
&& !empty($_REQUEST['password'])
} {
// load user
}
A more maintainable solution would be storing each key in an array, and then foreach over it and check if isset or empty. You're not very DRY with your current solution.
The implementation would look someting like:
<?php
$keys = array('login_name', 'password');
foreach($keys as $key)
{
if(!isset($_REQUEST[$key]) || empty($_REQUEST['key'])
// Show error message, kill script etc.
}
// Dot stuff
?>
If a global variable is not set, that is the same as being empty. Thus:
!is_set(($_REQUEST['username'])) is the same as empty($_REQUEST['username'])
So based on your update, you can simplify to:
if (empty($_GET['redirect'])
&& !empty($_REQUEST['login_name'])
&& !empty($_REQUEST['password'])
) {
echo 'load user';
}
please read!
Sorry, the previous answer I gave will not give you what you want. Here is why:
If you use !_REQUEST['password'], it will return true if the password is empty or if it is not set. However if you use if($_REQUEST['password']) it will pass the conditional anytime that global variable is set, even if it is empty.
Therefore I recommend:
$no_redirect = (!$_GET['redirect']);
$login_name = (!$_REQUEST['login_name']) ? false : true;
$password = (!$_REQUEST['login_name']) ? false : true;
if($no_redirect && $login_name && $password) {
echo 'load user';
}
Sorry for the previously bad info.
You could create an array
$array = array(
$_GET['redirect'],
$_GET['redirect'],
$_REQUEST['login_name'],
$_REQUEST['login_name'],
$_REQUEST['password'],
$_REQUEST['password']
);
foreach($array as $stuf)
{
if(!empty($stuff) && $tuff !=0)
//do something
}