PHP基础补全系列:static

    昨天晚上睡了大概两个小时。感觉今天一天整个人的状态都特别萎靡。    

    在手册中,static主要实现两个作用,1.定义静态变量和静态方法;2.实现后期静态绑定(延迟静态绑定)

    定义静态变量和静态方法主要是需要注意声明和调用的方式。

    1.手册中提到静态属性不能使用表达式声明。这个并不严谨,实际测试使用类似于 2+3 或者 "hello "."world" 这种方式声明,虽然编辑器报警,但是实际执行没有问题。如果使用函数或者变量声明,则直接报错

    2.静态方法可以通过对象调用,但是静态属性不能。

    3.在函数中的静态变量,在程序离开函数后,静态变量的值不丢失。

    具体见代码:

<?php

error_reporting(E_ALL);

class testStatic {

	public static $a = 1;

	public static $b = 3 + 4;

	public static $c = "Hello " . "world\n";

	//public static $d = time();

	public static function test () {
		echo self::$a . "\n";
		echo self::$b . "\n";
		echo self::$c . "\n";
		//echo self::$d . "\n";
	}

}

//手册中提到静态属性不能通过表达式初始化,但是testStatic::$b和testStatic::$c编辑器报警,运行正常.testStatic::$d报错.
testStatic::test(); //testStatic::$a,testStatic::$b,testStatic::$c可以正常输出,$d报错

$temp = new testStatic();
//静态属性不能通过对象访问
echo $temp->a;//报错
//静态方法可以通过对象访问
$temp->test();//正常

//可以在函数内部声明静态变量,当程序执行离开函数后,静态变量的值不丢失
function testStaticVaribale () {
	static $a = 1;
	echo ($a++) . "\n";
}

testStaticVaribale();//输出1
testStaticVaribale();//输出2

//基于这个原因,可以通过使用静态变量来写递归(不过个人认为这并不是太好的实践)
function dfs () {
	static $count = 0;
	$count++;
	echo $count;
	if($count < 10)
		dfs();
}

dfs();//输出 12345678910

    在C语言中,static声明的全局变量和函数都只能在当前声明的源文件内调用,在PHP中没有发现这个限制。

    编写in.php文件如下:

<?php

$a = "hello,world\n";

static $b = "hello,world\n";

    编写out.php文件如下:

<?php

require_once "in.php";

function test () {
	global $b;
	echo $b;
}

//在C语言中static关键字限制了生命的静态全局变量和静态函数只在声明的文件内有效,在其他文件中不能使用.
//在PHP中我测试的结果没有这个问题,下面三个语句输出结果均正常.
echo $a;//输出 hello,world
echo $b;//输出 hello,world
test();//输出 hello,world

    

    static的另一个作用是实现后期延迟绑定,这里援引手册中的解释如下:

    准确说,后期静态绑定工作原理是存储了在上一个“非转发调用”(non-forwarding call)的类名。当进行静态方法调用时,该类名即为明确指定的那个(通常在 :: 运算符左侧部分);当进行非静态方法调用时,即为该对象所属的类。所谓的“转发调用”(forwarding call)指的是通过以下几种方式进行的静态调用:self::,parent::,static:: 以及 forward_static_call()。可用 get_called_class() 函数来得到被调用的方法所在的类名,static:: 则指出了其范围。

    该功能从语言内部角度考虑被命名为“后期静态绑定”。“后期绑定”的意思是说,static:: 不再被解析为定义当前方法所在的类,而是在实际运行时计算的。也可以称之为“静态绑定”,因为它可以用于(但不限于)静态方法的调用。

    样例见代码:

<?php

//通过static可以实现后期静态绑定(有些地方成为延迟静态绑定)
class Daddy {

	public static function getClassName () {
		echo __CLASS__ . "\n";
	}

}

class Son extends Daddy {

}

Daddy::getClassName();//输出 Daddy
Son::getClassName();//输出 Daddy

class Daddy_1 {

	public static function getClassName () {
		echo __CLASS__ . "\n";
	}

	public static function test () {
		static::getClassName();
	}

}

class Son_1 extends Daddy_1 {

	public static function getClassName () {
		echo __CLASS__ . "\n";
	}

}

Daddy_1::test();//输出Daddy_1
Son_1::test();//输出Son_1
    浑身难受,今天回去得早点儿休息。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值