Home » Php » What are the valid characters in PHP variable, method, class, etc names?

What are the valid characters in PHP variable, method, class, etc names?

Posted by: admin April 23, 2020 Leave a comment

Questions:

What are the valid characters you can use in PHP names for variables, constants, functions, methods, classes, …?

The manual has some mentions of the regular expression [a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*. When does this restriction apply and when does it not?

How to&Answers:

The [a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]* regex only applies when the name is used directly in some special syntactical element. Some examples:

$varName           // <-- varName needs to satisfy the regex
$foo->propertyName // <-- propertyName needs to satisfy the regex
class ClassName {} // <-- ClassName needs to satisfy the regex
                   //     and can't be a reserved keyword

Note that this regex is applied byte-per-byte, without consideration for encoding. That’s why it also allows many weird Unicode names.

But the regex restricts only these “direct” uses of names. Through various dynamic features PHP provides it’s possible to use virtually arbitrary names.

In general you should make no assumptions about which characters names in PHP can contain. To the most parts they are just arbitrary strings. Doing things like “validating if something is a valid class name” is just meaningless in PHP.

In the following I will provide examples of how you can create weird names for the different categories.

Variables

Variable names can be arbitrary strings:

${''} = 'foo';
echo ${''};      // foo
${"
${''} = 'foo'; echo ${''}; // foo ${"\0"} = 'bar'; echo ${"\0"}; // bar 
"} = 'bar'; echo ${"
${''} = 'foo'; echo ${''}; // foo ${"\0"} = 'bar'; echo ${"\0"}; // bar 
"}; // bar

Constants

Global constants can also be arbitrary strings:

define('', 'foo');
echo constant('');   // foo
define("
define('', 'foo'); echo constant(''); // foo define("\0", 'bar'); echo constant("\0"); // bar 
", 'bar'); echo constant("
define('', 'foo'); echo constant(''); // foo define("\0", 'bar'); echo constant("\0"); // bar 
"); // bar

There is no way to dynamically define class constants that I’m aware of, so those can not be arbitrary. Only way to create weird class constants seems to be via extension code.

Properties

Properties can not be the empty string and can not start with a NUL byte, but apart from this they are arbitrary:

$obj = new stdClass;
$obj->{''} = 'foo';   // Fatal error: Cannot access empty property
$obj->{"
$obj = new stdClass; $obj->{''} = 'foo'; // Fatal error: Cannot access empty property $obj->{"\0"} = 'foo'; // Fatal error: Cannot access property started with '\0' $obj->{'*'} = 'foo'; echo $obj->{'*'}; // foo 
"} = 'foo'; // Fatal error: Cannot access property started with '
$obj = new stdClass; $obj->{''} = 'foo'; // Fatal error: Cannot access empty property $obj->{"\0"} = 'foo'; // Fatal error: Cannot access property started with '\0' $obj->{'*'} = 'foo'; echo $obj->{'*'}; // foo 
' $obj->{'*'} = 'foo'; echo $obj->{'*'}; // foo

Methods

Method names are arbitrary and can be handled by __call magic:

class Test {
    public function __call($method, $args) {
        echo "Called method \"$method\"";
    }
}

$obj = new Test;
$obj->{''}();    // Called method ""
$obj->{"
class Test { public function __call($method, $args) { echo "Called method \"$method\""; } } $obj = new Test; $obj->{''}(); // Called method "" $obj->{"\0"}(); // Called method "\0" 
"}(); // Called method "
class Test { public function __call($method, $args) { echo "Called method \"$method\""; } } $obj = new Test; $obj->{''}(); // Called method "" $obj->{"\0"}(); // Called method "\0" 
"

Classes

Arbitrary class names can be created using class_alias with the exception of the empty string:

class Test {}

class_alias('Test', '');
$className = '';
$obj = new $className; // Fatal error: Class '' not found

class_alias('Test', "
class Test {} class_alias('Test', ''); $className = ''; $obj = new $className; // Fatal error: Class '' not found class_alias('Test', "\0"); $className = "\0"; $obj = new $className; // Works! 
"); $className = "
class Test {} class_alias('Test', ''); $className = ''; $obj = new $className; // Fatal error: Class '' not found class_alias('Test', "\0"); $className = "\0"; $obj = new $className; // Works! 
"; $obj = new $className; // Works!

Functions

I’m not aware of a way to create arbitrary function names from userland, but there are still some occasions where internal code produces “weird” names:

var_dump(create_function('',''));
// string(9) "
var_dump(create_function('','')); // string(9) "\0lambda_1" 
lambda_1"

Answer:

NikiC has all of them except functions. With variable functions you can have whatever name you want, though the syntax sucks.

${'=^^='}=function(){
   echo "Hello Kitty!";
};

${'=^^='}(); //outputs "Hello Kitty!"