PHPマニュアルの変数範囲

6904 ワード

前言
PHPマニュアルシリーズの文章は、いくつかのマニュアルの中の面白い評論を選んで翻訳マニュアルカタログを行います:言語参考---変数---変数範囲参考詳細
コメントセクション
  • はいくつかの面白いコードを提出して、クラス関数の中でstatic変数
  • を使用します
    class sample_class
    {
      public function func_having_static_var($x= NULL)
      {
        static $var = 0;
        if ($x === NULL)
        { return $var; }
        $var = $x;
      }
    }
    
    $a = new sample_class();
    $b = new sample_class();
    echo $a->func_having_static_var()."
    "; echo $b->func_having_static_var()."
    "; // this will output (as expected): // 0 // 0 $a->func_having_static_var(3); echo $a->func_having_static_var()."
    "; echo $b->func_having_static_var()."
    "; // this will output: // 3 // 3 // maybe you expected: // 3 // 0 ?> 3.0, , public static , . , static , . , static , : var= $x; } } ?> static , ( ), . public , $instance->$param = $value $instance public $param, , , , php , .
  • javaおよびC++とは異なり、ループブロックおよびifブロック文の変数は、ブロック外で
  • にアクセスできる.
    for($j=0;$j<3;$j++)
    {
         if($j == 1)
            $a = 4;
    }
    echo $a;  //   4
    
  • ネスト関数の場合、globalは常に最外層のグローバル変数を示すが、前の層の範囲を指すのではなく、以下のように予想される出力
  • に従わない.
    // $var1 is not declared in the global scope
    function a($var1){
        function b(){
            global $var1;
            echo $var1; // there is no var1 in the global scope so nothing to echo
        }
        b();
    }
    a('hello');
    
    function a()に$var 1='some'を追加すると、出力結果'some'が得られます.
  • 面白いコード
  • を提出しました
    class obj{
        public function __destruct(){
            echo 'destruct';
        }
    }
    
    function foo ()
    {
       global $testvar;
       $localvar = new obj();
       $testvar = &$localvar;
    }
    
    foo ();
    var_dump($testvar);   
    /*
      
    destruct
    NULL
    */
    

    オブジェクト参照は同じ識別子を参照するため、メソッドが終了するとunset($localvar)に相当し、クラスインスタンスを指す他の識別子はないのでdestructを呼び出し、$testvarもunsetに相当し、NULLであり、functionを変更すると次のようになります.
    function foo ()
    {
       global $testvar;
       $localvar = new obj();
       $testvar = $localvar;  //         
    }
    /*
      
    object(obj)#1 (0) {
    }
    destruct
    */
    

    付与値は参照と異なり、付与値はcopyの識別子がクラスインスタンスを指すため、$localvarの解放は$testvarに影響しないため、プログラムの最後にdestructを呼び出すまで具体的な割り当てと参照の違いについては、次を参照してください.http://segmentfault.com/a/1190000002928594

  • クラス内メソッドのstatic変数の使用については、1で述べたように、static変数は
  • の継承をサポートしていないことを指摘する.
    class A {
        function Z() {
            static $count =0;        
            printf("%s: %d
    ",get_class($this), ++$count); } } class B extends A {} $a = new A(); $b = new B(); $a->Z(); $a->Z(); $b->Z(); $a->Z(); ?> /* : A: 1 A: 2 B: 1 A: 3 */

    クラスAとクラスBは異なる静的変数を用いており,同じ方法を用いてもfunction Zが静的方法であっても結果は同じであることがわかる.
  • ここでは、グローバル$GLOBALS配列を使用するとglobalキーワードを使用するよりも
  • 速くなります.
  • static変数が配列であり、その要素を返すと、その要素の参照
  • が返されます.
    function incr(&$int) {
      return $int++;
    }
    
    function return_copyof_scalar() {
      static $v;
      if (!$v)   
        $v = 1;
      return($v); 
    } 
    
    function return_copyof_arrayelement() {
      static $v;
      if (!$v) {
        $v = array();
        $v[0] =1;
      }
      return($v[0]);
    } 
    
    echo "scalar: ".
         incr(return_copyof_scalar()).
         incr(return_copyof_scalar()).
         "
    "; echo "arrayelement: ". incr(return_copyof_arrayelement()). incr(return_copyof_arrayelement()). "
    "; ?> /* : scalar:11 array element:11 */ /* : scalar:11 array emelent:12 */

    しかしphp 7で同じテストを行ったところ、所望の出力と同じ結果が得られたため、ここの配列要素は参照に従って返されず、参照を使用する場合は&functionのように関数を宣言し、&functionのように呼び出す必要があるが、incr(return_copyof_scalar()のようにパラメータとして呼び出す場合、例外がある.&を追加する必要はありません.このように、上記の例の関数宣言部分でそれぞれ追加するだけで、出力結果が得られます.
    scalar:12
    array element:12
    
  • 他の複数の関数で同じstaticにアクセスする必要がある場合があります.同時に、このstaticの可視範囲も非グローバルです.ここでは、この問題を解決する簡単な方法があります.
  •   // We need a way to get a reference of our static
      function &getStatic() {
        static $staticVar;
        return $staticVar;
      }
      // Now we can access the static in any method by using it's reference
      function fooCount() {
        $ref2static = & getStatic();
        echo $ref2static++;
      }
      fooCount(); // 0
      fooCount(); // 1
      fooCount(); // 2
    
  • メソッドのstaticを入力された参照パラメータに関連付けることはできませんが、配列の形式で参照を保存して操作
  • を実行できます.
    function test($arr = null){
        static $my;
        if(!$arr)return $my[0];
        $my = $arr;
    }
    
    $you = 'hello';
    test(array(&$you));
    $you = 'world';
    var_dump(test());
    /*
      
    world
    */
    
  • includeによって取り込まれたfileがreturnを使用してvalueを返しても、includeのファイル内の同名valueと同じアクセス範囲
  • を維持します.
    $foo = 'aaa';
    $bar = include('include.php');
    echo($foo.' / '.$bar);
    
    // include.php
    $foo = 'bbb';
    return $foo;
    
    /*
        :aaa/bbb
        :bbb/bbb
    */
    
  • 比較的興味深いコード
  •   class A
       {
         function __destruct()
          {
            global $g_Obj;
            echo "
    #step 2: "; var_dump($g_Obj); } function start() { global $g_Obj; echo "
    #step 1: "; var_dump($g_Obj); } }; $g_Obj = new A(); // start here $g_Obj->start(); ?> /* #step 1: object(A)#1 (0) { } #step 2: object(A)#1 (0) { } */

    以上から分かるように、__destruct()は、実行が完了した後にクラスインスタンスを破棄する.
  • ネスト関数は、繰り返し宣言および最初の宣言
  • に注意する必要があります.
    function norm($a, $b) {
        static $first_time = true;
        if($first_time) {
            function square($x)
            {
                return $x * $x;
            }
            $first_time = false;
        }
        return sqrt(square($a) + square($b));
    }
    
    print norm(5,4);
    print square(4);
    print norm(6,5);
    

    この例では、functionの判定文if($first_time)を削除すると重複宣言のエラーが発生します.また、文print norm(5,4)の前にsquare関数を呼び出すとundefined functionのエラーになります.外部のnorm関数を1回実行し、外部に内部定義宣言のsquare関数があることを伝えなければなりません.
  • static変数を定義すると、
  • と宣言できます.
    static $var =1; //numbers
    static $var ='strings';
    static $var = array(1,'a',3);//array construct
    

    しかし、このような声明はできません(error)
    static $var = some_function('arg');
    static $var = (some_function('arg'));
    static $var = 2+3;//any expression
    static $var = new object;
    
  • リモートコールphpファイルを使用する場合、リモートファイルの変数はコールファイルで
  • を使用できません.
    // remotefile.php
    $paramVal=10;
    
    // localfile.php
    include "[http://example.com/remotefile.php](http://example.com/remotefile.php)";
    echo "remote-value= $paramVal";   //        
    

    ここで言うと、私は自分でテストしたことがありません.自分で頭を回して真偽をテストする必要があります.