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.
Related
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
Can someone please explain to me the following line of php?
($myobjectfunction = object::function('letsgo')) ? eval($myobjectfunction) : false;
I understand objects and their functions. Is this php saying if $myobjectfunction is defined then eval $myobjectfunction, otherwise do nothing? Because in the code I am reading, object hasn't yet been defined before this line (sometimes).
This line assigns the returned value from the function object::function('letsgo') to the variable $myobjectfunction. If the return was a "truthy" value (evaluates to boolean TRUE), the contents of that variable are then evaluated as PHP code (eval). If the initial return was FALSE, no further action is taken. The false at the end basically does nothing.
This works because PHP will return the value from an assignment, even though it isn't usually used for anything. In the case of your bit of code, however, the return from the assignment is used to determine which branch of the ternary operator to take since it is enclosed in parentheses.
$x = 3;
// returns 3 even if we don't use it...
This is an unusual idiom, because the parentheses are around the initial assignment.
($myobjectfunction = object::function('letsgo')) ? eval($myobjectfunction) : false;
//^^---------------------------------------------^^^
A more typical usage of the ternary operator would assign the output of either side of the ? to the variable on the left, based on the condition to the right of the = like:
$myobjectfunction = object::function('letsgo') ? $someothervalue : false;
It's difficult to tell exactly what's going on here. I'm assuming you have substituted actual values in order to 'simplify' the example, but the use of keywords actually clouds the matter.
The declaration of the class 'object' doesn't need to be before this statement, so long as the object class is defined at some point during the code execution.
This code is equivalent to:
$myobjectfunction = object::function('letsgo');
if( $myobjectfunction ) {
eval( $myobjectfunction );
}
else {
false;
}
In other words, assign the result of object::function( 'letsgo' ) to a variable. If that variable is "truthy" (i.e. not false, null, or 0, or another value that evaluates like false) then eval its contents; otherwise do nothing.
ya you pretty much got it, well its saying IF $myobjectfunction has successfully been returned a positive result (ie: not false, 0, or null) the eval the new variable object, but i probably wouldnt use "false" in the else bit., id probaby use null.
Now for this to do anything, "object" does need to be defined
this is a strange piece of code though, in my own honest opinion
It's hard to ask search this question and the answer would help clean up my code a bit. Basically, in PHP, if I use:
if (this = that)
what is going on? Is it checking that the variable got assigned correctly or is it checking the truth of "that" and as an aside also assigning it to "this?"
I ask because it would be easier if the answer were the former due to it taking an extra line to assign it, then run the conditional, and then use the return of it later. I know it's miniscule to be harping over one line, but over an entire script it can add up. Thanks for any help.
TO CLARIFY: I want to essentially write the equivalent of the following:
$this = something;
if ($this)
do things with $this
by writing it as
if ($this = $myFunctionCall)
do things with $this;
all assuming that $this isn't set beforehand.
It's assigning, and then it's checking the "trueness" of the value that was assigned.
its checking the "truthiness" of this iirc, the assignment occurs before evaluation
Linus,
Regardless of if it works, I'm not a fan of the assignment-within-test approach. I think it's too-easy to overlook the ASSIGNMENT, which is a potential (and easily avoidable) source of future bugs... I think this commonly used coding paradigm is "a bit sloppy".
In almost all "modern" languages you can create and assign a local variable in one step... which I find succinct, self explanatory, and emminently readable.
var stuff = getStuff();
if (stuff == null) {
Message("Sorry, no stuff found.");
return;
}
verses
var thing, widget, stuff, foo;
.... then many lines later ...
if ((stuff=getStuff())) {
// do things with stuff
} else {
// no stuff
Message("Sorry, no stuff found.");
}
As you can tell, I'm also anything but a fan of the old "structured programming" adage that there should be one exit-point per function/method/script. Instead, I believe that whenever we strike a situtation that means we can't continue here, we should leave, by the most direct route possible. This is JUST a personal preference. You can make valid arguements for any approach.
One word of advise: Whatever you do, do it CONSISTENTLY! The programmer who (a few years down the track, when you've moved on) is charged with enhancing your code will catch-on quick enough to "your style". They may not like it, but that's really not important, so long as they UNDERSTAND it. There's always a trade-off between succinctness and explicitness... there is no "correct" style... just some styles seem to WORK better than others, in the long run.
KISS it my son, and booger to brevity.
Cheers. Keith.
It will first set $this to $that, and then if $this == true, the contents of the if statement will be executed.
You would be assigning the value of that to this and checking if this then evaluates to true.
Yes, it first assigns and then checks if it's true.
Like when traversing MySQL tables:
while ($row = mysql_get_row($query)) {
...
}
When it doesn't work anymore (a false pops up), the loop breaks. It assigns and checks validity, all in one line.
I want to say that it assigns as well as check the value, purely based on this code
while($row = mysql_fetch_assoc($query))
{
// Query actions
}
Which we all know loops until there are no more results to process. mysql_fetch_assoc returns false when no results remain, but the value is still assigned, hence, it doesn't check that the value was assigned, but the value that was assigned.
An assignment operation ($foo = 'bar') is an expression in which a value is assigned to a variable. The expression as a whole returns a value. The returned value is the value that was assigned.
So, if ($foo = 'bar') is synonymous to:
$foo = 'bar';
if ('bar') ...
Some demo code
$false = false;
$true = true;
$someVar = true;
function someFunk() {
return false;
}
if ($someVar = $false) {
echo "True \n";
} else {
echo "False \n";
}
if ($someVar = $true) {
echo "True \n";
} else {
echo "False \n";
}
if ($someVar = someFunk()) {
echo "True \n";
} else {
echo "False \n";
}
This outputs
False
True
False
http://codepad.org/8JxX8MYP
if (this = that)
step 1->
this=that; //copy data from that to this
step 2->
If copy succeed then the code became like this
if (1) //true
If copy failed then the code became like this
if (0) //false
Yesterday, I posted an answer to a question that included several (unknown to me at the time) very bad code examples. Since then, I've been looking at my fundamental knowledge of PHP that allowed me to think that such code is possible. This brings me to a question that I can't seem to find an answer to:
If I want to check for whether or not a variable has anything set, is it a valid practice to not use isset() or another helper function? here's a "for instance":
if($not_set){
//do something
} else {
//do something else
}
Rather than...
if(isset($not_set)){
//do something
} else {
//do something else
}
From the name of the variable, you can see that this variable is not set. Therefore the conditional would be false and the else portion would run. Up until now I have been using this practice, but after the posts yesterday, I now have an inkling that this is wrong.
Here's why I thought that it would be an ok practice to leave out the isset() function above. From PHP manual:
The if construct is one of the most
important features of many languages,
PHP included. It allows for
conditional execution of code
fragments. PHP features an if
structure that is similar to that of
C:
if (expr) statement
As described in the section about
expressions, expression is evaluated
to its Boolean value. If expression
evaluates to TRUE, PHP will execute
statement, and if it evaluates to
FALSE - it'll ignore it. More
information about what values evaluate
to FALSE can be found in the
'Converting to boolean' section.
And from the 'Converting to boolean section':
When converting to boolean
, the following values are considered
FALSE:
...
* the special type NULL (including unset variables)
Why would the manual go out of its way to state that unset variables are included if this is a bad practice? If it's unset, it gets converted to NULL and therefore is evaluated properly by the conditional. Using isset() will find the same result, but will take extra cycles to do so.
Have I been wrong this whole time, and if so, why? (And just how bad it is, maybe?)
If the variable is not set you get a Notice. If you use isset() you don't get a notice. So from an error reporting point of view, using isset() is better :)
Example:
error_reporting(E_ALL);
if($a) {
echo 'foo';
}
gives
Notice: Undefined variable: a in /Users/kling/test on line 5
whereas
error_reporting(E_ALL);
if(isset($a)) {
echo 'foo';
}
does not output anything.
The bottom line: If code quality is important to you, use isset().
It's okay but not good practice to use if to check for a set variable. Two reasons off the top of my head:
Using isset makes the intent clear - that you're checking whether the variable is set, and not instead checking whether a condition is true.
if ($not_set) will evaluate to false when $not_set is actually set but is equal to boolean false.
You will run in to problems if your variable is set, but evaluates to FALSE, like the following:
the boolean FALSE itself
the integer 0 (zero)
the float 0.0 (zero)
the empty string, and the
string "0"
an array with zero elements
an object with zero member
variables (PHP 4 only)
the special type NULL (including
unset variables)
SimpleXML objects created from empty
tags
Taken from the PHP manual.
Basically, using isset() is showing that you are explicitly checking if a variable exists and is not NULL, while the structure of your if statement only checks if the variable is true. It is more clear and less error-prone.
It is a common practise, but is not good -- you should always use isset!
If your $not_set is set, and is a bool with the value false, your "test" will fail!
isset works as a guard preventing you from using variables that do not actually exist.
if (isset($foo)) and if ($foo) do not mean the same thing. isset just tells you if the variable actually exists and if it's okay to use it, it does not evaluate the value of the variable itself*.
Hence, you should usually use one of these two patterns:
If the variable is sure to exist and you just want to check its value:
if ($foo == 'bar')
If the variable may or may not exist, and you want to check its value:
if (isset($foo) && $foo == 'bar')
If you're just interested that a variable is set and evaluates to true, i.e. if ($foo), you can use empty:
if (isset($foo) && $foo)
// is the same as
if (!empty($foo))
* it does check for null, where null is as good as not being set at all
I've seen the following lines of code and I know what they do, but I don't know how the second line works (and hence how to apply it to another situation).
$user = User::model()->findByPk(123);
empty($user->profile) and $user->profile = new Profile();
The code tries to look up the User from the database, and if there isn't a profile, creates a new for use later on.
I have also seen code before that goes something like the following:
$variable1 = $variable2 = $variable3;
It did something a bit more complex than simple assigning three things to be the same, but I'm finding it impossible to search for this type of thing to find out any information about it, let alone find the original code that I came across. I think it originally had an 'and' in there somewhere. Does anyone know how to search for code that has more than one equals sign in it that wasn't just an if statement?
Sorry for the two questions in one (and vague at that) and the terrible title (I'll fix it up when I know what the names are, if it's anything like a tenary statement)).
Using Logical Operators to Skip Code:
As php evaluates a line with the AND operator, if the fist part is false, the second part is not evaluated since it would not change the result.
So in this case, if empty() returns true, then php evaluates the right side. If empty() returns false, no more evaluation is done and the profile is not effected.
The php manual logical operators page has some illustrations of this.
Multiple Assignment Operators: The assignment operator assigns the right expression to the variable on the left.
$variable1 = $variable2 = $variable3;
In this case $variable2 is set to the value of $variable3 then $variable1 is set to the value of $variable2. The php manual assignment operators page covers this.
empty($user->profile) and $user->profile = new Profile();
in and statement, first element is evaluated first; if it's true, then second statement is evaluated, simple assignment should always evaluate to true, I presume. if the first element was false, second element is not evaluated.
You can read more about operator precedence in php docs.
It's basically the same as
if (empty($user->profile))
$user->profile = new Profile();
Weird syntax indeed...
What you're seeing is used in many languages. Here is an article for using it in JavaScript... but it explains the concept well.
http://css.dzone.com/articles/guard-and-default-operators-ja
This is a fairly bizarre way to write this. With a PHP expression, if the first part evaluates false, the expression will stop rendering.
Like if I write:
if (x == 5 and y == 2)
that will test if x==5, then if it does, it will test if y==2. If x != 5, it will never test the y == 2. So the code above is using that fact to test whether $user->profile is empty. Then if it is, it runs the next part of the expression, which is the assignment of $user->profile = new Profile(); Basically the same as:
if (empty($user->profile))
$user->profile = new Profile();
or
empty($user->profile) ? $user->profile = new Profile();
As far as your second question, the operator = is just an assignment, so it means that the value of $variable1 will be set to the value of $variable2, which will be set to the value of $variable3.
PHP does some very nice things with expressions, which are really helpful to learn. Check out this link for more info:
http://us.php.net/manual/en/language.expressions.php
$variable1 = $variable2 = $variable3;
Assignment (via the equal sign) in PHP has right to left precedence. Every expression in PHP has a return value. So the return value of the expression $variable3 is assigned to $variable2. Then the reurn value of the expression $variable2 = $variable3 is assigned to $variable1.