PHP if statement not functioning correctly - php

I am trying to run an if statment then checks if a cell in database holds a certain value then it sets a variable, if it does not contain that value then it sets a different value
I have tried the following code
case "Chemistry":
$type_tarin_text = ' Exp in ';
if($user_playerdata_tab['profile_type']='Drug Runner') {
$treining_value =$sp_value*11;
} else {
$treining_value =$sp_value*10;
}
$this->AddSubValueByUserID($player_id,'PlayerData','CHEMISTRY_EXP',$treining_value);
break;
It is currently setting the $treining_value as $sp_value*11 regardless of wether profile_type is 'Drug Runner' or not.

Please use == or strict === since you're expecting a string.
You're now assigning a variable which is likely not what you are trying to do.

As others have helpfully pointed out, the issue is here:
$user_playerdata_tab['profile_type']='Drug Runner'
The single = means assignment. What you were intending to do was to test whether the two were equal.
That means using == - or, to be more strict, use === (make that your go-to equality check in the future - you'll thank us later)
Your other assignments are fine, though I would recommend a single space both sides of your = signs for readability

Related

Odd and confusing PHP syntax

I am taking over the maintenance of an old web site and came across this confusing syntax for processing a form that I have never seen before, and I am not exactly certain what it does:
foreach (array('address','comments','country','email','mail_content','name','title') as $vuln)
{
isset($_REQUEST[$vuln]) and $_REQUEST[$vuln] = htmlentities($_REQUEST[$vuln]);
isset($_GET[$vuln]) and $_GET[$vuln] = htmlentities($_GET[$vuln]);
isset($_POST[$vuln]) and $_POST[$vuln] = htmlentities($_POST[$vuln]);
isset($$vuln) and $$vuln = htmlentities($$vuln);
}
It's the "and" that is throwing me - I read it as "if variable is set convert it to htmlentities, but why is there an "and" in there?
Finally what does the last line do?
isset($$vuln) and $$vuln = htmlentities($$vuln);
It's using the operator precedence rules of PHP in an unusual way.
If you have an and statement, PHP will stop processing it if the left side is false - there's no need to check the right hand side, because it won't make a difference to the end result. (The converse is also true for an or statement if the left hand side is true.)
So the coder that wrote this is using it as a shorthand for:
if (isset($_REQUEST[$vuln])) {
$_REQUEST[$vuln] = htmlentities($_REQUEST[$vuln]);
}
They've save a small amount of typing, at the cost of making the code slightly harder to read. It's good practice to use isset to make sure that your array values are set before you use them, which is why the check is there.
As to the last line; logically, it's doing the same as the above, but with a variable variable. The first time through, $vuln will be set to the first item in your array, which is address - the final line of code is checking to see if there's a variable called $address, and if so, set its value to htmlentities($address).
That's what the code is doing. Why it's checking REQUEST, GET, and POST is beyond me.
Hi These are the nothing but the shortend form.
isset($_REQUEST[$vuln]) and $_REQUEST[$vuln] = htmlentities($_REQUEST[$vuln]);
above line means
if(isset($_REQUEST[$vuln])){
$_REQUEST[$vuln] = htmlentities($_REQUEST[$vuln]);
}
Also the $$vuln is a reference variable its checking the same that if reference variable is set then assign it value
isset($var) and <statement goes here that uses $var>;
This basically only executes the <statement ...> if the statement preceding and (in this case isset($var)) evaluates to true. This happens because if anything is false before a and, there's no need to evaluate (or execute) the rest. This works similarly to:
if (false && condition) { ... }
The condition will never be evaluated, since no matter what its value evaluates to, the if condition will always evaluate to false.
A more readable alternative for the first example:
if (isset($var)) {
<statement goes here that uses $var>;
}
As pointed out in the comments by #chris85, see $$variable.
An example of a variable variable:
$vuln = 'abc'; /* Regular variable assignment */
$$vuln = 'def'; /* This is "equivalent" to $abc = 'def'
* because $$vuln expands to $<contents of $vuln>,
* therefore $abc is assigned with 'def'.
*/
/* $abc is now a variable with 'def' as its value */
It might be easier to comprehend as the following, for the first iteration through the array:
<?php
if(isset($_REQUEST['address'])) {
$_REQUEST['address'] = htmlentities($_REQUEST['address']);
}
if(isset($_GET['address'])) {
$_GET['address'] = htmlentities($_GET['address']);
}
if(isset($_POST['address'])) {
$_POST['address'] = htmlentities($_POST['address']);
}
if(isset($address)) {
$address = htmlentities($address);
}
It looks to me like legacy code that probably was a replacement for (or perhaps in addition to) 'magic quoting' when 'register globals' was turned on. Probably so they could do some pseudo escaping of variables before database inserts and or page echos.

php evaluation sequence of if-statements

I'm having trouble with sanitizing user input, where I don't know, if POST-Data has been sent or not. When I just do this to check:
if ($_POST["somedata"] == 2)
DoSomething();
I will get an error notice with error_reporint = E_ALL, that $_POST["somedata"] may not be defined (e.g. when the page is loaded without the form).
So I do this check now:
if (isset($_POST["somedata"]) && $_POST["somedata"] == 2)
DoSomething();
This doesn't output an error but it looks very unstable to me. I'm not sure if I just have luck with my PHP-Version or the simplicity of the statement. Is it also safe to use, when the if-statement is more complex, as long as the order of these two items are the same? Is it safe to use with all PHP-Versions?
Using isset in combination with a lazy-and (&&) is relatively correct (it prevents strictness warnings). A more advanced way would be to have automatic input checking against a schema or model.
You could have:
$schema = array(
"somedata" => "number"
);
Using the schema approach requires a little bit of architecture but it removes the instability that you might be worried about.
One thing worth mentioning is that there is a difference between validating input on a syntax level (did I get all the required inputs) and input validation on a semantic level. Let's say you have a service called GetItem and you pass id = 3 the syntax checker will check for the presence of the id property and that it is a number. Then you need to check whether 3 actually exists.
So rather than returning invalid request (bad input) you might want to return no such item.
Your approach is functionally correct, as the && is short-circuited if the first term evaluates to false. Regarding stability, as you suspected, there is a small concern, related especially to code duplication, mainly you need to always pay care that both keys match the same string (it is appropriate to say this is a matter of code duplication).
One approach to this would be to define a function that does the check and returns the contents at the desired key if exist, like for example:
function arr(array $array, $key, $defaultValue=false) {
return isset($arrray[$key]) ? $array[$key] : $defaultValue
}
You pay a small performance penalty for calling a function (you can reduce it by removing the type hinting for the $array parameter), however you have a more stable code.
Usage example in your case:
if(arr($_POST, 'somedata') === 2)) {
// do your stuff
}
We've been using this at work for some time now, going back years in code. It's fine to use since it first checks it the variable is actually there, and only then checks if it has a value.
Your code snippet is correct.
if (isset($_POST["somedata"]) && $_POST["somedata"] == 2)
DoSomething();
I would highly encourage you to use the triple equals for your quality check. Check out How do the PHP equality (== double equals) and identity (=== triple equals) comparison operators differ? for more info on equality checks.
The triple equal means it needs to be an integer and not just a string, good practice to get into doing this.

