Poturi

目次

環境変数の表示

環境変数表示用のコードです。CGIの動作チェックなんかに便利かもしれません。

使用例

ソースコード

#!/usr/bin/perl

print <<"EOF";
Content-Type: text/html

<html>
<head>
<title>Environment Variables</title>
<style type="text/css">
h1 {
	text-align: center;
}
table {
	border-collapse: collapse;
	margin: 0 auto;
	padding: 0;
}
th {
	font: bold 10pt sans-serif;
	text-align: left;
	color: #fff;
	background: #666;
	margin: 0;
	padding: 5px 1em;
}
td {
	font: normal 10pt sans-serif;
	border-bottom: 1px dotted #666;
	margin: 0;
	padding: 5px 1em;
}
</style>
</head>
<body>
<h1>Environment Variables</h1>
<table>
<thead>
	<tr>
		<th>Key</th>
		<th>Value</th>
	</tr>
</thead>
<tbody>
EOF

foreach $key (sort keys %ENV) {
	chomp($value = $ENV{$key});
	$value =~ s/<[\/]*[a-zA-Z0-9]+>//g;

print <<"EOF";
	<tr>
		<td>$key</td>
		<td>$value</td>
	</tr>
EOF
}

print <<"EOF";
</tbody>
</table>
</body>
</html>
EOF

CPANの使い方

Perlにモジュールを追加するには、CPAN(Comprehensive Perl Archive Network)を使うと簡単で、管理しやすくなります。

> perl -MCPAN -e shell

初回起動時は初期設定が必要になりますが、ほとんどデフォルトのままリターンすれば大丈夫です。ミラーサーバは、日本のサーバを選びましょう。

モジュールの情報を見るには、iコマンドを使います。

cpan[0]> i DBD::mysql
Strange distribution name [DBD::mysql]
Bundle    Bundle::DBD::mysql     (CAPTTOFU/DBD-mysql-4.004.tar.gz)
Module  = DBD::mysql             (CAPTTOFU/DBD-mysql-4.004.tar.gz)
2 items found

このモジュールをインストールしたければ、installコマンドを使います。

cpan[0]> install DBD::mysql

UTF-8の文字数をカウントする

UTF-8でエンコードされたPerlスクリプトで、length()関数を使って文字数をカウントしようとすると、日本語1文字が3バイトなので、うまくカウントするのが大変です。そこでEncode.pmを使って文字列をデコードすると、簡単に文字数をカウントできます。

use Encode;

$str = "こんにちはHello";
$count = length($str);
print "「$str」は$countバイトです。\n";

$count = length(decode('utf-8', $str));
print "「$str」は$count文字です。\n";

このスクリプトの出力は次のようになります。

「こんにちはHello」は20バイトです。
「こんにちはHello」は10文字です。

改行を<br />に置換する

改行コードはWindowsではCR+LF、Mac OS 9ではCR、Unix系OSではLFですが、Perlで\nと\rを組み合わせてそれぞれの改行コードにマッチさせようとするのは根本的に間違っています。

そこで、ASCIIコード(CRは\x0D、LFは\x0A)で置換します。詳細については大崎博基氏のWebサイトの「改行コードを統一する」がとても参考になりました。

$str =~ s/\x0D\x0A/<br \/>/g;
$str =~ s/\x0D/<br \/>/g;
$str =~ s/\x0A/<br \/>/g;

PerlとMySQLによる簡易BBS

当サイトに設置しているBBSのプログラムをせっかくなので公開しておきます。400行ほどのPerlスクリプトですが、独自フォーマットのデータベースを作るよりもMySQLと連携させる方がずいぶん楽だと思いました。

タグのエスケープ

BBSで大事なのはタグのエスケープで、セキュリティ対策としてきわめて重要な処理です。具体的には、小なり記号「<」と大なり記号「>」をそれぞれ実体参照の「&lt;」と「&gt;」に置換して、タグとして解釈されないようにします。また、ダブルクォート「"」とアンパサンド「&」も、ブラウザが特殊な値として解析しないように「&quot;」と「&amp;」に置換します。

エスケープする順番は、最初にアンパサンドをエスケープしてから、ほかの記号をエスケープします。

$text='<a href="http://example.net">foo</a>'
&escape_tag(\$text);
print "$text\n";

# &、<、>、"を実体参照に置換
sub escape_tag {
	my $var = $_[0]; # reference
	${$var} =~ s/&/&amp;/g;
	${$var} =~ s/</&lt;/g;
	${$var} =~ s/>/&gt;/g;
	${$var} =~ s/"/&quot;/g;
}

このコードの実行すると、$textのタグがエスケープされて次のようになります。

&lt;a href=&quot;http://example.net&quot;&gt;foo&lt;/a&gt;

データベースのデータ形式

データベースには余計なデータを保存しないのが理想なので、エスケープ前のテキストを保存します。つまり、ブラウザに表示するときと、画面遷移時に値を持ち越すときだけタグをエスケープするようにします。これが案外ややこしい処理になりますが、手を抜かないようにしましょう。

データベースに値を登録するとき、バックスラッシュ(円記号)「\」をエスケープする必要があります。バックスラッシュのエスケープは、二重にエスケープすることになるので注意が必要です。「\」を登録するにはPerlで「\\\\」に置換して、そうすると実際は「\\」になっているので、データベースには「\」が登録されるという計算です。

# バックスラッシュをエスケープ
sub escape_backslash {
	my $var = $_[0]; # reference
	${$var} =~ s/\\/\\\\/g;
}

MySQLとの連携

PerlからMySQLを使うにはDBIモジュールとDBD::mysqlモジュールが必要なので、CPANから最新版を入手します。

ソースコード