قابلية الرؤية في كائنات PHP
يمكن تعريف قابلية رؤية خاصية أو تابع أو (بدءًا من الإصدار 7.1.0 من اللغة) ثابت بأنّها إلحاق صيغة التصريح بإحدى الكلمات المفتاحية public، أو protected، أو private. يتيح التصريح من نوع public الوصول إلى أعضاء الصنف من أي مكان، ويتيح التصريح من نوع protected الوصول إلى الأعضاء من داخل الصنف نفسه أو الأصناف التي ترث الصنف أو تورّثه، أما التصريح من نوع private فيتيح الوصول إلى الأعضاء من داخل الصنف الذي عرِّف فيه ذلك العضو حصرًا.
قابلية رؤية الخاصية
يجب أن يكون التصريح عن خاصيات الأصناف من نوع public، أو private، أو protected، وإن استخدمت الكلمة المفتاحية var للتصريح عن الخاصية فإنّها تعدّ من النوع public.
المثال 1: التصريح عن الخاصيات
<?php
/**
* Define MyClass
*/
class MyClass
{
public $public = 'Public';
protected $protected = 'Protected';
private $private = 'Private';
function printHello()
{
echo $this->public;
echo $this->protected;
echo $this->private;
}
}
$obj = new MyClass();
echo $obj->public;// Works
echo $obj->protected; // Fatal Error
echo $obj->private; // Fatal Error
$obj->printHello(); // Shows Public, Protected and Private
/**
* Define MyClass2
*/
class MyClass2 extends MyClass
{
// We can redeclare the public and protected properties, but not private
public $public = 'Public2';
protected $protected = 'Protected2';
function printHello()
{
echo $this->public;
echo $this->protected;
echo $this->private;
}
}
$obj2 = new MyClass2();
echo $obj2->public; // Works
echo $obj2->protected; // Fatal Error
echo $obj2->private; // Undefined
$obj2->printHello(); // Shows Public2, Protected2, Undefined
?>
ملاحظة: لضمان عدم حصول مشاكل في توافق الشيفرة مع الإصدار الرابع من اللغة، فإنّ الإصدار الخامس لا زال يدعم الكلمة المفتاحية var (كمرادف للكلمة المفتاحية public). يؤدي استخدام الكلمة المفتاحية var في الإصدارت السابقة للإصدار 5.1.3 إلى إطلاق تحذير من نوع E_STRICT.
قابلية رؤية التابع
يمكن التصريح عن توابع الأصناف كتوابع من نوع public، أو protected، أو private. وفي حال عدم استخدام أي كلمة مفتاحية لتحديد طبيعة التصريح، فإن اللغة ستعدّ أن التابع من النوع public.
المثال 2: التصريح عن التوابع
<?php
/**
* Define MyClass
*/
class MyClass
{
// التصريح عن دالة بانية عامة
public function __construct() { }
// التصريح عن دالة عامة
public function MyPublic() { }
// التصريح عن دالة محمية
protected function MyProtected() { }
// التصريح عن دالة خاصة
private function MyPrivate() { }
// هذه الدالة عامة
function Foo()
{
$this->MyPublic();
$this->MyProtected();
$this->MyPrivate();
}
}
$myclass = new MyClass;
$myclass->MyPublic(); // Works
$myclass->MyProtected(); // Fatal Error
$myclass->MyPrivate(); // Fatal Error
$myclass->Foo(); // Public, Protected and Private work
/**
* Define MyClass2
*/
class MyClass2 extends MyClass
{
// This is public
function Foo2()
{
$this->MyPublic();
$this->MyProtected();
$this->MyPrivate(); // Fatal Error
}
}
$myclass2 = new MyClass2;
$myclass2->MyPublic(); // Works
$myclass2->Foo2(); // Public and Protected work, not Private
class Bar
{
public function test() {
$this->testPrivate();
$this->testPublic();
}
public function testPublic() {
echo "Bar::testPublic\n";
}
private function testPrivate() {
echo "Bar::testPrivate\n";
}
}
class Foo extends Bar
{
public function testPublic() {
echo "Foo::testPublic\n";
}
private function testPrivate() {
echo "Foo::testPrivate\n";
}
}
$myFoo = new Foo();
$myFoo->test(); // Bar::testPrivate
// Foo::testPublic
?>
قابلية رؤية الثوابت
منذ الإصدار 7.1.0 من اللغة أصبح بالإمكان تعريف الثوابت كثوابت من النوع public، أو private، أو protected. وفي حال عدم استخدام أي كلمة مفتاحية عند التصريح عن الثابت فإنّ اللغة ستعدّه من نوع public.
المثال 3: التصريح عن الثوابت في الإصدار 7.1.0 وما بعده
<?php
/**
* Define MyClass
*/
class MyClass
{
// التصريح عن ثابت عام
public const MY_PUBLIC = 'public';
// التصريح عن ثابت محمي
protected const MY_PROTECTED = 'protected';
// التصريح عن ثابت خاص
private const MY_PRIVATE = 'private';
public function foo()
{
echo self::MY_PUBLIC;
echo self::MY_PROTECTED;
echo self::MY_PRIVATE;
}
}
$myclass = new MyClass();
MyClass::MY_PUBLIC; // Works
MyClass::MY_PROTECTED; // Fatal Error
MyClass::MY_PRIVATE; // Fatal Error
$myclass->foo(); // Public, Protected and Private work
/**
* Define MyClass2
*/
class MyClass2 extends MyClass
{
// This is public
function foo2()
{
echo self::MY_PUBLIC;
echo self::MY_PROTECTED;
echo self::MY_PRIVATE; // Fatal Error
}
}
$myclass2 = new MyClass2;
echo MyClass2::MY_PUBLIC; // Works
$myclass2->foo2(); // Public and Protected work, not Private
?>
قابلية الرؤية في الكائنات الأخرى
يمكن للكائنات التي تكون من النوع ذاته الوصول إلى الأعضاء من النوع private و protected حتى لو لم تكن هذه الكائنات نسخًا متشابهة، وسبب ذلك هو تفاصيل الاستخدام المحدّد تكون معروفة داخل تلك الكائنات.
المثال 4: الوصول إلى أعضاء من نوع private في كائن من نفس النوع
<?php
class Test
{
private $foo;
public function __construct($foo)
{
$this->foo = $foo;
}
private function bar()
{
echo 'Accessed the private method.';
}
public function baz(Test $other)
{
$other->foo = 'hello';
var_dump($other->foo);
$other->bar();
}
}
$test = new Test('test');
$test->baz(new Test('other'));
?>
تعطي الشيفرة السابقة النتيجة التالية:
string(5) "hello"
Accessed the private method.