5

バックグラウンド

以下は、 CGI を使用して送信されたフォーム データを取得し、フォーム データを DBI に渡し、必要な行を MySQL から取得し、結果を Template Toolkit に渡す典型的な Perl コード (説明のためにsample.pl ) です。表示用の HTML ドキュメントにレンダリングします。

sample.plのコードリスト:

#!/usr/bin/perl
use strict;
use CGI;
use DBI:
use Template;

#Grab submitted form data
my $cgi = CGI->new();
my $idFromSomewhere= $cgi->param('id');

my $driver   = "mysql";
my $server   = "localhost:3306";
my $database = "test";
my $url      = "DBI:$driver:$database:$server";
my $user     = "apache";
my $password = "";

#Connect to database
my $db_handle = DBI->connect( $url, $user, $password ) 
    or die $DBI::errstr;

#SQL query to execute
my $sql = "SELECT * FROM tests WHERE id=?";

#Prepare SQL query
my $statement = $db_handle->prepare($sql)
        or die "Couldn't prepare query '$sql': $DBI::errstr\n";

#Execute SQL Query
$statement->execute($idFromSomewhere)
    or die "Couldn't execute query '$sql': $DBI::errstr\n";

#Get query results as hash
my $results = $statement->fetchall_hashref('id');

$db_handle->disconnect();
my $tt = Template->new();

#HTML output template
my $input = 'template.html';
my $vars = {
    tests => $results,
};

#Process template and output as HTML
$tt->process($input, $vars)
    or die $tt->error();

パフォーマンスとスケーラビリティを向上させるために、Dreamhost などの共有サーバーを提供する Web ホストは、すべての運用 Perl スクリプトが FastCGI をサポートすることを強く推奨します。FastCGI のドキュメントには、FastCGI をサポートするために既存の Perl コードを変更する方法が明確に記載されています。以下の単純なコードは、多くの場合、例として示されています。

use FCGI;
while (FCGI::accept >= 0)
{    
   #Run existing code.
}

あまり明確でないのは、while ループのどこに何を入れるかです。

サブ質問

A. sample.pl のコードは、次のように既存のコードを単純にラップする必要があります。

while (FCGI::accept >= 0)
{    
    #Grab submitted form data
    my $cgi = CGI->new();
    ...
    ...
    #Process template and output as HTML
    $tt->process($input, $vars)
    or die $tt->error();
}

B. それ以上のことはありますか? たとえば、CGI、データベース、およびテンプレートを処理するコードは、独自のサブにリファクタリングする必要がありますか?

C. DBI->connect() と $db_handle->disconnect() は、FCGI while ループの内側または外側で呼び出す必要がありますか? また、パフォーマンスへの影響は?

D. $tt->process() は FCGI while ループの内側または外側で呼び出す必要がありますか?

4

3 に答える 3

10

CGI.pm に慣れている場合は、FCGI.pm を使用しても意味がありません。CGI::Fast を使用してください。

CGI::Fast を使用するように変換された例は次のようになります。

#!/usr/bin/perl
use strict;
use CGI::Fast;
use DBI;
use Template;

my $driver   = "mysql";
my $server   = "localhost:3306";
my $database = "test";
my $url      = "DBI:$driver:$database:$server";
my $user     = "apache";
my $password = "";

#Connect to database
my $db_handle = DBI->connect( $url, $user, $password ) or die $DBI::errstr;

while ( my $cgi = CGI::Fast->new() ) {

    #Grab submitted form data
    my $idFromSomewhere = $cgi->param( 'id' );

    #SQL query to execute
    my $sql = "SELECT * FROM tests WHERE id=?";

    #Prepare SQL query
    my $statement = $db_handle->prepare( $sql )
        or die "Couldn't prepare query '$sql': $DBI::errstr\n";

    #Execute SQL Query
    $statement->execute( $idFromSomewhere )
        or die "Couldn't execute query '$sql': $DBI::errstr\n";

    #Get query results as hash
    my $results = $statement->fetchall_hashref( 'id' );

    my $tt = Template->new();

    #HTML output template
    my $input = 'template.html';
    my $vars = { tests => $results, };

    #Process template and output as HTML
    $tt->process( $input, $vars )
        or die $tt->error();
}

あなたのサブ質問について:

  • A: 何をしているのかを完全に理解している場合を除き、FCGI を使用しないでください。あなたは間違いなくCGI::Fastが欲しいです:)
  • B: 読みやすくするためにリファクタリングします
  • C: 接続を受け入れる前に DBI->connect を使用すると、パフォーマンスの観点から優れた永続的なデータベース接続が得られます
  • D: 間違いなく中です。

余談ですが、Perl で Web サイトを開発したい場合は、少なくとも Catalyst ( http://www.catalystframework.org/ )をご覧ください。

于 2009-06-04T09:43:48.970 に答える
1

FCGI を使用する場合は、そのループで最小限の作業のみを実行してタスクを開始します。他のすべてはモジュールに存在する必要があり、入力を渡すだけで済みます。

use FCGI;
while (FCGI::accept >= 0)
    {    
    MyApplication->activate( @args );
    }

残りのものは MyApplication のどこかにあります。興味深いものは、FastCGI スクリプトに含めるべきではありません。すべてのアプリケーションを、それをアクティブにするものと密接に結合する必要はありません。

スクリプトを再利用可能なモジュールに変換する方法については、 Mastering Perlの modulinos に関する私の章を参照してください。そのようなことは、このようなことを本当に簡単にします。

永続的なデータベース接続については、もう少し作業が必要です。ループ外で接続を開始できますが、定期的に ping を実行し、場合によっては再確立する必要があります。これについては、 Apache::DBIを参照してください。

于 2009-06-04T21:56:16.180 に答える
0

サブ質問 C: (永続的な DB 接続)

DBI->connect_cached()を見てください。CGI::Fast ループ内で使用できると思います。DBI.pm は接続を記憶/キャッシュします。したがって、同じパラメーターを使用して connect_cached() を 2 回目、3 回目などで呼び出すと、既存の接続が返されます。古い接続が利用できなくなった場合、新しい接続が作成されます。

このアプローチの本当に素晴らしい点は、既存のアプリケーションに加える必要がある唯一の変更 (CGI::Fast ループの追加以外) は、connect() を connect_cached() に置き換えることです。また、connect_cached() はプレーンなバニラ CGI でも動作します。

Perl で FastCGI を利用するには、DB 接続/初期化を FCGI ループの外に置く必要がありますか?も参照してください。 および http://www.mail-archive.com/cgiapp@lists.erlbaum.net/msg04351.html

于 2009-11-21T04:03:02.457 に答える