電子書籍の厳選無料作品が豊富!

htmlのフォームタグ内で、inputtyp=file で受け取ったwordファイルやPDFファイルを
perlで書いたCGIプログラムのほうで、MYSQLのデータベースへ保存したいのですが
どのように書けばいいのかわかりません。

保存する型はBLOB型でよいといくつかのサイトで書いてあるのですが、
SQL文の書き方や、フォームから受け取ったデータの処理の仕方などの詳細が
わかりません。

フォームで受け取ったファイルをデータベース(mysql)へ保存する
簡単なサンプルコードなどが知りたいです。


よろしくお願いいたします。

A 回答 (3件)

PerlによるMySQL DBへのアクセスでは、DBIモジュールを使うのが最も代表的な方法です。


DBIモジュールとDBD::mysqlモジュールが利用できる環境が必要です。

以下に、DBIモジュールによるファイルアップロードのサンプルを示します。

#!/usr/local/bin/perl ←利用環境に合わせて書き換え
use strict;
use warnings;
use CGI;
use CGI::Carp qw(fatalsToBrowser);
use DBI;
use DBD::mysql;

# 各種設定
my $db_host = 'localhost';# DBホスト名
my $db_name = 'dbname';# DB名
my $db_user = 'user';# DBユーザー名
my $db_pass = 'password';# DBパスワード

# CGI POSTデータ取得
my $cgi = new CGI;
my $fh = $cgi->param('fileform') or die "Upload file is missing\n";# <INPUT>要素のNAMEを指定
binmode($fh);
read($fh, my $file, -s $fh);
close($fh);

# DBに接続
my $dbh = DBI->connect("DBI:mysql:host=${db_host};database=${db_name}", $db_user, $db_pass) or die $DBI::errstr;

# SQLでファイルバイナリをINSERT
my $sth = $dbh->prepare('INSERT INTO tablename SET file=?') or die $dbh->errstr; # DBテーブル構造に合わせて適宜変更
my $rv = $sth->execute($file);
if(! $rv || $rv eq '0E0') { die $sth->errstr; }
$sth->finish;

# DB切断
$dbh->disconnect;

# CGI結果出力
print "Content-Type: text/html;\x0D\x0A\x0D\x0A";
print "<html><body>Upload done.</body></html>";

exit;

=comment
データベーステーブルを生成するSQL文の例:

CREATE DATABASE IF NOT EXISTS dbname DEFAULT CHARACTER SET utf8;
USE dbname;
CREATE TABLE IF NOT EXISTS tablename (
id MEDIUMINT AUTO_INCREMENT NOT NULL,
file MEDIUMBLOB,
PRIMARY KEY (id)
) ENGINE=InnoDB,DEFAULT CHARACTER SET utf8;

=cut

=comment
ファイルアップロードフォームの例:

<html>
<body>
<form method="POST" action="fileupload.cgi"><!-- ←CGIファイル名に合わせて書き換え -->
<input type="file" name="fileform">
<input type="submit">
</form>
</body>
</html>

=cut

以上です。詳細は「Perl DBI」などで検索してください。
ただし、Perlでリレーショナルデータベースを扱う以上は、PerlおよびSQLの文法については最低限の知識として勉強する必要があります。
上記のサンプルでも、データベーステーブルの生成やアカウント作成は含まれていませんので、事前に済ませておく必要があります。
Webアプリケーションフレームワークではテーブルの生成をやってくれるものもありますが、それらも勉強せずに一朝一夕で使えるものではありません。
またDBIモジュール以外にも、DBIx::Classモジュールなども多く使われています。ご自分の環境や技量に応じて使いやすいものを選ぶといいでしょう。

この回答への補足

すいません、wordファイルは保存することができたのですが、

1メガバイトほどのPDFファイルを選択すると保存ができなくなってしまいました。

カラムの型はLONGBLOBにしてあるのですが、PDFファイルの保存はできないのでしょうか?

何度も申し訳ございません。

補足日時:2011/11/16 18:41
    • good
    • 0
この回答へのお礼

わかりやすいサンプルをありがとうございます!
しっかりとファイルをデータベースに保存することができました。

perlもデータベースも最近始めたばかりですが、少しづつ勉強して使いこなせるようになりたいと思います。

本当にありがとうございました。

お礼日時:2011/11/16 18:31

> 1メガバイトほどのPDFファイルを選択すると保存ができなくなってしまいました。



おそらくMySQLサーバーの設定の問題だと思います。
MySQLでは通信パケットの最大サイズのデフォルト値が1MBになっています。
my.iniのmysqldセクションでmax_allowed_packetとして指定できますので、この値を大きくしてやればいいです。

[mysqld]
max_allowed_packet=16MB

その他の要因としては、レンタルサーバーなどでApacheの設定によってPOSTの最大サイズが制限されている場合があります。この場合、自分で管理していないサーバーだったりするとお手上げかもしれません。サーバー管理者に相談してください。

あと、PerlのCGI.pmでも最大POSTサイズを制限する変数があります($CGI::POST_MAX)。
こちらは通常の環境ではデフォルト値が -1 (無制限)のはずですのでたぶん無関係と思いますが、念のため存在だけご紹介しておきます。

この回答への補足

回答ありがとうございます。

my.iniのmysqldセクションのmax_allowed_packetを確認したところ 16Mとなっており問題ありませんでした。

Apacheのほうは、httpd.confに

<Files *.pdf>
LimitRequestBody 10485760
</Files>

を追加てみたんですが、1MサイズのPDFは保存できませんでした。

また、CGI.pmの$CGI::POST_MAXも確認したところ
$CGI::POST_MAX=1024 * 100; # max 100K posts
となっていましたの $CGI::POST_MAX=1024 * 5000;
に直してみたんですが、やはりPDFの保存はできませんでした。
試しに500KBとほどのPDFで確認してみたんですが、こちらは保存できていました。

原因はファイルサイズのようですが、うまくいきません。
POSTのサイズのほうについてもう少し調べてみようと思います。

補足日時:2011/11/17 14:18
    • good
    • 0

この回答への補足

リンク先を参照させていただきましたが、こちらjavaで書かれているようでした。
また、独自のクラスメソッドなども使っているようでして、問題解決までにはいきませんでした。

参考にできる部分もあると思いますので、活用させていただきます。回答ありがとうございます。

補足日時:2011/11/15 19:15
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!