htmlテンプレートを処理し、ブラウザにエラー(ダイ)を表示し、あらゆる種類のリダイレクトを行い、ファイルを提供するなどのフレームワークを使用します。 -すべてがいつも通りです。 このフレームワークは、応答を形成してSTDOUTに出力した後、
exit()
を実行します。これは一般的にはオリジナルではありません。
この
exit()
は、
eval()
、または複数のネストされたeval-sの内部で呼び出すことができます。たとえば、計算の深さのどこかで、CGIがユーザーにリダイレクトを与えることを決定します。 同時に、フレームワークの関数を呼び出し、
print "Location: ..."
を出力して
exit()
ます。
ただし、FastCGIの
exit()
できません。
したがって、この出口をインターセプトし、
die()
(たとえばmod_perl が行うように)または
goto
ます。
die()
の問題は、
exit()
が
eval()
内で呼び出され、
eval()
を呼び出した後、ユーザーが
die()
再度呼び出して上記の未知のエラーを渡さないことです(ただし、このCGIボックスでevalが行われるたびにこの動作を保証します)私はできません-むしろ、これが通常起こらないことを保証できます)、
exit()
は単に最も近い
eval()
からの出口につながりますが、リダイレクトを引き起こしたCGIshopは明らかにカウントしませんでした!
CGI擬似コード
sub that_cgi_script {
...
eval { do_something() };
...
}
sub do_something {
# 1) may return if everything ok
# 2) may die on error, but such error non-important to
# calling code in above case and will be catched by
# eval and ignored
# 3) may redirect: print Location header and call exit()
}
ダイを介したオプション出口
my $FCGI_EXIT = "FCGI NORMAL EXIT\n";
BEGIN { *CORE::GLOBAL::exit = sub { die $FCGI_EXIT }; }
while (CGI::Fast->new()) {
eval { that_cgi_script(); };
die $@ if $@ && $@ ne $FCGI_EXIT;
$CGI::Fast::Ext_Request->Finish();
}
gotoによるバリアント出口
BEGIN { *CORE::GLOBAL::exit = sub { goto EXIT }; }
while (CGI::Fast->new()) {
eval { that_cgi_script(); };
die $@ if $@;
EXIT:
$CGI::Fast::Ext_Request->Finish();
}
perldoc -f gotoの説明
サブルーチンや「foreach」ループなど、初期化を必要とする構造体には使用できません。 また、最適化された構造に移動したり、「ソート」に指定されたブロックやサブルーチンから抜け出すために使用することもできません。
それでは、熊手はどこにありますか?
この状況に適用できる
goto
の唯一の問題は、
sort
内で
exit()
呼び出す
sort
です。 :)このCGIではそのようなことが許可されていないと心から信じています。 アーメン
CORE::GLOBAL::exit
goto
を使用する場合、他にレーキになり得るものは何ですか? 私が心配しているのは、mod_perl
goto
は使用しないことですが、
die()
よりも効率的なソリューションのようです。