phpにおける静的変数と動的変数の違い--フレームワークに変数をロードする際の運用
5477 ワード
静的変数:
例:
staticキーワードは、次のように使用される1つ以上の変数を宣言します.
function t() {static $i = 0;$i++;echo $i, ;}t();t();t();上のプログラムは1 2 3を出力します.この例から、$i変数は他の局所変数とは独立していることがわかる.
単例モードでの静的変数の運用:
例:
例:静的変数と静的メソッドのライフサイクル
動的変数と静的変数の違い:
1、保管場所
動的変数:メモリアウトスタックデータ領域に格納
静的変数:グローバルデータ領域(静的データ領域)に格納
2、寿命
動的変数:定義した位置に基づいて決定します.たとえば、関数で定義した場合、その関数の範囲を超える変数は失効します.
静的変数:プログラムの終了時にリリースされます.
3、作用域
動的変数:2番目のポイントと同じように、定義した位置に基づいて決定されます.
静的変数:現在のファイルで有効
スタックとスタックの区別:
ヒープスタック
1、メモリの分配方面:
ヒープ:一般的にはプログラマーによってリリースが割り当てられ、プログラマーがリリースしない場合は、プログラム終了時にOSによって回収される可能性があります.データ構造のスタックとは異なり、割り当て方法はチェーンテーブルに似ていることに注意してください.使用可能なキーワードは、new、malloc、delete、freeなどです.
スタック:コンパイラ(Compiler)によって自動的に割り当てられて解放され、関数のパラメータ値、ローカル変数の値などが格納されます.その動作は、データ構造内のスタックに似ています.
2、申請方式方面:
ヒープ:プログラマーが自分で申請し、サイズを指定する必要があります.cにおけるmalloc関数、例えばp 1=(char*)malloc(10);C++ではnew演算子を使用しますが、p 1、p 2自体はスタック内にあることに注意してください.局所変数と考えられるからです
スタック:システムによって自動的に割り当てられます.例えば、関数内の局所変数int bを宣言する.システムは自動的にスタックの中でbのために空間を開く.
3、システム応答方面:
ヒープ:オペレーティングシステムには空きメモリアドレスを記録するチェーンテーブルがあり、システムがプログラムの申請を受け取ると、そのチェーンテーブルを巡り、申請した空間よりも大きな最初の空間のヒープノードを探し、その後、そのノードを空きノードチェーンテーブルから削除し、そのノードの空間をプログラムに割り当てます.また、多くのシステムでは、このメモリ領域の最初のアドレスに今回の割り当てのサイズが記録され、コードのdelete文がこのメモリ領域を正しく解放することができます.また、見つかったスタックポイントのサイズが申請のサイズに等しいとは限らないため、余分な部分を自動的に空きチェーンテーブルに再配置します.
スタック:スタックの残りの領域が申請された領域より大きい場合、システムはプログラムにメモリを提供します.そうしないと、例外プロンプトスタックがオーバーフローします.
4、サイズ制限の面:
ヒープ:高アドレスに拡張されたデータ構造で、不連続なメモリ領域です.これは,システムがチェーンテーブルで格納する空きメモリアドレスであるため,当然不連続であり,チェーンテーブルの遍歴方向は低アドレスから高アドレスである.スタックのサイズは、コンピュータシステムで有効な仮想メモリに制限されます.このことから,スタックが得られる空間は比較的柔軟であり,比較的大きいことが分かる.
スタック:Windowsの下で、スタックは低アドレスに拡張されたデータ構造で、連続したメモリの領域です.スタックトップのアドレスとスタックの最大容量はシステムで予め定められており、WINDOWSではスタックの大きさは固定(コンパイル時に決定される定数)であり、申請された空間がスタックの余剰空間を超えるとoverflowが提示される.したがって、スタックから得られる空間は小さい.
5、効率方面:
ヒープ:newによって割り当てられたメモリで、一般的に速度が遅く、メモリの破片が発生しやすいが、最も便利である.また、WINDOWSでは、VirtualAllocでメモリを割り当てるのが最善の方法である.彼はヒープではなく、スタックではなく、プロセスのアドレスの空き間に直接メモリを残すのではなく、最も不便であるが.しかし、スピードが速く、最も柔軟です.
スタック:システムによって自動的に割り当てられ、速度が速い.しかし、プログラマーはコントロールできません.
6、保存内容:
ヒープ:通常、ヒープのヘッダにヒープのサイズを1バイトで格納します.スタックの具体的な内容はプログラマーが手配します.
スタック:関数呼び出し時に最初にスタックされたのは、メイン関数の次の命令です.(関数呼び出し文の次の実行可能文)のアドレスは、関数の各パラメータです.ほとんどのCコンパイラでは、パラメータは右から左へスタックに入り、関数のローカル変数になります.注意:静的変数はスタックに入りません.今回の関数呼び出しが終了すると、ローカル変数はスタックを出てからパラメータになり、最後にスタックトップポインタは最初に保存された場所を指します.アドレス、すなわちメイン関数の次の命令で、プログラムはその点で実行されます.
7、アクセス効率方面:
ヒープ:char*s 1=“Hellow Word”;コンパイル時に確定したものです.
スタック:char s 1[]=「Hellow Word」;実行時に付与されます.ポインタを使用するよりも配列を使用するほうが速いです.ポインタは最下位アセンブリでedxレジスタで中継する必要があり、配列はスタックで直接読み出す必要があります.
, , , , 。 php javascript 。
:
,PHP
, , 。
, , , 。
。 。 , , , 。 , 。 , 。 static ,
例:
staticキーワードは、次のように使用される1つ以上の変数を宣言します.
function t() {static $i = 0;$i++;echo $i, ;}t();t();t();上のプログラムは1 2 3を出力します.この例から、$i変数は他の局所変数とは独立していることがわかる.
: . , , , 。
単例モードでの静的変数の運用:
: new , new
: PHP , , , , , , PHP , PHP
例:
class A
{
private static $instance = null;
private $b = 1;
private function __construct()
{
//Code in this function
//could not be get out of the class
}
public static function get_instance()
{
if(self::$instance == null){
$classname = __CLASS__;
self::$instance = new $classname();
}
return self::$instance;
}
public function add()
{
$this->b++;
}
public function show()
{
echo $this->b;
}
}
$a = A::get_instance();
$b = A::get_instance();
// $a $b !
$a->add();
$a->show();
echo '<br />';
$b->show();
//output
//2
//2
例:静的変数と静的メソッドのライフサイクル
<?php
class User
{
static private $counter = 1;
public function __construct()
{
self::$counter++;
}
static public function getCount()
{
return self::$counter;
}
public function __destruct()
{
self::$counter--;
}
}
echo 'run static getCount:'.User::getCount().'<br>';
$user1 = new User();
$user2 = new User();
echo 'run user1 getCount:'.$user1->getCount().'<br>';
unset($user1);
echo 'run user2 getCount:'.$user2->getCount();
?>
:
run static getCount:1
run user1 getCount:3
run user2 getCount:2
:
1、 , new ;
2、 unset , 。
, , , , , 。
apache , apahce 。
: , ( ) 。
動的変数と静的変数の違い:
1、保管場所
動的変数:メモリアウトスタックデータ領域に格納
静的変数:グローバルデータ領域(静的データ領域)に格納
2、寿命
動的変数:定義した位置に基づいて決定します.たとえば、関数で定義した場合、その関数の範囲を超える変数は失効します.
静的変数:プログラムの終了時にリリースされます.
3、作用域
動的変数:2番目のポイントと同じように、定義した位置に基づいて決定されます.
静的変数:現在のファイルで有効
スタックとスタックの区別:
ヒープスタック
1、メモリの分配方面:
ヒープ:一般的にはプログラマーによってリリースが割り当てられ、プログラマーがリリースしない場合は、プログラム終了時にOSによって回収される可能性があります.データ構造のスタックとは異なり、割り当て方法はチェーンテーブルに似ていることに注意してください.使用可能なキーワードは、new、malloc、delete、freeなどです.
スタック:コンパイラ(Compiler)によって自動的に割り当てられて解放され、関数のパラメータ値、ローカル変数の値などが格納されます.その動作は、データ構造内のスタックに似ています.
2、申請方式方面:
ヒープ:プログラマーが自分で申請し、サイズを指定する必要があります.cにおけるmalloc関数、例えばp 1=(char*)malloc(10);C++ではnew演算子を使用しますが、p 1、p 2自体はスタック内にあることに注意してください.局所変数と考えられるからです
スタック:システムによって自動的に割り当てられます.例えば、関数内の局所変数int bを宣言する.システムは自動的にスタックの中でbのために空間を開く.
3、システム応答方面:
ヒープ:オペレーティングシステムには空きメモリアドレスを記録するチェーンテーブルがあり、システムがプログラムの申請を受け取ると、そのチェーンテーブルを巡り、申請した空間よりも大きな最初の空間のヒープノードを探し、その後、そのノードを空きノードチェーンテーブルから削除し、そのノードの空間をプログラムに割り当てます.また、多くのシステムでは、このメモリ領域の最初のアドレスに今回の割り当てのサイズが記録され、コードのdelete文がこのメモリ領域を正しく解放することができます.また、見つかったスタックポイントのサイズが申請のサイズに等しいとは限らないため、余分な部分を自動的に空きチェーンテーブルに再配置します.
スタック:スタックの残りの領域が申請された領域より大きい場合、システムはプログラムにメモリを提供します.そうしないと、例外プロンプトスタックがオーバーフローします.
4、サイズ制限の面:
ヒープ:高アドレスに拡張されたデータ構造で、不連続なメモリ領域です.これは,システムがチェーンテーブルで格納する空きメモリアドレスであるため,当然不連続であり,チェーンテーブルの遍歴方向は低アドレスから高アドレスである.スタックのサイズは、コンピュータシステムで有効な仮想メモリに制限されます.このことから,スタックが得られる空間は比較的柔軟であり,比較的大きいことが分かる.
スタック:Windowsの下で、スタックは低アドレスに拡張されたデータ構造で、連続したメモリの領域です.スタックトップのアドレスとスタックの最大容量はシステムで予め定められており、WINDOWSではスタックの大きさは固定(コンパイル時に決定される定数)であり、申請された空間がスタックの余剰空間を超えるとoverflowが提示される.したがって、スタックから得られる空間は小さい.
5、効率方面:
ヒープ:newによって割り当てられたメモリで、一般的に速度が遅く、メモリの破片が発生しやすいが、最も便利である.また、WINDOWSでは、VirtualAllocでメモリを割り当てるのが最善の方法である.彼はヒープではなく、スタックではなく、プロセスのアドレスの空き間に直接メモリを残すのではなく、最も不便であるが.しかし、スピードが速く、最も柔軟です.
スタック:システムによって自動的に割り当てられ、速度が速い.しかし、プログラマーはコントロールできません.
6、保存内容:
ヒープ:通常、ヒープのヘッダにヒープのサイズを1バイトで格納します.スタックの具体的な内容はプログラマーが手配します.
スタック:関数呼び出し時に最初にスタックされたのは、メイン関数の次の命令です.(関数呼び出し文の次の実行可能文)のアドレスは、関数の各パラメータです.ほとんどのCコンパイラでは、パラメータは右から左へスタックに入り、関数のローカル変数になります.注意:静的変数はスタックに入りません.今回の関数呼び出しが終了すると、ローカル変数はスタックを出てからパラメータになり、最後にスタックトップポインタは最初に保存された場所を指します.アドレス、すなわちメイン関数の次の命令で、プログラムはその点で実行されます.
7、アクセス効率方面:
ヒープ:char*s 1=“Hellow Word”;コンパイル時に確定したものです.
スタック:char s 1[]=「Hellow Word」;実行時に付与されます.ポインタを使用するよりも配列を使用するほうが速いです.ポインタは最下位アセンブリでedxレジスタで中継する必要があり、配列はスタックで直接読み出す必要があります.