有沒有辦法在PHP中創建對象的只讀屬性?我有一個對象,裏面有一對數組。我想訪問他們,因爲我通常會陣列PHP中的只讀屬性?
echo $objObject->arrArray[0];
但我不希望能夠寫入這些數組後,他們構建。這感覺就像一個PITA構建一個局部變量:
$arrArray = $objObject->getArray1();
echo $arrArray[0];
而且不管怎麼說,雖然它一直在數組中的對象質樸,它並不能阻止我重新寫本地數組變量。
有沒有辦法在PHP中創建對象的只讀屬性?我有一個對象,裏面有一對數組。我想訪問他們,因爲我通常會陣列PHP中的只讀屬性?
echo $objObject->arrArray[0];
但我不希望能夠寫入這些數組後,他們構建。這感覺就像一個PITA構建一個局部變量:
$arrArray = $objObject->getArray1();
echo $arrArray[0];
而且不管怎麼說,雖然它一直在數組中的對象質樸,它並不能阻止我重新寫本地數組變量。
那麼,問題是你想防止寫作從哪裏?
的第一步是使陣列保護或私人爲防止寫入從對象範圍之外:
protected $arrArray = array();
如果從陣列的「外部」的吸氣將你的罰款。或者:
public function getArray() { return $this->arrArray; }
和訪問它像
$array = $obj->getArray();
或
public function __get($name) {
return isset($this->$name) ? $this->$name : null;
}
和訪問它想:
$array = $obj->arrArray;
注意,它們不返回引用。所以你不能從對象範圍之外改變原始數組。你可以改變陣列本身...
如果你真的需要一個完全不可改變的數組,你可以使用一個對象使用ArrayAccess
...
或者,你可以簡單地擴展ArrayObject
並覆蓋所有的寫作方法:
class ImmutableArrayObject extends ArrayObject {
public function append($value) {
throw new LogicException('Attempting to write to an immutable array');
}
public function exchangeArray($input) {
throw new LogicException('Attempting to write to an immutable array');
}
public function offsetSet($index, $newval) {
throw new LogicException('Attempting to write to an immutable array');
}
public function offsetUnset($index) {
throw new LogicException('Attempting to write to an immutable array');
}
}
然後,只需讓$this->arrArray
對象的實例:
public function __construct(array $input) {
$this->arrArray = new ImmutableArrayObject($input);
}
它還支持大多數陣列狀用法:
count($this->arrArray);
echo $this->arrArray[0];
foreach ($this->arrArray as $key => $value) {}
但是,如果您嘗試寫微博,你會得到一個LogicException
...
哦,但要意識到如果你需要寫它,所有你需要做的(對象中)是這樣做:
$newArray = $this->arrArray->getArrayCopy();
//Edit array here
$this->arrArray = new ImmutableArrayObject($newArray);
如果您使用PHP 5 +,可以使用__set()和__get()方法執行此操作。
你必須定義它們如何工作,但應該這樣做。
編輯一個例子就是這樣。
class Example {
private $var;
public function __get($v) {
if (is_array($v)) {
foreach() {
// handle it here
}
} else {
return $this->$v;
}
}
}
這可能不是這樣做的「最好」的方式,但它會根據你的需要
老闆:「我還以爲你說你完成了你的算法」客戶: 「我做老闆,有什麼問題」老闆:「它不起作用」客戶:「它取決於你需要什麼」 – Chris 2010-08-30 13:36:55
@Chris客戶爲什麼要接受老闆的命令?大聲笑。 – 2017-05-09 21:32:32
如果定義的工作,神奇的功能__get()
和__set()
將每當一個不存在的所謂或訪問私有財產。這可以用於爲私有屬性創建「get」和「set」方法,例如使它們成爲只讀或在存儲或檢索數據時對其進行操作。
例如:
class Foo
{
private $bar = 0;
public $baz = 4; // Public properties will not be affected by __get() or __set()
public function __get($name)
{
if($name == 'bar')
return $this->bar;
else
return null;
}
public function __set($name, $value)
{
// ignore, since Foo::bar is read-only
}
}
$myobj = new Foo();
echo $foo->bar; // Output is "0"
$foo->bar = 5;
echo $foo->bar; // Output is still "0", since the variable is read-only
在課堂上,這樣做:
private $array;
function set_array($value) {
$this->array = $value;
}
那麼你只需要設置是這樣的:
$obj->set_array($new_array);
如果我想讓我的不可變陣列用創建數據加載本身我會覆蓋__construct函數,調用父構造函數,但是如何設置對象包含的內容? – 2012-06-29 18:39:52
非常好的答案!但是請注意,一個數組可以包含對象:每個對象都作爲引用返回,並且可以更改,即使使用不可變的類:'$ a = new ImmutableArrayObject((object)['foo'=>'bar']); $ b = $ a [0]; $ b-> foo ='改變';' – Philipp 2017-04-23 18:44:45