[英]How can I access an existing private property out of the class in Overloading(using __get() magic method or some other way) in PHP?
Consider below working code : 考虑以下工作代码:
<?php
class PropertyTest {
/** Location for overloaded data. */
private $data = array();
/** Overloading not used on declared properties. */
public $declared = 1;
/** Overloading only used on this when accessed outside the class. */
private $hidden = 2;
public function __set($name, $value) {
echo "Setting '$name' to '$value'\n";
$this->data[$name] = $value;
}
public function __get($name) {
echo "Getting '$name'\n";
if (array_key_exists($name, $this->data)) {
return $this->data[$name];
}
$trace = debug_backtrace();
var_dump($trace); die;
trigger_error(
'Undefined property via __get(): ' . $name .
' in ' . $trace[0]['file'] .
' on line ' . $trace[0]['line'],
E_USER_NOTICE);
return null;
}
/** As of PHP 5.1.0 */
public function __isset($name) {
echo "Is '$name' set?\n";
return isset($this->data[$name]);
}
/** As of PHP 5.1.0 */
public function __unset($name) {
echo "Unsetting '$name'\n";
unset($this->data[$name]);
}
/** Not a magic method, just here for example. */
public function getHidden() {
return $this->hidden;
}
}
echo "<pre>\n";
$obj = new PropertyTest;
$obj->a = 1;
echo $obj->a . "\n\n";
var_dump(isset($obj->a));
unset($obj->a);
var_dump(isset($obj->a));
echo "\n";
echo $obj->declared . "\n\n";
echo "Let's experiment with the private property named 'hidden':\n";
echo "Privates are visible inside the class, so __get() not used...\n";
echo $obj->getHidden() . "\n";
echo "Privates not visible outside of class, so __get() is used...\n";
echo $obj->hidden . "\n";
?>
Output : 输出:
Setting 'a' to '1'
Getting 'a'
1
Is 'a' set?
bool(true)
Unsetting 'a'
Is 'a' set?
bool(false)
1
Let's experiment with the private property named 'hidden':
Privates are visible inside the class, so __get() not used...
2
Privates not visible outside of class, so __get() is used...
Getting 'hidden'
Notice: Undefined property via __get(): hidden in <file> on line 70 in <file> on line 29
I understood everything in the code. 我了解代码中的所有内容。 I only have a concern in accessing the private property
$hidden
outside the class using magic method __get()(or some other way but in overloading). 我只关心使用魔术方法__get()(或其他方法,但有重载)访问类外部的私有属性
$hidden
。 I mean by usage of Overloading only. 我的意思是仅使用重载 。
But currently I'm not able to achieve that. 但目前我无法实现这一目标。 Getting User Notice for the same.
获取用户通知同样。
I don't understand your problem 我不明白你的问题
<?php
class TestClass{
private $private = 'true';
public function __get($key){
if( isset($this->{$key}) ){
return $this->{$key};
}
throw new Exception('Undefined object property '.__CLASS__.'::'.$key);
}
}
echo (new TestClass())->private;
Outputs 输出
true
There is no reason you can't do that from the class where $private
is defined in. That said it's probably a poor design choice. 没有理由在定义
$private
的类中不能这样做。那可能是一个糟糕的设计选择。
Now if you are trying to do this ( Access private parent property from a child ) 现在,如果您尝试执行此操作(从孩子访问私有父属性)
<?php
class TestClass{
private $private = 'true';
}
class ChildClass extends TestClass{
public function __get($key){
if( isset($this->{$key}) ){
return $this->{$key};
}
throw new Exception('Undefined object property '.__CLASS__.'::'.$key);
}
}
echo (new ChildClass())->private;
Outputs ( our exception ) 输出(我们的例外)
<b>Fatal error</b>: Uncaught Exception: Undefined object property ChildClass::private in
Indeed, and if you want to get real Crazy you can do this: 确实,如果您想变得真正的疯狂 ,可以这样做:
<?php
class TestClass{
private $private = 'true'; //not visible to child
//called -via- child class
public function parentEcho(){
echo "\nParent: {$this->private}\n";
return $this; //return this for chaining
}
}
class ChildClass extends TestClass{
private $private = 'false'; //this is not parent::$private
public function childEcho(){
echo "\nChild: {$this->private}\n";
return $this;
}
}
(new ChildClass())->childEcho()->parentEcho();
Outputs 输出
Child: false
Parent: true
This illustrates the scope of a private
property Is only within this
class. 这说明了
private
属性的范围仅在this
之内。 Even children know nothing about it. 甚至孩子对此一无所知。 However with a method in parent that accesses is directly ( not overwritten in child ) it can still be reached by inheritance.
但是,使用父级中直接访问的方法(不会在子级中覆盖),继承仍然可以访问它。 Because, the child inherits the method and the method is defined within the class ( parent ) which can access it.
因为,子级继承了该方法,并且该方法是在可以访问它的类(父级)中定义的。
But if you truly want your mind blown (Reflection) : 但是,如果您确实希望自己的想法被打击(反思) :
<?php
class TestClass{
private $private = 'true';
public function parentEcho(){
echo "\nParent: {$this->private}\n";
return $this;
}
}
$Obj = new TestClass();
$Obj->parentEcho();
echo "\n";
$ReflectionObj = new ReflectionObject($Obj);
$ReflectionProperty = $ReflectionObj->getProperty('private');
$ReflectionProperty->setAccessible(true);
echo $ReflectionProperty->getValue($Obj)."\n";
$ReflectionProperty->setValue($Obj, 'false' );
echo $ReflectionProperty->getValue($Obj)."\n";
$Obj->parentEcho();
Outputs 输出
Parent: true
true
false
Parent: false
You can see this darling here 你可以在这里看到这个宝贝
Reflection allows you to inspect the definition of other Objects, methods, function etc... (introspection) from outside of them. 反射使您可以从外部检查其他对象,方法,函数等的定义(自省)。 I am not to sure with recent versions of PHP, but in the past their was a significant performance hit when using reflection (it wasn't like seconds, more like 10s of milliseconds ).
我不确定最新版本的PHP,但是在过去,使用反射时它们对性能产生了重大影响(这不像秒,更像是10毫秒)。 However, there are some really neat things you can do with it.
但是,您可以使用它进行一些真正整洁的操作。
http://php.net/manual/en/intro.reflection.php http://php.net/manual/en/intro.reflection.php
That all said, you can access it with a simple get
method, and semantically that is probably the best way. 综上所述,您可以使用简单的
get
方法访问它,从语义上来说,这可能是最好的方法。
public method getProperty() {
return $this->property;
}
public method setProperty($property) {
return $this->property = $property;
}
A few things I feel I must mention 我觉得我必须提到的几件事
I rarely, rarely, rarely ever use private
properties. 我很少,很少,很少使用
private
财产。 The problem with private properties is if you decide to extend the class, later, you'll wind up changing most of them over to protected
anyway. 私有属性的问题是,如果您决定扩展该类,则以后,您最终会将它们中的大多数更改为
protected
的。 private - visible only within the scope of this
class. 私有 -仅在
this
的范围内可见。
I use protected
Something like 99%
of the time. 我有
99%
的时间使用protected
的内容。 It just works. 它只是工作。 protected - visible only within the scope of this class's descendants.
保护 -仅在此类后代的范围内可见。
I refuse to use public
properties as it's a poor design, IMO, that leads to a lot of woes when it comes time to maintain your code. 我拒绝使用
public
属性,因为它是一个糟糕的设计,IMO,在维护代码时会带来很多麻烦。 Classes should be Black Boxes
, which means the internal workings of them should not be exposed to the rest of your code. 类应该是
Black Boxes
,这意味着它们的内部工作不应暴露于代码的其余部分。 The problem with exposing all the workings of you class is you could rename a property without thinking and break some piece of code somewhere. 公开类的所有工作的问题是,您可以重命名属性而无需考虑并在某些地方破坏一些代码。 At least with public methods you can rename the properties, re-work the method and nothing outside the class should be affected (as long as the method name, inputs, and outputs don't change) public - visible within the scope of the caller (and class's descendants)
至少在公开方法,你可以重命名的属性,重新工作类之外的方法并没有什么应该受到影响(只要方法名,输入和输出不会改变) 公共 -可见呼叫者的范围之内(以及班级的后代)
Cheers, and happy coding. 欢呼,编码愉快。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.