首頁 >後端開發 >PHP問題 >php方法中的靜態變數是什麼

php方法中的靜態變數是什麼

藏色散人
藏色散人原創
2021-10-25 09:31:324342瀏覽

php中的靜態變數只存在於函數作用域內,也就是說,靜態變數只存活在堆疊中;在PHP只要在變數前面加上關鍵字static,變數就變成靜態變數了。

php方法中的靜態變數是什麼

本文操作環境:Windows7系統、PHP7.1版、DELL G3電腦

php方法中的靜態變數是什麼?

PHP中的靜態變數及static靜態變數使用詳解

靜態變數只存在於函數作用域內,也就是說,靜態變數只存活在堆疊中。一般的函數內變數在函數結束後會釋放,例如局部變量,但是靜態變數卻不會。是說,下次再呼叫這個函數的時候,該變數的值會保留下來。

#只要在變數前面加上關鍵字static,變數就變成靜態變數了。

<?php
  function test()
  {
    static $nm = ;
    $nm = $nm * ;
    print $nm."<br />";
  }
  // 第一次执行,$nm = 
  test();
  // 第一次执行,$nm = 
  test();
  // 第一次执行,$nm = 
  test();
?>

程式運行結果:
1
2
2
4
3
8

函數test( )執行後,變數$nm的值都保存了下來。

在class中常使用到靜態屬性,例如靜態成員、靜態方法。

Program List:類別的靜態成員

靜態變數$nm屬於類別nowamagic,而不是類別的某個實例。這個變數對所有實例都有效。

::是作用域限定運算符,這裡用的是self作用域,而不是$this作用域,$this作用域只表示類別的目前實例,self::表示的是類別本身。

<?php
  class nowamagic
  {
    public static $nm = ;
    function nmMethod()
    {
      self::$nm += ;
      echo self::$nm . &#39;<br />&#39;;
    }
  }
  $nmInstance = new nowamagic();
  $nmInstance -> nmMethod();
  $nmInstance = new nowamagic();
  $nmInstance -> nmMethod();
?>

程式執行結果:
1
3
2
5

Program List:靜態屬性

<?php
  class NowaMagic
  {
    public static $nm = &#39;www.nowamagic.net&#39;;
    public function nmMethod()
    {
      return self::$nm;
    }
  }
  class Article extends NowaMagic
  {
    public function articleMethod()
    {
      return parent::$nm;
    }
  }
  // 通过作用于限定操作符访问静态变量
  print NowaMagic::$nm . "<br />";
  // 调用类的方法
  $nowamagic = new NowaMagic();
  print $nowamagic->nmMethod() . "<br />";
  print Article::$nm . "<br />";
  $nmArticle = new Article();
  print $nmArticle->nmMethod() . "<br />";
?>

程式運行結果:

www.nowamagic.net
www.nowamagic.net
www.nowamagic.net
www.nowamagic.net

Program List:簡單的靜態建構器

PHP沒有靜態建構​​器,你可能需要初始化靜態類,有一個很簡單的方法,在類別定義後面直接呼叫類別的Demonstration()方法。

<?php
function Demonstration()
{
  return &#39;This is the result of demonstration()&#39;;
}
class MyStaticClass
{
  //public static $MyStaticVar = Demonstration(); //!!! FAILS: syntax error
  public static $MyStaticVar = null;
  public static function MyStaticInit()
  {
    //this is the static constructor
    //because in a function, everything is allowed, including initializing using other functions
    self::$MyStaticVar = Demonstration();
  }
} MyStaticClass::MyStaticInit(); //Call the static constructor
echo MyStaticClass::$MyStaticVar;
//This is the result of demonstration()
?>

程式運行結果:

This is the result of demonstration()

下面要介紹PHP靜態變數static的使用介紹

static關鍵字在C#程式設計中非常常見,它用來修飾符宣告屬於類型本身而不是屬於特定物件的靜態成員。 static 修飾符可用於類別、欄位、方法、屬性、運算子、事件和建構函數,但不能用於索引器、析構函數或類別以外的類型。宣告為static的類別、函數和變數將不能引用實例方法或變量,另外在C#中一旦類別被添加了static修飾符,則其內部所有變數和方法都必須是靜態的。靜態變數和方法必須透過類別名稱進行引用而不能透過實例物件引用。

那麼static關鍵字在php中與C#都有些不同呢?

聲明範圍

