从PHP中的成员函数访问私有变量

时间:2009-11-19 09:53:20

标签: php oop exception

我从Exception派生了一个类,基本上是这样的:

class MyException extends Exception {

    private $_type;

    public function type() {
        return $this->_type; //line 74
    }

    public function __toString() {

        include "sometemplate.php";
        return "";

    }

}

然后,我从MyException得出如此:

class SpecialException extends MyException {

    private $_type = "superspecial";

}

如果我throw new SpecialException("bla")来自一个函数,请抓住它,然后转到echo $e,那么__toString函数应该加载一个模板,显示该模板,然后实际上不返回任何内容来回显。

这基本上就是模板文件中的内容

<div class="<?php echo $this->type(); ?>class">

    <p> <?php echo $this->message; ?> </p>

</div>
在我看来,这绝对有用。但是,当抛出异常并尝试显示它时,我收到以下错误:

  

致命错误:无法在 74 C:\ path \ to \ exceptions.php 中访问私有属性SpecialException :: $ _ type

任何人都能解释为什么我违反规则吗?我用这段代码做了一些非常机智的事吗?有没有更惯用的方法来处理这种情况? $_type变量的点是(如图所示)我希望使用不同的div类,具体取决于捕获的异常类型。

8 个答案:

答案 0 :(得分:36)

将变量命名为protected:

* Public: anyone either inside the class or outside can access them
* Private: only the specified class can access them. Even subclasses will be denied access.
* Protected: only the specified class and subclasses can access them

答案 1 :(得分:36)

仅举例说明如何访问私有财产

<?php
class foo {
    private $bar = 'secret';
}
$obj = new foo;


if (version_compare(PHP_VERSION, '5.3.0') >= 0)
{

      $myClassReflection = new ReflectionClass(get_class($obj));
      $secret = $myClassReflection->getProperty('bar');
      $secret->setAccessible(true);
      echo $secret->getValue($obj);
}
else 
{
    $propname="\0foo\0bar";
    $a = (array) $obj;
    echo $a[$propname];
}

答案 2 :(得分:7)

请在此处查看我的回答: https://stackoverflow.com/a/40441769/1889685

PHP 5.4 开始,您可以使用预定义的Closure类将类的方法/属性绑定到甚至可以访问私有成员的delta函数。

The Closure class

例如,我们有一个带有私有变量的类,我们想在类外部访问它:

class Foo {
    private $bar = "Foo::Bar";
}

PHP 5.4 +

$foo = new Foo;
$getFooBarCallback = function() {
    return $this->bar;
};

$getFooBar = $getFooBarCallback->bindTo($foo, 'Foo');
echo $getFooBar(); // Prints Foo::Bar

从PHP 7开始,您可以使用新的Closure::call方法将对象的任何方法/属性绑定到回调函数,即使对于私有成员也是如此:

PHP 7 +

$foo = new Foo;
$getFooBar = function() {
    return $this->bar;
}

echo $getFooBar->call($foo); // Prints Foo::Bar

答案 3 :(得分:0)

您需要设置受保护的访问权限。私有意味着它只能从它自己的类中访问,不能被继承。受保护允许它不受限制,但仍然无法直接从课外访问。

答案 4 :(得分:0)

如果您查看visibility文档,则隐藏在评论中的是:

  

//我们可以重新声明public和protected方法,但不能重新声明

你应该让protected做你想做的事。

顺便说一下,您似乎只是将其设置为班级名称 - 您可以使用get_class()

<div class="<?php echo get_class($this); ?>class">

答案 5 :(得分:0)

在构建继承类时,您确实应该将访问修饰符更改为protected

虽然增加了一点;不要使用return "";,只需使用return;

答案 6 :(得分:0)

无法在类外访问$ this。 相反,需要调用该类的实例。 然后,访问该类中的函数,该函数将返回消息。

答案 7 :(得分:0)

通过使用 \Closure 有这种方式:

$reader = function ($object, $property) {
    $value = \Closure::bind(function () use ($property) {
         return $this->$property;
    }, $object, $object)->__invoke();

    return $value;
};

$myClass = new MyClass();
$property = $reader($myClass, 'yourProperty');
echo $property; // will display the value of property