PHP static static 詳細説明

序文

クラスがインスタンス化された後、PHP クラス プロパティとメソッドの両方を呼び出す必要があります (定数プロパティを除く)。ただし、PHP には静的プロパティと静的メソッドも用意されています。いわゆる「静的」とは、クラスをインスタンス化せずに直接呼び出すことができることを意味します。これらのプロパティとメソッド。静的クラスはインスタンス化が不可能ではありませんが、インスタンス化せずに使用できます。

静的メンバーの定義

static キーワードを使用して、クラスのプロパティとメソッドを変更し、これらのプロパティとメソッドを静的プロパティと静的メソッドを呼び出します。

1.静的属性

文法:

static 属性名

例:

<?php
class Foo {
  public static $my_static = 'hello';  
}
?>

2.静的メソッド

文法:

static function 方法名{
    //代码
}

例:

<?php
class Foo {
  public static function staticValue() {
     return 'hello';
  }
}
?>

注: オブジェクトのプロパティやメソッドと同様に、静的プロパティとメソッドは、3 つの可視性レベルの設定をサポートしprivateますprotectedpublic

静的メンバー呼び出し

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.非静的メソッドで静的プロパティ/メソッドを呼び出す

$thisが現在のオブジェクトを指すのと同様に、によって呼び出されると、 self は現在のクラスを指し、インスタンス化されていない場合、ポインタは空のオブジェクトを指すため、静的プロパティとメソッドを参照するために触れることはできません。 self::属性/方法$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

private5. 呼び出しとprotected可視性レベルの静的プロパティ/メソッド

private属性の制限によりprotected、クラス内でしか呼び出せないため、クラス外で呼び出したい場合は、メソッドpublic、メソッドアクセスprivateprotected外部用の属性を用意する必要があります。用語: クラスは、外の世界へのインターフェイスを提供します。

<?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.静的属性

サブクラスは親クラスの static メンバー変数を書き換えることができますが, 親クラスの static 変数はまだ存在します. これら 2 つの static メンバー変数は独立しています. それらは呼び出しのクラス名に従って別々にアクセスされます.

<?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__でき、 getClassName2 つのクラスのメソッドをそれぞれ呼び出します。

結果:

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

サブクラス名ではなく、2 番目の出力の結果が親クラスMystatic1Mystatic2? これは、$thisポインターが常にそれを保持している参照オブジェクトを指しているが、を指しselfいないためです. この問題を解決するために、PHP 5.3 から、遅延静的バインディングと呼ばれる新しい機能が追加されました.定义时持有它的类调用时的类

遅延静的バインディング

Late Static Bindings (Late Static Bindings) は、静的メソッドの呼び出しを目的としています. この機能を使用する場合は、 を介して静的メソッド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->オブジェクトを介してのみ呼び出すことができます (呼び出し)。

  • クラスのすべてのインスタンス オブジェクトは、クラス内の静的プロパティを共有します。このクラスの静的プロパティが変更された場合、このクラスのすべてのオブジェクトがこの新しい値にアクセスできます。

  • 静的メソッドと静的プロパティのライフ サイクルは、対応するクラスと同じくらい長く、静的メソッドと静的プロパティは、クラスの定義と共に割り当てられ、メモリに読み込まれます。静的プロパティとメソッドは、スレッドが終了するまで破棄されません。非静的メソッドとプロパティのライフサイクルは、クラスのインスタンス化されたオブジェクトと同じです. クラスがオブジェクトをインスタンス化する場合にのみ、非静的メソッドとプロパティが作成され、オブジェクトが破棄されると、非静的メソッドとプロパティが作成されます. static メソッドはすぐに破棄されます。静的メソッドと静的変数は、作成後に常に同じメモリ ブロックを使用しますが、インスタンスを使用すると複数のメモリが作成されます。ただし、静的メソッドはインスタンス化よりも効率的です. 静的メソッドの欠点は、インスタンス化されたメソッドが破棄される可能性があるのに対し、自動的に破棄されないことです.

アプリケーション シナリオ:

  1. 静的メソッドは、ファイル操作、日付処理メソッドなどのツール クラスのメソッドの定義に最適です。

  2. 静的変数は、グローバル変数の定義に適しています。

参考リンク:

PHP の静的プロパティと静的メソッド | オブジェクト指向プログラミング | 実戦チュートリアルへの PHP 入門

https://www.jb51.net/article/110708.htm

PHP クラスのひみつ (4) 静的プロパティと静的メソッド - ナゲット

静的メソッドと非静的メソッドの違い - kittyUncle - 博客园

おすすめ

転載: blog.csdn.net/WHQ556677/article/details/122356593