I'm working to integrate a plug-in into a PHP web application, and one line of the code puzzles me:
$sql = "update inventory set qtyleft='$qtyleft',price='$price',sales=sales+'$sales',qtysold=qtysold+'$qtysold' where id='$id'";
mysql_query($sql);
where $qtyleft, $price, $sales, $qtysold and $id are all variables.
I'm not very familiar with PHP, but I always thought string concatenation in PHP is done by using the . operator and it seems to me that the code above is just a long string without actually putting those variables to the SQL query. Is that the case?
In PHP, double quote (") delimited strings will evaluate variables in them.
$foo = 42;
echo "The answer for everything is $foo"; // The answer for everything is 42
This specific example is very bad because you shouldn't include variables directly in an SQL query, and shouldn't use mysql_query in new code.
See more:
Why shouldn't I use mysql_* functions in PHP?
How can I prevent SQL injection in PHP?
See Variable Parsing section of the Strings manual page.
When a string is specified in double quotes or with heredoc, variables are parsed within it.
If you use single quotes for a string, the variables will not be interpolated. If you use double quotes, they will be.
The code you mentioned will work in PHP without any issues. Please refer PHP Manual for more details.
Other issue that you might need to look forward is the function mysql_query is depreciate. Please refer here. Which gives me a feeling that the plugin you are going to is use not maintained correctly. And one more problem is, its not a good practice to pass the variable directly in the SQL query do to possible security issues
Some call it "variable interpolation". It is explained on the Variable parsing section of the manual page about strings. It helps to read the entire page and also the user comments.
The basic idea is that for strings enclosed in quotes (") and on heredoc blocks, PHP searches for variables inside the string when it needs to use it and replaces them with their values at the moment of the execution. This means the same string can render to different values in different moments of the script's execution.
This is just syntactic sugar, it doesn't change the way the code behaves and any string that contains variables inside can be rewritten using the string concatenation operator (.). Usually this syntax produces shorter source code. Sometimes the code is easier to read this way, other times it is harder because the complex expressions (array access, f.e.) need to be enclosed in curly braces ({ and }) inside the string.
Related
I regularly use the PHP HereDocs and NowDocs to add large strings of HTML, JavaScript, and CSS content to my code, but I sometimes run into situations where I want to have a PHP variable's value substituted into a HereDoc string that also contains jQuery code, which causes errors/problems when the $ prefix for jQuery conflicts with the $ prefix for the PHP variable's name. This situation only gets worse when I prefix JavaScript object variables that are assigned jQuery Objects because I indicate this by prefixing the JavaScript variable name with a $, i.e., $variable-name.
Is there a way to configure PHP to only substitute variable values when it 'sees' a variable specified as ${variable-name} instead of $variable-name? This way the PHP compiler won't produce an error when it can't find a PHP variable for the jQuery statement that follows the $ or cause problems when it substitutes my jQuery statement or JavaScript variables for a PHP variable that happens to exits?
When I use a HereDoc, I explicitly use double quotes around the opening identifier to make it clear that I'm going to specify a PHP variable in the string that will have its value substituted into the string, i.e.:
$statement = <<<"STATEMENT"...${phpVar}...STATEMENT;
I realize that the default action of a HereDoc is to allow substitutions and explicitly enclosing the identifier with double quotes just makes it easier to differentiate the HereDoc from a NowDoc statement, and that enclosing a php variable in curl-braces only makes the variable easier for me to see the PHP variable amongst the rest of the text in the string.
I use NowDocs to prevent the unwanted substitutions or to make the compilation faster.
However, I'm looking for a way to make variable substitution only happen when I explicitly use double quotes in my HereDocs and curl-braces around the PHP variable.
To get around situations where I need to use jQuery and PHP variable substitution in the same text string, I break my HTML/JavaScript/CSS into chunks and enclose them in HereDocs and NowDocs, but this makes reading my code much harder.
If it isn't possible to make ${php_variable} the only way to cause variable value substitution rather than $php_variable in HereDocs that explicitly use double quotes, then how can I submit this as an enhancement request to the PHP Development Organization?
Thanks
I've been trying to find solution somewhere for this possibly simple fix but, I haven't been able to surprisingly.
How is it possible to stop PHP from assuming a variable is a part of a string. E.g.
The line of code is $string = "slfnnwnfkw49828323$dgjkt^7ktlskegjejke";
how do you stop PHP from thinking '$dgjkt' is a variable within the string when it's really a part of the full string as characters. Thanks
Use this string like $sting = 'slfnnwnfkw49828323$dgjkt^7ktlskegjejke'
You have to use ' instead of " otherwise php tries to find any variables inside your string
Read the manual.
The most important feature of double-quoted strings is the fact that
variable names will be expanded. See string parsing for details:
When a string is specified in double quotes or with heredoc, variables are parsed within it.
There are two types of syntax: a simple one and a complex one. The
simple syntax is the most common and convenient. It provides a way to
embed a variable, an array value, or an object property in a string
with a minimum of effort.
The complex syntax can be recognised by the curly braces surrounding
the expression.
I tried to do redirect with this syntax:
header("location: readMore.php?id=$post['post_id']");
But it didn't work. It worked only after someone suggested to put curly brackets around $post['post_id']!
The correct syntax is:
header("location: readMore.php?id={$post['post_id']}");
What does the curly brackets do in this case?
Quoting the manual:
When a string is specified in double quotes or with heredoc, variables are parsed within it.
There are two types of syntax: a simple one and a complex one. The simple syntax is the most common and convenient. It provides a way to embed a variable, an array value, or an object property in a string with a minimum of effort.
The complex syntax can be recognised by the curly braces surrounding the expression.
Your first code uses simple syntax, and your second code uses a complex one.
The manual does not explicitly state this, but whitespace in simple syntax seems to be an error, rendering your first code invalid. Complex syntax appears to support the same syntax as regular PHP does as far as I can see, but again this does not seem to be actually guaranteed anywhere.
String interpolation is quite flunky in general:
$a = [['derp']];
$b = $a[0];
// Works. It prints derp
echo "$b[0]";
// Doesn't work. It throws an error
echo "$b[ 0 ]";
// Works. It prints derp
echo "{$b[ 0 ]}";
// Doesn't work. It prints Array[0]
echo "$a[0][0]";
// Works. It prints derp
echo "{$a[0][0]}";
// Doesn't work. It prints { Array[0] }
echo "{ $a[0][0] }";
You get similar issues with $object -> foo and $object->foo->bar.
To me, that is pure madness. For that reason I've come to avoid double quoted strings whenever possible (the only thing I used them for are for escape sequences like "\n"). I instead use single quotes and string concatenation, like so:
header( 'location: readMore.php?id=' . $post[ 'post_id' ] );
This lets you use actual PHP syntax for variables without the horrible death trap that is string interpolation.
I came to this question to know more about constant interpolation syntax when those PHP "<<<" things are used to create multiline strings called Heredocs (which allow variable interpolation, unlike Nowdocs).
However, it seems there is no specific syntax for them, and therefore a simple workaround is to create a closure to do so. In here it is just an anonymous function assigned to a variable that will be invoked with parameters:
$int = 'intruder'; // Variable
define('con', '"smart"'); // Constant
// For complex interpolation:
// 1. Define a closure (anonymous function)
// 2. Assign it to a variable with a short name (e.g.: _ )
// 3. Invoke the function by calling the variable with parameters enclosed in ()
$_ = function ($val){return $val;};
$doc = <<<TXT
Hi there,
One day I caught this $int nearby.
I was then told that actually other {$_(con)} $int was there before.
So who came first, the chicken or the egg?
TXT; // Heredoc
echo $doc;
Output:
Hi there,
One day I caught this intruder nearby.
I was then told that actually other "smart" intruder was there before.
So who came first, the chicken or the egg?
You can test the above online on 3v4l. This was based on this answer with a few more examples with operations inside the interpolation brackets.
When you use double or single quotes, PHP will treat whatever is in it as a string unless you tell it that it’s a variable. PHP understands anything after { followed by $ as a variable and treats it as such. Here is an example:
$Text = "XYz";
echo "name-{$Text}";
The other alternative method is to use concatenation. Here is an example:
header("location: readMore.php?id=" . $post['post_id']);
Brackets allow PHP to read what's inside as a variable. You can do that this way too:
header("location: readMore.php?id=" . $post['post_id']);
PHP's simple string interpolation doesn't recognize quoted array keys, which your example demonstrates perfectly. In fact, the correct way to write this is exactly opposite depending on which syntax used: simple vs complex.
Simple syntax - Wrong
Quoted keys cannot be parsed.
header("location: readMore.php?id=$post['post_id']");
Simple syntax - Right
The unquoted string is the associative array key.
header("location: readMore.php?id=$post[post_id]");
Complex syntax - Wrong
It will work, but only if post_id is a defined constant. If not, you'll get a PHP warning.
header("location: readMore.php?id={$post[post_id]}");
Complex syntax - Right
Written just like outside the string.
header("location: readMore.php?id={$post['post_id']}");
To quote the manual on the complex syntax:
// Works, quoted keys only work using the curly brace syntax
echo "This works: {$arr['key']}";
I'd recommend using complex (curly brace) syntax if using quoted keys. And you really should be using them, because outside the string interpolation unquoted keys are actually constants. It's too bad the simple syntax won't allow them, because it makes code reviews and updating old PHP code more difficult.
I am new to Laravel and I am having this question.
I tried out this line of code and it works fine: return redirect("/cards/{$note->id}");
But when ever I try to use the single quotes, it does not work: return redirect('/cards/{$note->id}');
How can I solve this problem ?
What you are doing first is called variable interpolation or string interpolation. You can read more about it here, on PHP docs and here, on Wiki.
It's a feature in PHP that allows you to pass a string and have variables/placeholders inside interpreted.
In your second example you are using single quotes, which does not provide this feature, so you will have to break it up and add the variable manually to the string:
return redirect('/cards/' . $note->id);
If you are interested in a more elaborate explanation and the performance behind it then you can read more on this answer here by Blizz
He concludes that:
Everyone who did the test concluded that using single quotes is marginally better performance wise. In the end single quotes result in just a concatenation while double quotes forces the interpreter to parse the complete string for variables.
However the added load in doing that is so small for the last versions of PHP that most of the time the conclusion is that it doesn't really matter.
You should use "/cards/{$note->id}" or '/cards/'.$note->id
The most important feature of double-quoted strings is the fact that variable names will be expanded.
When a string is specified in double quotes or with heredoc, variables are parsed within it.
From PHP documentation
Use it like that:
return redirect('/cards/'. $note->id);
With either single or double quotes
Is there any difference between typing:
<?php echo $_SERVER[REQUEST_URI] ?>
or
<?php echo $_SERVER['REQUEST_URI'] ?>
or
<?php echo $_SERVER["REQUEST_URI"] ?>
?
They all work... I use the first one.
Maybe one is faster than the other?
Without quotes PHP interprets the REQUEST_URI as a constant but corrects your typo error if there is no such constant and interprets it as string.
When error_reporting includes E_NOTICE, you would probably get an error such as:
Notice: Use of undefined constant REQUEST_URI - assumed 'REQUEST_URI' in <file path> on line <line number>
But if there is a constant with this name, PHP will use the constant’s value instead. (See also Array do's and don'ts)
So always use quotes when you mean a string. Otherwise it can have unwanted side effects.
And for the difference of single and double quoted strings, see the PHP manual about strings.
The first one is wrong - you're actually looking for a constant REQUEST_URI that doesn't exist. This will generate a notice-level warning.
There's no difference between the other two.
There is a difference between single and double quotes in PHP string handling. A string enclosed in double quotes will be evaluated for embedded variables and escape characters (e.g. \n); a string enclosed in single quotes won't (or not as much).
So, for example,
$hello = "world";
echo "Hello $hello!\n";
echo 'Hello $hello!\n';
echo 'Done';
will output
Hello world!Hello $hello!\nDone
In situations where you have no escape characters or embedded variables, it is slightly more efficient to use single quotes as it requires less processing of the string by the runtime. However, many people (me included) prefer to use double quotes for all strings to save confusion.
As a caveat to Gumbo's answer the third representation - double quotes - actually makes PHP look for variables inside that string. Thus that method might be a little slower (although in a string of 11 characters it'll be negligible - it's better practice not to make PHP do that however).
When PHP comes across plain strings being used as array keys it checks if there is a constant with that name and if there isn't it defaults it back to an array key. Therefore, not using quote marks causes a slight performance hit and there is a possibility that the result will not be what you expect.
$_SERVER[REQUEST_URI]
is syntatically incorrect and AFAIK will not run on a default installation of PHP5. The array index is a string so it needs to be passed on strings. I know PHP4 converted undefined constants to strings inside the square brackets but it's still not good practice.
EDIT: Well unless you define a constant called REQUEST_URI, which you haven't in your example script.
$_SERVER['REQUEST_URI']
is the standard method and what you should be using.
$_SERVER["REQUEST_URI"]
also works and while not wrong is slightly more work for the PHP interpreter so unless you need to parse it for variables should not be used. (and if you need to do so, you need to rethink that part of your program.