كيفية تنفيذ متغير عضو في القراءة فقط في PHP؟
-
23-09-2019 - |
سؤال
عند محاولة تغييره ، رمي استثناء.
المحلول
أفترض أن الحل ، بالنسبة لخصائص الفصل ، سيكون:
- لا تحدد خاصية بالاسم الذي يثير اهتمامك
- استخدم السحر
__get
طريقة للوصول إلى تلك الخاصية ، باستخدام الاسم "المزيف" - تحديد
__set
الطريقة بحيث يلقي استثناء عند محاولة تعيين هذه الخاصية. - يرى التحميل الزائد, لمزيد من المعلومات حول الأساليب السحرية.
بالنسبة للمتغيرات ، لا أعتقد أنه من الممكن أن يكون لديك متغير للقراءة فقط يمكن لـ PHP أن يلقي استثناء عندما تحاول الكتابة إليه.
على سبيل المثال ، ضع في اعتبارك هذه الفئة الصغيرة:
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
}
}
}
stanciaging الفصل ومحاولة قراءة العقار:
$a = new MyClass();
echo $a->myVar . '<br />';
سوف تحصل على الإخراج المتوقع:
test
أثناء محاولة الكتابة إلى العقار:
$a->myVar = 10;
سوف تحصل على استثناء:
Exception: not allowed : myVar in /.../temp.php on line 19
نصائح أخرى
class test {
const CANT_CHANGE_ME = 1;
}
وأنت تحيلها باسم test::CANT_CHANGE_ME
استخدم ثابت. الكلمة الرئيسية const
أعلم أن هذا سؤال قديم ، لكن إجابة باسكال ساعدتني حقًا وأردت إضافتها قليلاً.
__GET () لا يطلق النار على الخصائص غير الموجودة فحسب ، بل تطلق على الخصائص "التي يتعذر الوصول إليها" أيضًا ، مثل تلك المحمية. هذا يجعل من السهل صنع خصائص للقراءة فقط!
class MyClass {
protected $this;
protected $that;
protected $theOther;
public function __get( $name ) {
if ( isset( $this->$name ) ) {
return $this->$name;
} else {
throw new Exception( "Call to nonexistent '$name' property of MyClass class" );
return false;
}
}
public function __set( $name ) {
if ( isset( $this->$name ) ) {
throw new Exception( "Tried to set nonexistent '$name' property of MyClass class" );
return false;
} else {
throw new Exception( "Tried to set read-only '$name' property of MyClass class" );
return false;
}
}
}
الإجابة المختصرة هي أنه لا يمكنك إنشاء متغير عضو كائن للقراءة فقط في PHP.
في الواقع ، تعتبر معظم اللغات الموجهة نحو الكائنات أنها سيئة لفضح متغيرات الأعضاء علنًا على أي حال ... (C# كونها الاستثناء الكبير القبيح مع عمليات بناء الممتلكات).
إذا كنت تريد متغير فئة ، استخدم const
الكلمة الرئيسية:
class MyClass {
public const myVariable = 'x';
}
يمكن الوصول إلى هذا المتغير:
echo MyClass::myVariable;
سيكون هذا المتغير موجودًا في إصدار واحد بالضبط بغض النظر عن عدد الكائنات المختلفة من النوع MyClass
يمكنك إنشاء ، وفي معظم السيناريوهات الموجهة نحو الكائنات ، لا فائدة منها.
ومع ذلك ، إذا كنت تريد متغيرًا للقراءة فقط يمكن أن يكون له قيم مختلفة لكل كائن ، فيجب عليك استخدام متغير عضو خاص وطريقة ملحق (ويعرف أيضًا باسم Getter):
class MyClass {
private $myVariable;
public function getMyVariable() {
return $this->myVariable;
}
public function __construct($myVar) {
$this->myVariable = $myVar;
}
}
يتم تعيين المتغير في المُنشئ ، ويتم صنعه للقراءة فقط من خلال عدم وجود جهاز. لكن كل مثيل من MyClass
يمكن أن يكون لها قيمتها الخاصة 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