Is there any differences between $var and ${var} - php

Are these 2 two "spellings" equivalent? Just wondering.

${var} out of context could be either correct or not. If it is used inside of the string like "foo ${var} bar" - then it is the same.
If it is used right in the code - then ${var} is incorrect, and ${'var'} should be used instead.
The valid cases for using ${...} are:
Inside the string in cases like "ab${cd}e" - when all the letters go without spaces, "${a['b']}" - when you use it with arrays
When you want to assemble the variable name dynamically: ${'a_' . $i}

Pretty much. The only difference is that you can enter code to be parsed in between the curly braces to get "variable" variable names.
Ex.
${'t'.'e'.'s'.'t'} = 'test'; // is the same as $test = 'test';
${substr('testaaa',0,4)} = 'test'; // the same
You can even do something like:
${ 'a' == 'b' ? 'Foo' : 'test' } = 'test'; //the same
It is essentially the same as:
$var_name = substr('testaaa',0,4);
$$var_name = 'test';

Related

Is htmlspecialchars() safe enough?

The user input is like this
$user_input = htmlspecialchars($_GET['$user_input']);
According to PHP.net:
'&' (ampersand) becomes '&'
'"' (double quote) becomes '"' when ENT_NOQUOTES is not set.
"'" (single quote) becomes ''' (or ') only when ENT_QUOTES is set.
'<' (less than) becomes '<'
'>' (greater than) becomes '>'
But what about $? For example the code is like this:
echo "Some cool text $user_input";
Now lets say user input is $secretCode so:$_GET['$user_input'] = "$secretCode";
Will the code then not echo the $secretCode?
Also what about this. Lets assume the code is like this:
$html = <<<EOF <head>.... EOF;
What if the input is $_GET['$user_input'] = "EOF;"; Won't this quit the string?
You're assuming a level interpretation that doesn't exist. If you write string literals like this:
$foo = 'bar';
$baz = "Hello $foo";
Then yes, $foo will be interpolated into the string. That is because it is explicitly written as a string literal in PHP source code.
On the other hand:
$foo = 'bar';
$baz = $_GET['var'];
Under no circumstances whatsoever will anything be interpolated here. Nor here:
$foo = <<<EOL
$_GET[var]
EOL;
$_GET['var'] can contain whatever it wants to, it is of no concern. PHP does not recursively evaluate all values over and over to see if there may be something that can be interpolated. There is no security issue here.
To provoke any of this recursive behaviour, you'd have to explicitly construct PHP source code as a string and then explicitly evaluate it:
$code = <<<EOL
$foo = 'bar';
echo "Hello $_GET[var]";
EOL;
// $code is now, say:
// $foo = 'bar';
// echo "Hello $foo";
eval($code);
Unless you do something like this (and please, never use eval), nothing will happen.
For embedding arbitrary text inside of HTML, htmlspecialchars is fine to escape characters which have a special meaning in HTML; yes, it's secure.
php will not parse variables inside variables itself, because the variable is not clearly written in your php code, php dont parse variables at this level. so with this in mind the following examples will fail and will output some text and $bar and not some text and test
$_GET['foo'] = '$bar';
$baz = $_GET['foo'];
$bar = 'test';
echo "some text and $baz";
// some text and $bar
Constant strings in your PHP code will be parsed like that, but strings that come from another source are not.
So in the line below, the variable $world will be expanded:
$var = "Hello $world";
In the line below, the exact value is used as it is read from (probably) a database. Even if the field 'example' world contain the text 'Hello $world', the variable $world would not be expanded.
$var = $row['example'];
This is normal PHP behaviour and is not related per se to htmlspecialchars.

Why is ${0x0} correct?

The following code is working perfectly:
${0x0} = 'test';
echo ${0x0}; // prints "test"
But I can't figure out why. 0x0 (or 0, as non-hex people call it) is a random container, it could have been any number, but php variables can't start with a number. What's so special about the { } used here, and what are their limitations ?
First of all, 0x0 is just a regular 0 in hexadecimal representation that gets cast to string '0' when used with the variable variable syntax:
var_dump(0x0===0); // prints "bool(true)"
${0x0} = 'test';
echo ${0x0}; // prints "test"
echo ${'0'}; // prints "test" as well
var_dump(get_defined_vars()); // contains ["0"] => string(4) "test"
You're correct whey you say that it isn't a valid variable name:
Variable names follow the same rules as other labels in PHP. A valid
variable name starts with a letter or underscore, followed by any
number of letters, numbers, or underscores. As a regular expression,
it would be expressed thus: '[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*'
This is the reason why $0foo = 'Test'; triggers a parse error.
Some quick testing with the variable variables syntax reveals that, in fact, PHP does not seem to really care about variable names as far as they are strings:
${'123 abc xyz '} = 'Test';
echo ${'123 abc xyz '}; // Test
echo ${'123 abc xyz '}; // PHP Notice: Undefined variable: 123 abc xyz in ...
var_dump(get_defined_vars()); // ["123 abc xyz "] => string(4) "Test"
My guess is that the aforementioned naming restriction is imposed by the source code parser rather than the language core. It needs such rules to tell variables apart when analysing PHP code. Internally, the Zend engine that powers PHP handles variables as a hash map:
PHP variables, in general, consist out of two things: The label, which
might, for instance, be an entry in a symbol table, and the actual
variable container.
So as far as it receives a valid string for the label, it's happy.
From the documentation:
Curly braces may also be used, to clearly delimit the property name. They are most useful when accessing values within a property that contains an array, when the property name is made of mulitple parts, or when the property name contains characters that are not otherwise valid (e.g. from json_decode() or SimpleXML).
To me this implies that if you use ${...}, there are no limitations regarding what characters may be used in a variable name. Whether you should however...
PHP parser provides a special syntax to create a variable name from any expression that returns string (or can be casted to string), eg.:
<?php
define('A', 'aaa');
${' _ '} = 'blah';
${'test' . A . (2 + 6)} = 'var';
echo ${' _ '}; // blah
echo ${'testaaa8'}; // var
${'123'} = 'blah';
echo ${100 + 23}; // blah
function returnVarName() {
return 'myVar';
}
$myVar = 12;
echo ${returnVarName()}; // 12
This syntax is also available for object properties:
$object->{' some property ... with strage name'};
0x0 is just a hex representation of 0 literal.
In other words everything within the curly braces in such cases is a string!
So s0x0 is indeed the hex version of 0 but here both are strings! That is why ${0x0} or ${0} work, where $0 or $0x0 won't!
On top of what #Michael Robinson said, in your example this will also be valid:
${0x0} = 'test';
$var = "0";
echo $$var; // prints "test"

Why and when should you typecast variables in PHP

Given this declaration:
(string)$my_string = 'Hello world';
*vs*
$my_string = 'Hello world';
or*
(int)$my_int = 1;
$my_int = 1;
Is there an advantage over the first way of defining a string variable in PHP?
Your "typecasting" code doesn't actually accomplish anything.
(type) $var = literal does this:
Assign literal value to $var with the literal value's native type.
"Return" (as an expression) the value of $var cast to the desired type.
The type of $var remains unchanged.
For example:
var_dump((string) $s = 1);
var_dump($s);
Output is:
string(1) "1"
int(1)
So there is no point to this syntax. Typecasting with a literal is almost certainly pointless.
However it can be useful to force a variable to be a certain type, for example: $intvar = (int) $var;
Is there an advantage over the first way
yes. second one is more concise.
What are the advantages of typecasting variables in PHP
casting it to the expected type.
you seldom need it with strings though.
and with variable definitions you don't need it at all.

Whats the difference between {$var} and $var?

I would like to know when and why should I use {$var}
echo "This is a test using {$var}";
and when (and why) should I use the simple form $var
echo "This is a test using $var";
You would use the latter when a) not accessing an object or array for the value, and b) no characters follow the variable name that could possibly be interpreted as part of it.
http://php.net/manual/en/language.variables.variable.php
In order to use variable variables with arrays, you have to resolve an
ambiguity problem. That is, if you
write $$a[1] then the parser needs to
know if you meant to use $a[1] as a
variable, or if you wanted $$a as the
variable and then the [1] index from
that variable. The syntax for
resolving this ambiguity is: ${$a[1]}
for the first case and ${$a}[1] for
the second.
The brackets allow you to remove ambiguity for the PHP parser in some special cases.
In your case, they are equivalent.
But consider this one:
$foobar = 'hello';
$foo = 'foo';
echo "${$foo . 'bar'}"; // hello
Without the brackets, you will not get the expected result:
echo "$$foo . 'bar'"; // $foo . 'bar'
For clarity purposes, I would however strongly advise against this syntax.
If you write
echo "This is a test using $vars"
You do not get content of $var in result text.
If you write
echo "This is a test using {$var}s";
Everything will be OK.
P.S. It works only with "" but not for ''.
The {} notation is also useful for embedding multi-dimensional arrays in strings.
e.g.
$array[1][2] = "square";
$text = "This $array[1][2] has two dimensions";
will be parsed as
$text = "This " . $array[1] . "[2] has two dimensions";
and you'll end up with the text
This Array[2] has two dimensions
But if you do
$text = "This {$array[1][2]} has two dimensions";
you end up with the expected
This square has two dimensions.

PHP curly string syntax question

I'm running PHP 5.3.0. I've found that the curly string syntax only works when the first character of the expression is $. Is there a way to include other types of expressions (function calls, etc)?
Trivial example:
<?php
$x = '05';
echo "{$x}"; // works as expected
echo "{intval($x)}"; // hoped for "5", got "{intval(05)}"
<?php
$x = '05';
echo "{$x}";
$a = 'intval';
echo "{$a($x)}";
?>
No. Only variables of various forms can be substituted using variable substitution.
take a look at this link LINK
Example of the code,
Similarly, you can also have an array index or an object property parsed. With array indices, the closing square bracket (]) marks the end of the index. For object properties the same rules apply as to simple variables, though with object properties there doesn't exist a trick like the one with variables.
<?php
// These examples are specific to using arrays inside of strings.
// When outside of a string, always quote your array string keys
// and do not use {braces} when outside of strings either.
// Let's show all errors
error_reporting(E_ALL);
$fruits = array('strawberry' => 'red', 'banana' => 'yellow');
// Works but note that this works differently outside string-quotes
echo "A banana is $fruits[banana].";
// Works
echo "A banana is {$fruits['banana']}.";
// Works but PHP looks for a constant named banana first
// as described below.
echo "A banana is {$fruits[banana]}.";
// Won't work, use braces. This results in a parse error.
echo "A banana is $fruits['banana'].";
// Works
echo "A banana is " . $fruits['banana'] . ".";
// Works
echo "This square is $square->width meters broad.";
// Won't work. For a solution, see the complex syntax.
echo "This square is $square->width00 centimeters broad.";
?>
there are different things you can achieve with the curly brace, but it is limited, depending on how you use it.
<?php
class Foo
{
public function __construct() {
$this->{chr(8)} = "Hello World!";
}
}
var_dump(new Foo());
Generally you don't need the braces around variables, unless you need to force PHP to treat something as a variable, where its normal parsing rules otherwise might not. The big one is multidimensional arrays. PHP's parser is non-greedy for deciding what's a variable and what isn't, so the braces are necessary to force PHP to see the rest of the array element references:
<?php
$arr = array(
'a' => array(
'b' => 'c'
),
);
print("$arr[a][b]"); // outputs: Array[b]
print("{$arr[a][b]}"); // outputs: (nothing), there's no constants 'a' or 'b' defined
print("{$arr['a']['b']}"); // ouputs: c

Categories