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

Car*_*ers 19 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 "";

    }

}
Run Code Online (Sandbox Code Playgroud)

然后,我是MyException这样派生的:

class SpecialException extends MyException {

    private $_type = "superspecial";

}
Run Code Online (Sandbox Code Playgroud)

如果我throw new SpecialException("bla")来自一个函数,捕获它,然后去echo $e,那么该__toString函数应该加载一个模板,显示它,然后实际上不返回任何回显.

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

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

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

</div>
Run Code Online (Sandbox Code Playgroud)

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

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

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

Fiv*_*ell 39

只是一个如何访问私有财产的例子

<?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];
}
Run Code Online (Sandbox Code Playgroud)

  • 先生,你很聪明. (4认同)

dfi*_*ovi 37

将变量命名为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
Run Code Online (Sandbox Code Playgroud)

  • 注意:在 PHP 中,`protected` 意味着你的父母也可以访问它们。 (2认同)

Chr*_*ras 9

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


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

Closure类

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

class Foo {
    private $bar = "Foo::Bar";
}
Run Code Online (Sandbox Code Playgroud)

PHP 5.4+

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

$getFooBar = $getFooBarCallback->bindTo($foo, 'Foo');
echo $getFooBar(); // Prints Foo::Bar
Run Code Online (Sandbox Code Playgroud)

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

PHP 7+

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

echo $getFooBar->call($foo); // Prints Foo::Bar
Run Code Online (Sandbox Code Playgroud)