Доступ к частной переменной из функции-члена в PHP

Я получил класс от 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>

на мой взгляд, это определенно должно работать. Тем не менее, я получаю следующую ошибку, когда генерируется исключение, и я пытаюсь его отобразить:

Неустранимая ошибка: не удается получить доступ к частной собственности SpecialException:: $_ введите C:\path\to\exceptions.php в строке 74

Может кто-нибудь объяснить, почему я нарушаю правила здесь? Я делаю что-то ужасно острое с этим кодом? Есть ли более идиоматический способ справиться с этой ситуацией? Точка переменной $_type (как показано), что я хочу использовать другой класс div в зависимости от типа исключения.

Ответ 1

Назовите переменную 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

Ответ 2

просто пример доступа к частной собственности

<?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];
}

Ответ 3

См. мой ответ здесь: fooobar.com/questions/510337/...


Как и в случае с PHP 5.4, вы можете использовать предопределенный класс Closure для привязки метода/свойства класса к дельта-функциям, имеющим доступ даже к закрытым членам.

Класс Closure

Например, у нас есть класс с частной переменной, и мы хотим получить к нему доступ за пределами класса:

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 для привязки любого метода/свойства объекта obect к функции обратного вызова даже для частных членов:

PHP 7 +

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

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

Ответ 4

Вам нужно установить доступ к защищенным. Частное означает, что доступ к нему можно получить только из собственного класса и не может быть унаследован. Защищенный позволяет ему быть включенным, но доступ к нему по-прежнему нельзя получить непосредственно вне класса.

Ответ 5

Если вы проверите visibility документацию, похоронили в комментарии:

//Мы можем повторно использовать открытый и защищенный метод, но не private

Чтобы сделать то, что вы пытаетесь сделать, вы должны сделать protected.

Кстати, похоже, вы просто устанавливаете его как имя класса - вы можете просто использовать get_class():

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

Ответ 6

Вы действительно должны изменить accessmodifier на protected, когда вы создаете классы наследования.

Один дополнительный момент; не используйте return "";, а просто используйте return;