php的static静态方法是什么
时间:2022-10-31 09:40
php static静态方法中的“静态”指的是无需对类进行实例化,就可以直接调用这些属性和方法;而static就是一个关键字,用来修饰类的属性及方法,其使用语法如“class Foo {public static $my_static = 'hello';}”。 本教程操作环境:windows7系统、PHP8.1版、Dell G3电脑。 PHP static静态详解 PHP 类属性和方法都需要在类实例化后才能调用(常量属性除外),但是,PHP 还提供了静态属性和静态方法,所谓「静态」指的是无需对类进行实例化,就可以直接调用这些属性和方法。静态类不是不可以实例化,而是不需要实例化就可以用。 用static关键字来修饰类的属性、方法,称这些属性、方法为静态属性、静态方法。 语法: 实例: 语法: 实例: 注:静态属性和方法与对象属性和方法一样,支持设置 通过 注:预定义常量 结果: 通过 结果: 通过 结果: 通过 结果: 与在非静态方法中调用静态属性/方法一样。 结果: 如果在一个类中调用其他类的静态属性和方法,需要通过 结果: 由于 结果: 在实际应用中会有一个类的多个对象,可能会共享一份数据。类常量和静态属性都可以实现。静态属性与类常量相似(相同),唯一的区分是类常量不可以更改,静态属性可以更改。访问方法是一样的,都可以使用 结果: 结果: 和非静态属性/方法一样,静态属性和方法也可以被子类继承,静态属性和方法还可以被子类重写。 子类可以重写父类的静态成员变量, 但父类的静态变量依然存在, 这两个静态成员变量是独立的. 会根据调用的类名分别进行访问。 结果: 子类可以重写父类的静态方法。 通过 结果: 说明子类重写了父类的同名静态方法,同样我们在子类上也可以调用父类中的 结果: 为什么第二个打印的结果是父类名 延迟静态绑定(Late Static Bindings)针对的是静态方法的调用,使用该特性时不再通过 结果: 表明后期静态绑定生效,即 此外,还可以通过 结果: 同理, 静态属性和方法可以直接通过类引用,所以又被称作类属性和类方法。非静态属性和非静态方法需要实例化后通过对象引用,因此被称作对象属性和对象方法。 静态属性保存在类空间,非静态属性保存在对象空间。非静态方法可以访问类中的任何成员(包括静态),静态方法只能访问类中的静态成员。 静态方法可以直接调用,类名调用和对象调用( 一个类的所有实例对象,共用类中的静态属性。如果修改了这个类静态属性,那么这个类的所有对象都能访问到这个新值。 静态方法和属性的生命周期跟相应的类一样长,静态方法和静态属性会随着类的定义而被分配和装载入内存中。一直到线程结束,静态属性和方法才会被销毁。 非静态方法和属性的生命周期和类的实例化对象一样长,只有当类实例化了一个对象,非静态方法和属性才会被创建,而当这个对象被销毁时,非静态方法也马上被销毁。静态方法和静态变量创建后始终使用同一块内存,而使用实例的方式会创建多个内存。但静态方法效率上要比实例化高,静态方法的缺点是不自动进行销毁,而实例化的则可以做销毁。 静态方法最适合工具类中方法的定义;比如文件操作,日期处理方法等. 静态变量适合全局变量的定义. 推荐学习:《PHP视频教程》 以上就是php的static静态方法是什么的详细内容,更多请关注gxlsystem.com其它相关文章!静态成员的定义
1、静态属性
static 属性名
<?php
class Foo {
public static $my_static = 'hello';
}
?>
2、静态方法
static function 方法名{
//代码
}
<?php
class Foo {
public static function staticValue() {
return 'hello';
}
}
?>
private
、protected
、public
三种可见性级别。静态成员的调用
1、在类外调用静态属性/方法
类名::属性/方法
的方式调用。<?php
class Mystatic {
public static $staticvalue = 'zhangsan';
public static function staticMethod() {
$a = 'hello';
return $a;
}
}
echo '$staticvalue: '.Mystatic::$staticvalue.PHP_EOL;
echo '$a: '.Mystatic::staticMethod().PHP_EOL;
?>
PHP_EOL
表示系统换行符。$staticvalue: zhangsan
$a: hello
对象名::属性/方法
的方式调用。<?php
class Mystatic {
public static $staticvalue = 'zhangsan';
public static function staticMethod() {
$a = 'hello';
return $a;
}
}
$obj = new Mystatic();
echo '$staticvalue: '.$obj::$staticvalue.PHP_EOL;
echo '$a: '.$obj::staticMethod();
?>
$staticvalue: zhangsan
$a: hello
对象名 -> 方法
调用、对象名 -> 属性
会失败。<?php
error_reporting(0);
class Mystatic {
public static $staticvalue = 'zhangsan';
public static function staticMethod() {
$a = 'hello';
return $a;
}
}
$obj = new Mystatic();
echo '$staticvalue: '.$obj -> staticvalue.PHP_EOL;
echo '$a: '.$obj -> staticMethod();
?>
$staticvalue:
$a: hello
2、在非静态方法中调用静态属性/方法
self::属性/方法
的方式调用,self 指向当前类,就像 $this 指向当前对象一样;而在没有实例化的情况下,$this
指针指向的是空对象,所以不能动过它引用静态属性和方法。<?php
class Mystatic {
public static $staticvalue = 'zhangsan';
public static function staticMethod() {
$a = 'hello';
return $a;
}
public function noStatic(){
echo '$staticvalue: '.self::$staticvalue.PHP_EOL;
echo '$a: '.self::staticMethod();
}
}
$obj = new Mystatic();
$obj -> noStatic();
?>
$staticvalue: zhangsan
$a: hello
3、在静态方法中调用静态属性/方法
<?php
class Mystatic {
public static $staticvalue = 'zhangsan';
public static function staticMethod1() {
$a = 'hello';
return $a;
}
public static function staticMethod2(){
echo '$staticvalue: '.self::$staticvalue.PHP_EOL;
echo '$a: '.self::staticMethod1().PHP_EOL;
}
}
Mystatic::staticMethod2();
$obj = new Mystatic();
$obj -> staticMethod2();
?>
$staticvalue: zhangsan
$a: hello
$staticvalue: zhangsan
$a: hello
4、调用另一个类的静态属性/方法
完整类名::
进行引用。<?php
class Mystatic1 {
public static $staticvalue1 = 'xiaomin';
}
class Mystatic2 {
public static $staticvalue2 = 'zhangsan';
public static function staticMethod() {
echo '$staticvalue1: '.Mystatic1::$staticvalue1.PHP_EOL;
echo '$staticvalue2: '.self::$staticvalue2.PHP_EOL;
}
}
Mystatic2::staticMethod();
$obj = new Mystatic2();
$obj -> staticMethod();
?>
$staticvalue1: xiaomin
$staticvalue2: zhangsan
$staticvalue1: xiaomin
$staticvalue2: zhangsan
5、调用
private
、protected
可见性级别的静态属性/方法private
、protected
属性的限制只在类内调用,想在类外调用,需为外部提供一个public
的方法,方法访问private
、protected
属性。术语:类对外提供接口。<?php
class Mystatic {
public static $staticvalue1 = 'zhangsan';
private static $staticvalue2 = 20;
protected static $staticvalue3 = 'student';
private static function staticMethod() {
$a = 'hello';
return $a;
}
public function port1() {
echo '$staticvalue1: '.self::$staticvalue1.PHP_EOL;
echo '$staticvalue2: '.self::$staticvalue2.PHP_EOL;
echo '$staticvalue3: '.self::$staticvalue3.PHP_EOL;
echo '$a: '.self::staticMethod().PHP_EOL;
}
public static function port2() {
echo '$staticvalue1: '.self::$staticvalue1.PHP_EOL;
echo '$staticvalue2: '.self::$staticvalue2.PHP_EOL;
echo '$staticvalue3: '.self::$staticvalue3.PHP_EOL;
echo '$a: '.self::staticMethod().PHP_EOL;
}
}
$obj = new Mystatic();
$obj -> port1();
echo "\r\n";
Mystatic::port2();
?>
$staticvalue1: zhangsan
$staticvalue2: 20
$staticvalue3: student
$a: hello
$staticvalue1: zhangsan
$staticvalue2: 20
$staticvalue3: student
$a: hello
静态属性支持动态修改
::
访问。 静态属性需要加$,常量名前没有$,所以访问类常量时根本不需要加。1、类常量
<?php
class Myconst {
const A = 1234;
}
$obj1 = new Myconst();
echo 'A: '.$obj1::A.PHP_EOL;
$obj1->A='aaa';
//$obj1::A='aaa';会报错
echo "\r\n";
$obj2 = new Myconst();
echo 'A: '.$obj2::A.PHP_EOL;
?>
A: 1234
A: 1234
2、静态属性
<?php
class Mystatic {
public static $A = 1234;
}
echo '$A: '.Mystatic::$A.PHP_EOL;
Mystatic::$A = 6666;
echo '$A: '.Mystatic::$A.PHP_EOL;
$obj1 = new Mystatic();
echo '$A: '.$obj1::$A.PHP_EOL;
Mystatic::$A = 5555;
$obj2 = new Mystatic();
echo '$A: '.$obj2::$A.PHP_EOL;
echo '$A: '.$obj1::$A.PHP_EOL;
?>
$A: 1234
$A: 6666
$A: 6666
$A: 5555
$A: 5555
静态成员的继承和重写
1、静态属性
<?php
class Mystatic
{
static public $a; //定义一个静态变量
static function test() //定义静态方法来操作并输出静态变量
{
self::$a++;
return self::$a;
}
}
class Mystatic2 extends Mystatic //定义一个子类
{
static function test() //定义子类的静态方法
{
self::$a++; //访问并操作父类的静态变量
return self::$a;
}
}
$obj1=new Mystatic; //新建父类对象
echo '此时$a的值为: '.$obj1->test().PHP_EOL; //通过对象调用静态方法test,静态属性$a的值+1
$obj2=new Mystatic; //新建另一个父类对象
echo '此时$a的值为: '.$obj2->test().PHP_EOL; //新父类对象调用静态方法test,静态属性$a的值+1+1
$obj3=new Mystatic2; //新建子类对象
echo '此时$a的值为: '.$obj3->test().PHP_EOL; //子类对象调用同名静态方法test, 静态属性$a的值+1+1+1
echo Mystatic::$a.PHP_EOL; //通过父类::直接访问静态成员$a变量
echo $obj1::$a.PHP_EOL; //通过对象名::可以直接访问静态成员$a变量
?>
此时$a的值为: 1
此时$a的值为: 2
此时$a的值为: 3
3
3
2、静态方法
<?php
class Mystatic1 {
public static function getclassName() {
return __CLASS__;
}
public static function whoclassName() {
echo self::getclassName().PHP_EOL;
}
}
class Mystatic2 extends Mystatic1{
public static function getclassName() {
return __CLASS__;
}
}
echo Mystatic1::getclassName().PHP_EOL;
echo Mystatic2::getclassName().PHP_EOL;
?>
__CLASS__
可以获取当前类的类名,我们分别调用两个类的 getClassName
方法:Mystatic1
Mystatic2
whoclassName
方法:<?php
class Mystatic1 {
public static function getclassName() {
return __CLASS__;
}
public static function whoclassName() {
echo self::getclassName().PHP_EOL;
}
}
class Mystatic2 extends Mystatic1{
public static function getclassName() {
return __CLASS__;
}
}
echo Mystatic1::whoclassName();
echo Mystatic2::whoclassName();
?>
Mystatic1
Mystatic1
Mystatic1
而不是子类名 Mystatic2
?这是因为, $this
指针始终指向持有它的引用对象,而self
指向的是定义时持有它的类
而不是调用时的类
,为了解决这个问题,从 PHP 5.3 开始,新增了一个叫做延迟静态绑定的特性。延迟静态绑定
self::
引用静态方法,而是通过 static::
,如果是在定义它的类中调用,则指向当前类
,此时和 self
功能一样,如果是在子类或者其他类中调用,则指向调用该方法所在的类
。<?php
class Mystatic1 {
public static function getclassName() {
return __CLASS__;
}
public static function whoclassName() {
echo static::getclassName().PHP_EOL;
}
}
class Mystatic2 extends Mystatic1{
//self改为static
public static function getclassName() {
return __CLASS__;
}
}
echo Mystatic1::whoclassName();
echo Mystatic2::whoclassName();
?>
Mystatic1
Mystatic2
static
指向的是调用它的方法所在的类,而不是定义时,所以称之为延迟静态绑定。static::class
来指向当前调用类的类名,例如我们可以通过它来替代 __CLASS__
,这样上述子类就没有必要重写 getClassName
方法了:<?php
class Mystatic1 {
public static function getclassName() {
return static::class;
}
public static function whoclassName() {
echo static::getclassName().PHP_EOL;
}
}
class Mystatic2 extends Mystatic1{}
echo Mystatic1::getclassName().PHP_EOL;
echo Mystatic2::getclassName().PHP_EOL;
echo Mystatic1::whoclassName();
echo Mystatic2::whoclassName();
?>
Mystatic1
Mystatic2
Mystatic1
Mystatic2
self::class
则始终指向的是定义它的类。静态与非静态的区别
类名或self::
调用),但是非静态方法只能通过对象调用(对象名或$this->
调用)。应用场景: