доступ к закрытой переменной из функции-члена в PHP - PullRequest
19 голосов
/ 19 ноября 2009

Я вывел класс из 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 в зависимости от типа перехваченного исключения.

Ответы [ 6 ]

37 голосов
/ 15 марта 2010

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

<?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];
}
36 голосов
/ 19 ноября 2009

Назовите защищенную переменную:

* 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
7 голосов
/ 06 ноября 2016

Смотрите мой ответ здесь: https://stackoverflow.com/a/40441769/1889685


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

PHP 7 +

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

echo $getFooBar->call($foo); // Prints Foo::Bar
0 голосов
/ 19 ноября 2009

Вы действительно должны изменить модификатор доступа на protected при создании классов наследования.

Одна дополнительная точка, хотя; не используйте return "";, а просто используйте return;

0 голосов
/ 19 ноября 2009

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

// Мы можем переопределить публичный и защищенный метод, но не приватный

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

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

<div class="<?php echo get_class($this); ?>class">
0 голосов
/ 19 ноября 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...