2016-12-29 16 views
0

Я не могу найти, или, может быть, я имею в виду неправильно, но мне нужно, чтобы сделать переменную, которая не может быть изменена, как только для чтения, что-то вроде:Как сделать конечную переменную в PHP?

final $finalVar = 'extremely secret number'; // don't change 

$finalVar = 'hacked...'; // THROW I GIANT BIG ERROR HERE ! 
+8

Используйте константу. –

+1

https://secure.php.net/manual/en/language.constants.php – aynber

+0

Да, я думал о постоянных, но не могу ли я использовать его с долларом? – user544262772

ответ

1

Помимо констант (как указано в комментариях), единственный способ, которым я могу думать, чтобы сделать это, чтобы использовать отношения родитель-ребенок с private переменной

class ParentC { 
    private $var = 'bob'; 
} 

class ChildC extends ParentC { 
    public function setVar() { 
     // Fatal error: Uncaught Error: Cannot access private property ParentC::$var 
     echo parent::$var; 
    } 
} 

Обратите внимание, что есть a hacky way around that с помощью класса Reflection. Но, по большей части, вы не можете коснуться private родительских переменным из дочернего класса

+0

Детский класс не может изменить переменную, но он также не может ее прочитать. – Andrea

+0

@ Andrea Да, но вы можете сделать метод getter или перегрузку, чтобы обойти это – Machavity

1

Хотя было talk только для чтения переменных, по крайней мере, 2012, с даже RFC предлагая его на объектах, поддержка не существует на языке.

Одним из способов достижения чтения только переменного (или набора только для чтения переменных, как это может быть важно при определенных значениях конфигурации) являются с посредническим контейнером:

class Readonly { 
    public function __construct(...$vars) { 
     $this->vars; 
    } 

    public function __set($var, $value) { 
     if (array_key_exists($var, $this->vars)) { 
      throw new \LogicException("Variable $var is read-only"); 
     } else { 
      $this->vars[$var] = $value; 
     } 
    } 

    public function __get($var) { 
     return array_key_exists($var, $this->vars) ? $this->vars[$var] : null; 
    } 

    protected $vars = []; 
} 

Что позволяет создавать контейнер переменных только для чтения:

$config = new Readonly('apikey'); 

$config->apikey = 'A01AB020'; // this works, first time set 
echo $config->apikey; 

$config->apikey = '00000000'; // boom! it's "final" 
+0

. Интересно, почему такой длинный ответ, если фактическое решение состоит в использовании констант? Здесь нет настоящей проблемы, ОП просто не хочет писать код без знака доллара. Это похоже на тотальную перегрузку ИМО, проблема в том, что она находится на стуле, а не на компьютере. OP должен научиться использовать этот язык, а не склонять его к своей воле, если у него нет ясной причины, по которой он не хочет использовать конструкции, предназначенные для определенных целей. Я не голосовал по этому поводу, но считаю, что это неверно, потому что он будет вводить в заблуждение будущих посетителей. – Mjh

+0

Константы @Mjh могут быть только скалярными или массивами (через 'const' в 5.6+ или' define' в 7.0+). Константы загрязняют глобальное пространство имен. 'const' - это время компиляции и должно быть объявлено в области верхнего уровня: не в функциях, циклах или try/catch. 'const' не может быть инициализирован из переменной, что может быть важно, если OP читает из файла конфигурации. ('define' может, но тогда у нас есть проблема без массива в <7, плюс проблемы с именами и глобальные проблемы загрязнения.) Короче говоря, я думаю, что немного презумпция прямо заявить, что« фактическое решение заключается в использовании константы». – bishop

+1

@bishop можно определить константы уровня класса. Фактическое решение - использовать константы. Независимо от того, управляете ли вы ими через глобальный охват или класс - до вас. Нет необходимости избегать констант.Если что-то неизменное, это не переменная. Если вам нужно сохранить что-то еще, кроме скаляра, то использование IoC и продемонстрированная вами техника - это путь. Всегда есть правильный инструмент для работы. – Mjh