相對C#來說,PHP中static變數的使用範圍要更廣一些,我們不僅可以在類,方法或變數前面加上static修飾符,甚至還能為函數內部變數新增static關鍵字。新增了static修飾符的變數即使在該函數執行完畢值仍然不會遺失,也就是說,在下次呼叫這個函數時,變數仍然記得原來的值。如:

<?php
function test()
{
  static $var=;
  $var+=;
  echo $var.&#39; &#39;;
}
test();
test();
test();
?>

運行結果如下:

3 5 7

這裡有一點要注意的是,變數的賦值運算只會在變數第一次初始化時會被調用,在之後函數的執行過程中,這個操作不會被調用。

由於PHP中函數同樣是一等公民,所以不同於C#,我們可以直接定義函數,並直接在程式碼的任何地方調用,這一點跟javascript倒是有些相似。因此這時候函數靜態變數會比定義全域變數更有用,它可以避免變數重複定義導致衝突。而由於C#中函數無法直接定義和調用,它必須寄宿在類別中,所以如果函數需要靜態變量,我們只需要在類別中定義便能達到相同效果。

呼叫方式

C#中,我們呼叫靜態成員的方式非常簡單和一致,因為靜態成員不屬於實例對象,所以無論是方法還是變量,C#對其靜態成員的存取方式一律是透過類別名稱.方法(變數)進行。且在C#中,靜態函數是不能被設定為虛方法或覆蓋的。而PHP對此提供了更為靈活多樣的支援。

首先,我們知道PHP中調用實例方法都是透過如:someobj->someFun()調用,那麼我們調用靜態函數是否也能像C#那樣透過SomeClass->someFun()調用呢?答案是否定的,在PHP中,對靜態成員的呼叫只能透過::的方式進行,如:SomeClass::someFun()。

<?php
class TestC
{
  public static $var=;
  public $var=;
  function t()
  {
    self::$var+=;
    echo self::$var.&#39; &#39;;
    echo $this->var.&#39; &#39;;
  }
  public static function t()
  {
    self::$var+=;
    echo self::$var.&#39; &#39;;
  }
}
$t=new TestC();
$t->t();
TestC::t();
?>

運行結果如下:

3 1 5

#另外一點和C#中不同的是,在類別中的方法中,如果我們需要呼叫靜態變量,必須透過self::$somVar靜態變數(注意變數前面的$符號,實例變數不需要),而呼叫靜態方法則為self::someFun()(這裡不需要$符號)。如上例。

另外,与C#最大的不同之处就是,PHP中,子类是可以覆盖父类的静态函数或变量的,不仅如此,(站在C#程序员的角度来看,我觉得PHP这点反而将事情搞复杂了),由于默认self::staticFun()调用的是子类的静态函数,这个时候如果我们想调用父类的静态变量怎么办呢?这里PHP提供了额外的parent来调用基类的静态成员。如:

<?php
class TestC
{
  public static $var=;
  public $var=;
  function t()
  {
    self::$var+=;
    echo self::$var.&#39; &#39;;
    echo $this->var.&#39; &#39;;
  }
  public static function t()
  {
    self::$var+=;
    echo self::$var.&#39; &#39;;
  }
}
$t=new TestC();
$t->t();
TestC::t();
?>

运行结果如下:

3 5 ‘Hello'

最好,根据上面的例子我们很容易想到,子类访问父类可以使用parent关键字,那么父类如何访问子类的静态方法呢?这里给出static的另外一个用法,这里如果将调用的静态方法前面的作用域换成static的话,PHP会根据该类的继承层次来计算最终的静态方法。如:

<?php
class Test
{
  function t()
  {
    static::t();
  }
  public static function t()
  {
    echo self::&#39;Test &#39;;
  }
}
class Test extends Test
{
  static function t()
  {
    echo self::&#39;Test &#39;;
  }
}
$t=new Test();
$t->t();
Test::t();
?>

运行结果如下:

Test2 Test2

这里t实例在t1方法调用t2静态方法时,会根据其实例找到最终的静态方法并输出Test2。

总结

从上面的分析,我们不难看出,对于静态成员的使用,PHP提供了比C#更为强大的功能或灵活性,但从我的角度来看,这种灵活性不见得就更好,从某种角度来看,如果类的继承层次过于复杂,它可能会让我产生混淆。当然,同样的工具不同人使用效果会完全不一样,既然PHP提供了更多样的选择,那么相信如果使用恰当的话,PHP中的static可能会提供比C#中更为强大而简便的使用方式。

推荐学习:《PHP视频教程

以上是php方法中的靜態變數是什麼的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn