Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is ${0x0} correct?

Tags:

php

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 ?

like image 578
Vlad Preda Avatar asked Mar 07 '13 11:03

Vlad Preda


2 Answers

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.

like image 69
Álvaro González Avatar answered Sep 22 '22 09:09

Álvaro González


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...

like image 28
Michael Robinson Avatar answered Sep 21 '22 09:09

Michael Robinson