• ベストアンサー

htmlフォームから受け取ったファイルをDBへ保存

htmlのフォームタグ内で、inputtyp=file で受け取ったwordファイルやPDFファイルを perlで書いたCGIプログラムのほうで、MYSQLのデータベースへ保存したいのですが どのように書けばいいのかわかりません。 保存する型はBLOB型でよいといくつかのサイトで書いてあるのですが、 SQL文の書き方や、フォームから受け取ったデータの処理の仕方などの詳細が わかりません。 フォームで受け取ったファイルをデータベース(mysql)へ保存する 簡単なサンプルコードなどが知りたいです。 よろしくお願いいたします。

質問者が選んだベストアンサー

  • ベストアンサー
  • N60-BASIC
  • ベストアンサー率80% (17/21)
回答No.2

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モジュールなども多く使われています。ご自分の環境や技量に応じて使いやすいものを選ぶといいでしょう。

hi_mawa
質問者

お礼

わかりやすいサンプルをありがとうございます! しっかりとファイルをデータベースに保存することができました。 perlもデータベースも最近始めたばかりですが、少しづつ勉強して使いこなせるようになりたいと思います。 本当にありがとうございました。

hi_mawa
質問者

補足

すいません、wordファイルは保存することができたのですが、 1メガバイトほどのPDFファイルを選択すると保存ができなくなってしまいました。 カラムの型はLONGBLOBにしてあるのですが、PDFファイルの保存はできないのでしょうか? 何度も申し訳ございません。

その他の回答 (2)

  • N60-BASIC
  • ベストアンサー率80% (17/21)
回答No.3

> 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 (無制限)のはずですのでたぶん無関係と思いますが、念のため存在だけご紹介しておきます。

hi_mawa
質問者

補足

回答ありがとうございます。 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のサイズのほうについてもう少し調べてみようと思います。

noname#158634
noname#158634
回答No.1
hi_mawa
質問者

補足

リンク先を参照させていただきましたが、こちらjavaで書かれているようでした。 また、独自のクラスメソッドなども使っているようでして、問題解決までにはいきませんでした。 参考にできる部分もあると思いますので、活用させていただきます。回答ありがとうございます。

関連するQ&A