Why use an extra set of parenthesis when using PHP boolean test in an IF()?

I'm sorry the title of this question is odd. I couldn't find a good way to word it!
The idea is simple, sometimes you see PHP tests this way:
if (!a_function("something")) { }
Here you can think of it as "if not true". I sometimes see the exact same thing but with extra parenz:
if (!(a_function("something"))) { }
Why does it require the extra parenz after the bang? Don't they both essentially mean if (!true)?
For extra bonus, what are the reasons for the two styles (does this have a name?) and maybe give examples of how they would give alternate results if not used correctly.
update:
Here is an example in a PHP script I'm using, the author is testing environment variables and seems to use the styles interchangeably:
if (!(extension_loaded("iconv"))) { ... }
if (!(extension_loaded("xml"))) { ... }
if (!function_exists("json_encode")) { ... }
if (!ini_get("short_open_tag")) { ... }
I know you can't answer for the programmer here, but why would they be alternating the use of extra parenz when these small functions are right next to each other?
I happen to know that, for example, the return value of ini_get is just the number 1, and the return value of the extension_loaded functions may also just be the number 1, so it seems like there would be no difference. I'm not 100% sure there isn't some other trick to this than simple preference or order of operation.
update 2:
I understand parenz can be used for either clarity, or order of operations, but I'm not convinced it is only personal preference beyond that.
In my example above, everything depends on what is returned by the functions that are being tested.
It's my understanding that by wrapping a statement in parenz, PHP will force it into a bool. But when it's not in parenz, could there be a return value that breaks the code without using the parenz around it to force a bool?
If people say, in my example code above, that there is nothing but personal preference going on, then I'll just have to accept that, but I have my doubts.
the parenthesizes are used in case if there are more than 1 logical operator with different precedence, to indicate that "!" operator must be applied after all other operators have been processed. For example:
if(!($var1 < $var2))
First will be checked if $var1 is less than $var2, and after that will be checked if the result is false.
If use that:
if(!$var1 < $var2)
then firstly will be checked if $var1 is false and the result will be compared to $var2, that simply do not make sense.
It's not required. It's a matter of personal preference. Sometimes you like to have extra parens to be EXTRA certain of how the expression will be evaluated.
if(a or b and c)
is confusing.
if ((a or b) and c)
is much more clear.
if(a or (b and c))
is much more clear.
They both work, but some people might have different opinions on which one is more readable.
Parenthesis are not required in the given case, but they can be if, for example, you also assign a variable at the same time :
if (($myVar = myFunc()) !== false) {
// Doing something with $myVar, ONLY if $var is not false
}
While, in the following case, it will change the logic
if ($myVar = myFunc() !== false) {
// Here $myVar = true or false instead of the wanted value
}
if( !(should_return_trueA() && should_return_trueB())) {
// at least one have returned false
}
esentially is the same as:
if( !should_return_trueA() || !should_return_trueB() ) {
// at least one have returned false
}
It's, in my case, a practice to avoid mistaken/ommited exclamation marks. Useful, when building more complex conditions and looking for all-false or all-true result.

