公开:
当你将一个方法(函数)或属性(变量)声明为公开
时,这些方法和属性可以被以下方式访问:
- 声明它的同一个类。
- 继承上述声明类的类。
- 任何在该类之外的外部元素也可以访问这些内容。
示例:
<?php
class GrandPa
{
public $name='Mark Henry';
}
class Daddy extends GrandPa // Inherited class
{
function displayGrandPaName()
{
return $this->name;
}
}
$daddy = new Daddy;
echo $daddy->displayGrandPaName();
$outsiderWantstoKnowGrandpasName = new GrandPa;
echo $outsiderWantstoKnowGrandpasName->name;
受保护的:
当你将一个方法(函数)或属性(变量)声明为protected
时,这些方法和属性可以被以下方式访问:
外部成员无法访问这些变量。所谓的“外部成员”是指它们不是声明类本身的对象实例。
示例:
<?php
class GrandPa
{
protected $name = 'Mark Henry';
}
class Daddy extends GrandPa
{
function displayGrandPaName()
{
return $this->name;
}
}
$daddy = new Daddy;
echo $daddy->displayGrandPaName();
$outsiderWantstoKnowGrandpasName = new GrandPa;
echo $outsiderWantstoKnowGrandpasName->name;
具体的错误将是这样的:
PHP致命错误:无法访问受保护的属性GrandPa::$name
私有:
当你将一个方法(函数)或属性(变量)声明为私有
时,这些方法和属性只能被以下对象访问:
外部成员无法访问这些变量。外部成员指的是不是声明类的对象实例,甚至是继承了声明类的类。
示例:
<?php
class GrandPa
{
private $name = 'Mark Henry';
}
class Daddy extends GrandPa
{
function displayGrandPaName()
{
return $this->name;
}
}
$daddy = new Daddy;
echo $daddy->displayGrandPaName();
$outsiderWantstoKnowGrandpasName = new GrandPa;
echo $outsiderWantstoKnowGrandpasName->name;
具体的错误信息如下:
通知:未定义属性:Daddy::$name
致命错误:无法访问私有属性:GrandPa::$name
使用反射解剖Grandpa类
这个主题并不是超出范围的,我在这里加上它只是为了证明反射的强大。正如我在上面的三个例子中所述,protected
和private
成员(属性和方法)不能在类外部访问。
然而,通过反射,你甚至可以在类外部访问protected
和private
成员,这是非常了不起的!
那么,什么是反射?
反射增加了逆向工程类、接口、函数、方法和扩展的能力。此外,它们还提供了获取函数、类和方法的文档注释的方法。
前言
我们有一个名为Grandpas
的类,假设我们有三个属性。为了便于理解,假设有三个名字为:
- Mark Henry
- John Clash
- Will Jones
让我们分别将它们(修饰符)设置为
public
、
protected
和
private
。你很清楚
protected
和
private
成员无法在类外部访问。现在让我们使用反射来反驳这个说法。
代码
<?php
class GrandPas // The Grandfather's class
{
public $name1 = 'Mark Henry';
protected $name2 = 'John Clash';
private $name3 = 'Will Jones';
}
$granpaWithoutReflection = new GrandPas;
echo "#Scenario 1: Without reflection<br>";
echo "Printing members the usual way.. (without reflection)<br>";
foreach($granpaWithoutReflection as $k=>$v)
{
echo "The name of grandpa is $v and he resides in the variable $k<br>";
}
echo "<br>";
$granpa = new ReflectionClass('GrandPas');
$granpaNames=$granpa->getDefaultProperties();
echo "#Scenario 2: With reflection<br>";
echo "Printing members the 'reflect' way..<br>";
foreach($granpaNames as $k=>$v)
{
echo "The name of grandpa is $v and he resides in the variable $k<br>";
}
输出:
Printing members the usual way.. (Without reflection)
The name of grandpa is Mark Henry and he resides in the variable name1
Printing members the 'reflect' way..
The name of grandpa is Mark Henry and he resides in the variable name1
The name of grandpa is John Clash and he resides in the variable name2
The name of grandpa is Will Jones and he resides in the variable name3
常见误解:
请不要将下面的示例与之混淆。正如您所看到的,私有(private)和受保护(protected)成员在没有使用反射的情况下无法在类外部访问。
<?php
class GrandPas // The Grandfather's class
{
public $name1 = 'Mark Henry';
protected $name2 = 'John Clash';
private $name3 = 'Will Jones';
}
$granpaWithoutReflections = new GrandPas;
print_r($granpaWithoutReflections);
输出:
GrandPas Object
(
[name1] => Mark Henry
[name2:protected] => John Clash
[name3:GrandPas:private] => Will Jones
)
调试函数
print_r
、var_export
和var_dump
是调试器函数。它们以人类可读的形式呈现有关变量的信息。这三个函数将显示PHP 5中对象的protected
和private
属性。静态类成员将不会被显示。
##更多资源: