范围解析操作符 (::)
理解
类外使用
静态成员
$obj::$member1;
//访问实例中的静态变量ClassName::member3_visit2();
//访问ClassName类中的静态方法
普通成员
echo $obj->member1;
//访问实例中的变量$obj->member2();
//访问实例中的方法
常量
- echo $obj::member1;//访问实例中的常量
类内使用
静态成员
self::$member2;
//访问类中静态变量ClassName::$member2;
//访问类中静态变量(不建议使用)self::member2;
//访问类中静态方法
普通成员
echo $this->member2;
//访问类中的变量echo $this->member3();
//方法中访问其他方法
常量
- echo self::member2;//方法中访问常量
访问大纲
访问又分为静态成员的访问和普通成员访问
1:静态成员
- 类内访问
self::$静态属性名
self::$类常量名
(其实类内页可以使用类外访问的类名的访问方式,不过考虑到了后期类名的更改,self就很方便的解决了这个问题)
- 类外访问
类名::$静态属性名
类名::$类常量名
2:普通成员
- 类内访问
$this->属性名
$this->方法名
- 类外访问
$对象名->属性名
$对象名->方法名 ($对象名 指的是实例化后的对象)
实战演示
一:静态成员属性的访问
1: 静态外部访问
<?php
class ClassName {
//必须带“$”,否则是常量
public static $member1 = '成员1';
}
$obj = new ClassName;
//注意这里的“::”
echo $obj::$member1;
?>
输出:
成员1
2:静态内部访问 (要知道,在类内部访问类成员必须定义一个方法来访问)
<?php
class ClassName {
//必须带“$”,否则是常量
public static $member2 = '成员2 <br />';
public function member2() {
echo self::$member2;
//下面这条效果与上条相同,但不推荐使用(考虑继承中。类名会变的因素)
echo ClassName::$member2;
}
}
$obj = new ClassName;
//类内访问类中静态成员
$obj->member2();
?>
输出:
成员2
成员2
- 1:类内访问类内成员首先要定义一个方法在方法内访问;
- 2:最开始介绍到:类内其实可以使用类名的访问方式(
echo ClassName::$member2;
),考虑到项目后期可能会有类名更改问题,类内最好使用self来代替
(不过也正好证明了在类内访问其实就是使用类(名)进行指定类内的成员,讲这个是因为不同于普通成员中的类内访问方式--$this)
二:静态成员方法的访问
1:在类外访问类内静态方法
<?php
class ClassName {
//静态方法
public static function member3() {
echo __METHOD__;//打印当前方法的方法名
}
}
//类外访问类内静态方法
ClassName::member3();
?>
输出:
ClassName::member3
在类外使用 类名::类中的方法名。 (__METHOD__指的是当前方法的方法名)
2:在类内访问类内静态方法
<?php
class ClassName {
//静态方法
public static function member3() {
echo __METHOD__.'<br />';//打印当前方法的方法名
}
//方法访问静态方法
public function member3_visit1() {
self::member3();
}
//静态方法访问静态方法
public static function member3_visit2() {
self::member3();
}
}
$obj = new ClassName;
$obj->member3_visit1();
ClassName::member3_visit2();
?>
输出
ClassName::member3
ClassName::member3
- 类内访问静态方法,同样需要在方法内访问,
- 定义的方法可以使用普通方法进行访问,
- 也可以定义一个同样是静态方法的方法来访问其他静态方法。。
- (可能这句话有些绕,直接分析代码就行)
三:普通成员的属性访问
1:在类外访问
<?php
class ClassName {
public $member1 = '成员1 ';
}
$obj = new ClassName();
//注意这里,不是“$member1”
echo $obj->member1;
?>
输出:
成员1
这里有个重点,记得看后面
2:在类内访问
<?php
class ClassName {
public $member2 = '成员2 ';
function member2() {
echo $this->member2;
}
}
$obj = new ClassName();
$obj->member2();
?>
输出:
成员2
你可能已经发现了,为什么在最开始静态访问演示的时候,
function member2() {
echo $this->member2;
}
$obj->member2();
上面变量名都有$符号,而这里却没有。
要知道这里面php里面有个可变属性和可变方法。下面来演示一下。

