سؤال

عند محاولة تغييره ، رمي استثناء.

هل كانت مفيدة؟

المحلول

أفترض أن الحل ، بالنسبة لخصائص الفصل ، سيكون:

  • لا تحدد خاصية بالاسم الذي يثير اهتمامك
  • استخدم السحر __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
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top