php エイリアス言語構造
今日、友人が Baidu に exit と die の違いについての質問を投稿しました。
中の標準的な答えはおそらく次のことを意味します:
Die は終了してメモリを解放することを意味し、exit は終了するがメモリを解放しないことを意味します。
この説明は明らかに間違っています。私たちは皆、以前にマニュアルを見て、この 2 つは単なる別名であると言いましたが、それ以外はまったく同じです。
しかし、私はまだ興味があったので、PHP がこの「エイリアス」をどのように処理するかを確認するためにソース コードから手がかりを探すことにしました。
まず第一に、die と exit は関数ではなく言語構造であることを明確にする必要があります。多くの初心者は、言語の構造と機能の違いを理解できません。平たく言えば、言語の構造は文法そのものの記号として理解できます。 +、-、*、/ と同様に、これらも言語構造です。if、else、for、while もすべて言語構造です。文法自体の一部です。どの言語にもこれらの要素は含まれます。これは、コンピューターが + を見たときに、それを追加する必要があるとは考えないためです。これには、コンパイラがそれをマシンコード (CPU が認識できる命令セット) に変換する必要があります。
PHP がソース コードを実行するときのプロセス全体は、まずソース コード内の echo や if などの言語構造を、zend_ language_scanner.l で定義されている T_ECHO や T_IF などのトークンに変換し、ソース コード内のスペースを削除します。プログラム ロジックと関係のないこれらの文字をコメント アウトします。 、いくつかの短い式が形成されます。これが字句解析の段階です。これらのトークンは、zend_vm_opcodes.h で定義されている操作コードに変換されます。次に、これらの操作コードを 1 つずつ実行します。
以上がphpのコンパイルと実行のプロセス、および言語構造の定義を大まかに説明しました。本題に入りましょう。
PHP には、implode や join などのエイリアス関数がたくさんあることも覚えておく必要があります。エイリアス関数にしても、エイリアス言語の構造にしても、実際の効果という観点では同じですが、ソースコードの処理方法が決定的に異なります。
まず、このエイリアス言語構造がどのように処理されるかを見てから、後でエイリアス関数を見てみましょう。
zend_ language_parser.c中,定义了一个宏
#define T_EXIT 300
还定义了一个enum,里面也有
enum yytokentype {
...
T_EXIT = 300,
....
}
这里告诉T_EXIT トークンのコードは 300 です。
これらのコード行が含まれている zend_ language_scanner.l を見てください。
"exit" {
return T_EXIT; }
"die" {
return T_EXIT }
明らかに、php が字句解析を行う場合は関係ありません。なんて元はまだ死ぬんだ, T_EXIT トークンが返されます。ここから、die と exit と PHP の内部処理がまったく同じであることが証明できます。
次の PHP コードを使用して決定することもできます:
var_dump(token_get_all(""));
die と exit に対応するトークン コード返された結果はどちらも 300 です。
dieとexitの問題に関しては、すでに確認できています。ここで、別の疑問が生じます。これも私がいつも見落としていた詳細です:
&&、|| は AND、OR と同じですか?
まず告白させてください、私は以前はいつも同じように思っていて、それは純粋な別名の関係だと思っていました。しかし、今日ソースコードを見たところ、それがまったく異なるトークンであることがわかりました。 && と AND を例に挙げます:
または zend_ language_scanner.l
"&&" {
return T_BOOLEAN_AND; }
"AND" {
return T_LOGICAL _そして;
}
1はブール「AND」と呼ばれ、1 つは論理「AND」と呼ばれます
異なるトークンを使用する理由。違いがあるはずです。ここでは販売しません。実際、この 2 つの最も重要な違いは、次のとおりです。
$b = 1 AND 0; $a);
var_dump($b);
前者は最初に 1 && 0 を計算し、結果を取得した後にそれを $a に代入するので、結果は次のようになります。
bool(false) int(1)
さて、ここで誰もが詳細を知っているはずです。使用する際には注意が必要です。
今話したのは言語構造の「エイリアス」ですが、PHP の関数エイリアスはどのように扱われるのでしょうか?
implode と join を例に挙げます。
Basic_function.c には、次の行があります:
PHP_FALIAS(join, implode, arginfo_implode)
この場合、PHP_FAILIAS マクロがその役割を果たすことは明らかです。以下には、ini_set や ini_alter など、エイリアス関係も多数あります。さらに深く掘り下げたい場合は、このマクロをずっと追いかけてください。
php.h 内
#define PHP_FALIAS ZEND_FALIAS
PHP_FALIAS が ZEND_FALIAS を指していることが判明しました
zend_API.h
#define ZEND_FALIAS(name, alias, arg_info) ZEND_FENTRY(name, ZEND_FN(alias), arg_info, 0)
...
#define ZEND_FENTRY(zend_name, name, arg_info, flags) { #zend_name, name, arg_info, (zend_uint) ) (sizeof(arg_info)/sizeof(struct _zend_arg_info)-1), flags },
次のステップは、関数の初期化などであり、エイリアス関数と何が起こっているかもわかります。
ディスカッションへの返信 (解決策)
学習した後、私は exit の使用に慣れています
より多くの知識が得られました
勉強中です
今日は、あるアプリでジョークを見ました
それは php exit と死ぬ
例は子供の出産についてです 例................................................
まず第一に、別名の問題は非常によく知られています。
なお、&& and and については、条件1 && 条件2を使用する場合、条件1が偽の場合、条件2は実行されずに2の計算をするということしか知りませんでしたが、今日本質的な理由が分かりました。
学びました...
まず第一に、エイリアスの問題について多くのことを学びました。
また、&& and and and は、条件 1 && 条件 2 を使用する場合しか知りません。条件 1 が false の場合、条件 2 は実行されず、2 を計算します。今日で本質がわかりました。理由。
いいえ
&& であっても AND であっても、左の式が false と評価されると、右の式は再度評価されません
$i = 0;
1>2 && $i = 1;
------------------
$i = 0;
1>2 AND $i = 1;
echo $i;
これら 2 つのコードの結果は 0 です。この例は、このアサーションの問題で、&& が AND と同じであることを示しています。
同様に
1
&& と AND の違いは、&& は = よりも優先順位が高いのに対し、AND は = よりも優先順位が低いということです。したがって、
$a = 1 && 0;
は次のように理解できます。
$a = (1 && 0 );
And
$b = 1 AND 0;
は次のように理解できます:
($b = 1) AND 0; 5 階の none01 からの返信を引用します。エイリアスの問題についてはいろいろあります。
さらに、&& および I は、条件 1 && を使用する場合、条件 1 が false の場合、条件 2 は実行されず、カウントされることだけを知っています。 2、今日その本質的な理由が分かりました。
いいえ
&& であろうと AND であろうと、左の式が結果を計算するとき... いつも誤解をしているようです 丁寧な説明ありがとうございます。
xie xie
ありがとうございます
token_get_all() 関数を初めて見ました
知識を学びましょう
来てください
学びましょう...
実際、ここで PHP がエイリアスの問題をどのように処理するか理解しました。カスタマイズすることもできます。PHP の構文では、他のステートメントのエイリアスとして新しい言語構造が追加されます。
"exit" {
return T_EXIT; }
"die" {
return T_EXIT
} に zend_lang_scanner.l が必要です。
以下に
を追加します。 ;"stop" {
return T_EXIT; }
再コンパイルできました。使用できる stop ステートメントがもう 1 つあります。これは他の言語構造のエイリアスとしてのみ使用されるため、既存のトークンが返され、新しいトークンは追加されず、その後の処理は必要ありません。 stop ステートメントの効果は、exit および die とまったく同じであり、純粋なエイリアス関係です。
もちろん、新しい機能的な PHP 言語構造を追加する必要がある場合は、新しいトークンを追加し、新しいトークンの処理ロジックを追加する必要もあります。このような場所を変えるだけでは簡単ではありません。
ホスト、本当にありがとう!このような技術的な投稿は実際にはあまり見かけません。
私はいつも die を使っていました。ある日、クラスメートにこれを使ったことがあるか尋ねたところ、それがエイリアスであることを思い出すまで、長い間呆然としていました。 !
技術的な投稿、
役に立つ!
素晴らしい奴だ! ! ! ! ! !
普段はあまり使わない!よく分からないんですが、見てみると、ああ、こうなっているんだ!
これらはブログに書くことができます
学びに来ました、そして教えていただきました、時間を割いて整理してくれた著者に感謝します。
学びました