在外面如果不带$,就是代表着取obj这个对象中进行访问查找 为此名字的成员。
一旦加上$,因为在类外部,就会被当做变量来找,所以就会报错。当然可以这样写 ⬇
<?php
class ClassName {
public $member1 = '成员1 ';
public $member2 = '成员2 ';
function member2() {
echo $this->member2;
}
}
$obj = new ClassName();
$member1 = 'member1';
echo $obj->$member1;
$obj->member2();
?>
输出:
成员1 成员2
(其中一个值当作另一个的名)当obj进行指向访问的时候 $member就会被解析为 member
四:普通成员的方法访问
1:类外访问
<?php
class ClassName {
public $member2 = '成员2,<br /> ';
function member2() {
echo $this->member2;
}
public function member3() {
echo __METHOD__;//打印当前方法的方法名
}
}
$obj = new ClassName();
$obj->member2();
$obj->member3();
?>
输出
成员2,
ClassName::member3
2:类内访问
<?php
class ClassName {
public function member3() {
echo __METHOD__.'<br />';//打印当前方法的方法名
}
public function member4() {
echo $this->member3();
//与上面一行代码同样的意思
$member3 = 'member3';
echo $this->$member3();
}
}
$obj = new ClassName();
$member4 = 'member4';
$obj->$member4();
?>
输出:
ClassName::member3
ClassName::member3
再次直接写了 可变的 形式,方法同样适用。
思考(这样的好处,以后比如前台页面的访问可以都给定 一个页面,页面中定义好类,类中定义好各个对象,通过页面点击传递要制定的对象名也就是方法名,然后使用可变的形式,来随时替换到变量,而调用只需要调用一次 $obj->变量名)
五:类常量的访问
首先:类常量就是const定义的常量。
要记住:类常量只能用const来定义
1:类外访问
<?php
class ClassName {
const member1='类常量1<br />';
}
$obj = new ClassName;
echo $obj::member1;
?>
输出:
类常量1
2:类内访问
<?php
class ClassName {
const member2='类常量2<br />';
public function visit() {
echo self::member2;
}
}
$obj = new ClassName;
$obj->visit();
?>
输出
类常量2
跟静态方式其实一样,但唯一的差别就是最前面中的 注释,变量名在类内声明的时候没有 $。
注意:(至于可变的形式,在常量中类内或者类外访问都不可以)
<?php
//以下代码采用可变方法访问常量,会报错
class ClassName {
const member1='类常量1<br />';
}
$obj = new ClassName;
//可变方法
$member1 = 'member1';
echo $obj::$member1;
?>
不过在调用方法的时候可以使用可变的形式,毕竟跟常量也没太大关系。
类与对象的内存关系
我们上面都知道,静态访问和类常量都是使用 类名来访问,而其他都是通过实例化的对象来访问。
其实:
在类内部,是分空间的,静态成员一般保存在类空间里,而像其他的 普通属性都是保存在对象的空间里(这里的对象指的是实例化的对象)
而唯一特殊的就是 成员方法,它按我们的访问方式是通过 对象来访问的,但是它并不存储在对象的空间里,相反存储在了类的空间里。
我们来使用前面的代码 证明一下:
<?php
class ClassName {
public $member1 = '成员1 ';
public $member2 = '成员2,<br /> ';
function member2() {
echo $this->member2;
}
//两个成员方法的访问
public function member3() {
echo __METHOD__.'<br />';//打印当前方法的方法名
}
public function member4() {
$member3 = 'member3';
echo $this->member3();
}
}
$obj = new ClassName();
$obj->member1 = '成员5';
echo $obj->member1;
$member1 = 'member1';
echo $obj->$member1;
$obj->member2();
$obj->member3();
$member4 = 'member4';
$obj->$member4();
$obj1 = new ClassName;
echo $obj1->member1;
?>
输出
成员5成员5成员2,
ClassName::member3
ClassName::member3
成员1
可以看出 新声明的obj1 明显没有被前面的 obj 改变的成员5 而改变!
就算是这个特殊的成员方法虽然存在了类空间里,但是仍不会被改变。
这样的原因就是因为存储在了 实例化的对象的空间里,一个实例化中的改变不会影响其他实例化对象的改变
二
<?php
class ClassName {
//两个静态属性
public static $member1 = '静态成员1 <br /> ';
public static $member2 = '静态成员2 <br /> ';
//两个静态方法
public static function member3() {
echo __METHOD__.'<br />';//打印当前方法的方法名
}
public function member3_visit1() {
self::member3();
}
public static function member3_visit2() {
self::member3();
}
public function member2() {
echo ClassName::$member2;
}
}
$obj = new ClassName();
//类外访问类中静态属性
ClassName::$member1 = '11131313';
echo ClassName::$member1;
//类内访问类中静态属性
$obj->member2();
//类外访问类内静态方法
ClassName::member3();
$obj->member3_visit1();
ClassName::member3_visit2();
$obj1 = new ClassName;
echo ClassName::$member1;
?>
而在类空间中除了不能改变的,常量外的静态成员,只要被改变,其他的实例化对象同样就会被调用。如上所显示。