I am using PHP's magic __set
and __get
methods to access a private array in a class. Use of the class can include "setting" new properties as well as using existing ones. I want to make sure the property names created or requested (i.e. $myObj->FakeProperty
) are valid according to the following rules:
- Property names must begin with either a letter or underscore [A-z_]
- If it begins with an underscore, it must be followed by a letter 开发者_Go百科
- So long as the first two rules are met, the name may contain any of [A-z0-9_]
My current RegEx isn't doing the trick; with my test values, _12
always falls through the cracks.
Test Fields:
albert12
12Albert
_12
_Albert12
_12Albert
_____a_1
RegEx:
^(?=_*[A-z]+)[A-z0-9_]+$
according to docs, the following would match any valid php identifier
/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/
/^[a-z_][a-z0-9_]+$/i
For completeness' sake, you should be aware that you can create properties with just about anything in the name, although it will probably break other stuff later. Consider the following working example:
class Test { function __construct() { $this->{" `~!@#$%^&*()-_=+[]{},./?;:'\""} = "Don't try this in production code."; } } var_dump(new Test);
Maybe I am missing something, but __get and __set are only triggered when you already tried to access a syntactically valid propertyname that is unavailable via the object's public API. If you want to make sure the element you are trying to access exists in the private array, use array_key_exists
:
class Foo {
protected $data = array(
'bar' => 'baz'
);
public function __get($name)
{
if(array_key_exists($name, $this->data)) {
return $this->data[$name];
}
throw new BadMethodCallException('Invalid property');
}
}
$obj = new Foo;
$obj->123; // Syntax Error => __get won't be called
$obj->foo; // valid syntax, but not in array => BadMethodCall Exception
$obj->bar; // returns baz
精彩评论