PHPマニュアルの変数範囲
6904 ワード
前言
PHPマニュアルシリーズの文章は、いくつかのマニュアルの中の面白い評論を選んで翻訳マニュアルカタログを行います:言語参考---変数---変数範囲参考詳細
コメントセクションはいくつかの面白いコードを提出して、クラス関数の中でstatic変数 を使用します javaおよびC++とは異なり、ループブロックおよびifブロック文の変数は、ブロック外で にアクセスできる.ネスト関数の場合、globalは常に最外層のグローバル変数を示すが、前の層の範囲を指すのではなく、以下のように予想される出力 に従わない.面白いコード を提出しました
オブジェクト参照は同じ識別子を参照するため、メソッドが終了するとunset($localvar)に相当し、クラスインスタンスを指す他の識別子はないのでdestructを呼び出し、$testvarもunsetに相当し、NULLであり、functionを変更すると次のようになります.
付与値は参照と異なり、付与値はcopyの識別子がクラスインスタンスを指すため、$localvarの解放は$testvarに影響しないため、プログラムの最後にdestructを呼び出すまで具体的な割り当てと参照の違いについては、次を参照してください.http://segmentfault.com/a/1190000002928594
クラス内メソッドのstatic変数の使用については、1で述べたように、static変数は の継承をサポートしていないことを指摘する.
クラスAとクラスBは異なる静的変数を用いており,同じ方法を用いてもfunction Zが静的方法であっても結果は同じであることがわかる.ここでは、グローバル$GLOBALS配列を使用するとglobalキーワードを使用するよりも 速くなります. static変数が配列であり、その要素を返すと、その要素の参照 が返されます.
しかしphp 7で同じテストを行ったところ、所望の出力と同じ結果が得られたため、ここの配列要素は参照に従って返されず、参照を使用する場合は&functionのように関数を宣言し、&functionのように呼び出す必要があるが、incr(return_copyof_scalar()のようにパラメータとして呼び出す場合、例外がある.&を追加する必要はありません.このように、上記の例の関数宣言部分でそれぞれ追加するだけで、出力結果が得られます.他の複数の関数で同じstaticにアクセスする必要がある場合があります.同時に、このstaticの可視範囲も非グローバルです.ここでは、この問題を解決する簡単な方法があります. メソッドのstaticを入力された参照パラメータに関連付けることはできませんが、配列の形式で参照を保存して操作 を実行できます. includeによって取り込まれたfileがreturnを使用してvalueを返しても、includeのファイル内の同名valueと同じアクセス範囲 を維持します.比較的興味深いコード
以上から分かるように、ネスト関数は、繰り返し宣言および最初の宣言 に注意する必要があります.
この例では、functionの判定文if($first_time)を削除すると重複宣言のエラーが発生します.また、文print norm(5,4)の前にsquare関数を呼び出すとundefined functionのエラーになります.外部のnorm関数を1回実行し、外部に内部定義宣言のsquare関数があることを伝えなければなりません. static変数を定義すると、 と宣言できます.
しかし、このような声明はできません(error)リモートコールphpファイルを使用する場合、リモートファイルの変数はコールファイルで を使用できません.
ここで言うと、私は自分でテストしたことがありません.自分で頭を回して真偽をテストする必要があります.
PHPマニュアルシリーズの文章は、いくつかのマニュアルの中の面白い評論を選んで翻訳マニュアルカタログを行います:言語参考---変数---変数範囲参考詳細
コメントセクション
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 , .
for($j=0;$j<3;$j++)
{
if($j == 1)
$a = 4;
}
echo $a; // 4
// $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
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が静的方法であっても結果は同じであることがわかる.
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
// 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
function test($arr = null){
static $my;
if(!$arr)return $my[0];
$my = $arr;
}
$you = 'hello';
test(array(&$you));
$you = 'world';
var_dump(test());
/*
world
*/
$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 $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;
// remotefile.php
$paramVal=10;
// localfile.php
include "[http://example.com/remotefile.php](http://example.com/remotefile.php)";
echo "remote-value= $paramVal"; //
ここで言うと、私は自分でテストしたことがありません.自分で頭を回して真偽をテストする必要があります.