PHP Initialising strings as boolean first

I'm in the habit of initialising variables in PHP to false and then applying whatever (string, boolean, float) value to it later.
Which would you reckon is better?
$name = false;
if (condition == true) {
$name = $something_else;
}
if ($name) { …do something… }
vs.
$name ='';
if (condition == true) {
$name = $something_else;
}
if (!empty($name)) { …do something… }
Which would you reckon can possibly give better performance? Which method would you use?
At first glance - your $condition==true is pointless since $condition is well enough.
Second - if you're not sure what type will be variable, but you want to initialize it (that is - indeed - a good habit), use null - since false points to certain data type - bool data type, while it's not correct and person who reads your code may be confused.
Both values '' as false have meaning.
I would suggest using null as the default value. Since that actually does not (and should not) 'mean' anything.
This will also allow you to test is_null($var) to make sure something actually set a value to your variable.
Take a look here Basic php benchmarks.I usually use null. A must know here also.
Well what I think giving it Boolean value is better. It won't make much difference when you compare code running on a very powerful system.
but when it comes to system performance then it all depends upon the size of datatype you are using. boolean uses 1 bit of data. So, it is more convenient to use, and faster also.
Adding to other answers, better use null.
I think irrespective of your above two choices the performance of an if-statement depends on whether its condition has a predictable pattern i.e. BRANCH PREDICTION. If the condition is always true or always false,i.e. if it is predictable, the branch prediction logic in the processor will pick up the pattern. On the other hand, if the processor cant predict the condition than it may affect the performance.
when talking about your code,the optimize one i can think of is
$name = false;// i dont think u should predeclare the 'name' variable
//as it is dependent on the if condition.so if the condition fails then
//the $name will be of no use.
if (condition) {
$name = $something_else;
}
if ($name) //this condition will only be executed
// when $name is true so why predeclare $name.
{ …do something…
}

PHP if() evaluation problem needs a rewrite

I noticed this weird evaluation yesterday after searching for a few hours in my code for an error. i am passing scores into php, sometimes the score=0 which causes an issue.
send php ?blah=blah&score=0
if(!empty($_REQUEST['score']){
//do database update stuff
}else{
// show entire webpage
}
It works great unless the score=0 the if() will evaluate to false and return the entire webpage to my ajax handler and error. I have temporarily changed !empty to isset but this will cause problems in the future because isset evaluates to true even if the score key is in the url string without a value.
ex: (?blah=blah&score=&something=else)
my question is: what is the best way to recode this to work correctly now and in the future?
edit: there are a few working answers here, i appreciate everyones time. it was difficult to choose an answer
As the manual says, a variable is considered empty() if it has an empty or zero value.
So it will treat your variable wrongly as empty even though 0 is a perfectly acceptable value in your case.
If you need score to be a number, you could use isset() in combination with a is_numeric() check instead:
if((isset($_REQUEST['score']) and (is_numeric($_REQUEST['score'])){
Check out the manual page to see the kinds of values is_numeric() accepts. If score is always an integer, you can also use is_int((int)$_REQUEST['score']) but that will convert invalid input values to 0.
Additionally, as #sightofnick says, it's better to use explicit $_GET or $_POST instead of $_REQUEST.
Re your update:
In that case I would
Do check whether the variable is "0" (string "zero")
If it is "0", make it 0 (integer "zero")
If it is not 0, convert it to an integer (int)$_REQUEST["score"])
If the conversion resulted in 0, it was invalid input - exit
You have a valid integer variable.
empty() will return false if a value is zero. Use isset() or array_key_exists() instead, if you want to check if a variable in an array is set:
if (array_key_exists('score', $_REQUEST)) {...}
Try doing
if (isset($_REQUEST['score']) && ($_REQUEST['score'] !== '')) {
...
}
The isset will handle the presence/absence of the query parameter, and the strict string (!==) comparison will handle the case where the 'score' query is present but has no value. PHP treats all data coming from _GET/_POST/_REQUEST as strings, so this test is 100% reliable.
if(isset($_REQUEST['score']) && $_REQUEST['score'] != ''){
//do database update stuff
}else{
// show entire webpage
}
You may be able to solve that with
if (isset($_REQUEST['score']) && is_numeric($_REQUEST['score'])) {}
That of course if scrore can only contain numeric value

Categories