How to implement a read-only member variable in PHP?
-
23-09-2019 - |
문제
When trying to change it,throw an exception.
해결책
I suppose a solution, for class properties, would be to :
- not define a property with the name that interests you
- use the magic
__get
method to access that property, using the "fake" name - define the
__set
method so it throws an exception when trying to set that property. - See Overloading, for more informations on magic methods.
For variables, I don't think it's possible to have a read-only variable for which PHP will throw an exception when you're trying to write to it.
For instance, consider this little class :
class MyClass {
protected $_data = array(
'myVar' => 'test'
);
public function __get($name) {
if (isset($this->_data[$name])) {
return $this->_data[$name];
} else {
// non-existant property
// => up to you to decide what to do
}
}
public function __set($name, $value) {
if ($name === 'myVar') {
throw new Exception("not allowed : $name");
} else {
// => up to you to decide what to do
}
}
}
Instanciating the class and trying to read the property :
$a = new MyClass();
echo $a->myVar . '<br />';
Will get you the expected output :
test
While trying to write to the property :
$a->myVar = 10;
Will get you an Exception :
Exception: not allowed : myVar in /.../temp.php on line 19
다른 팁
class test {
const CANT_CHANGE_ME = 1;
}
and you refer it as test::CANT_CHANGE_ME
Use a constant. Keyword const
이 효과를 얻는 속임수를 사용하는 것은 이렇게 할 수있는 방법이 없습니다.정상 열 (첫 번째가 추가됨)과 클러스터 된 열의 플롯을 추가하여 작동합니다 (하나의 시리즈는 모두 0 인 경우).모든 열의 너비는 동일하게 설정됩니다.
이제 내가 가지고있는 것입니다 :
function setupWeekElectricBar(Chart, theme, ClusteredColumns, Columns)
{
var realData = [2.50,3.45,1.22,1.86,2.54, 4.01, {y:3.10, color: 'green'}]; // a new array
var blankData = [0,0,0,0,0]; // a new array
var targetData = [2.00,2.00,2.00,2.86,2.54, 2.00, 2.00];
var chart = new Chart("weekElectricBar", {title: 'Daily Heating Cost', titleGap: 0, titleFont: 'bold normal normal 15px Tahoma', titleFontColor: "black"});
chart.setTheme(theme);
chart.addPlot("default", {
type: ClusteredColumns,
markers: true,
gap: 5,
minBarSize : 40,
maxBarSize : 40,
font: "bold normal 14px Tahoma",
fontColor: "Black",
shadows: {dx:4, dy:4}
});
chart.addPlot("back", {
type: Columns,
markers: true,
gap: 5,
minBarSize : 40,
maxBarSize : 40,
font: "bold normal 14px Tahoma",
fontColor: "Black",
shadows: {dx:4, dy:4}
});
chart.addAxis("y", {includeZero: true, fixUpper: 'major', vertical: true, min: 0, max:5, labels: [{value: 0, text: "£0"}, {value: 1, text: "£1"}, {value: 2, text: "£2"}, {value: 3, text: "£3"}, {value: 4, text: "£4"}, {value: 5, text: "£5"}] });
chart.addAxis("x", {labels: [{value: 1, text: "Wed"}, {value: 2, text: "Thurs"}, {value: 3, text: "Fri"}, {value: 4, text: "Sat"}, {value: 5, text: "Sun"}, {value: 6, text: "Mon"}, {value: 7, text: "Last 24 Hrs"}]});
chart.addSeries("blankData",blankData, {width: 2});
chart.addSeries("realData",realData);
chart.addSeries("targetData",targetData, {plot:'back'});
chart.render();
}
. The short answer is you can't create a read-only object member variable in PHP.
In fact, most object-oriented languages consider it poor form to expose member variables publicly anyway... (C# being the big, ugly exception with its property-constructs).
If you want a class variable, use the const
keyword:
class MyClass {
public const myVariable = 'x';
}
This variable can be accessed:
echo MyClass::myVariable;
This variable will exist in exactly one version regardless of how many different objects of type MyClass
you create, and in most object-oriented scenarios it has little to no use.
If, however, you want a read-only variable that can have different values per object, you should use a private member variable and an accessor method (a k a getter):
class MyClass {
private $myVariable;
public function getMyVariable() {
return $this->myVariable;
}
public function __construct($myVar) {
$this->myVariable = $myVar;
}
}
The variable is set in the constructor, and it's being made read-only by not having a setter. But each instance of MyClass
can have its own value for myVariable
.
$a = new MyClass(1);
$b = new MyClass(2);
echo $a->getMyVariable(); // 1
echo $b->getMyVariable(); // 2
$a->setMyVariable(3); // causes an error - the method doesn't exist
$a->myVariable = 3; // also error - the variable is private