![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?e8efa67)
htmlのフォームタグ内で、inputtyp=file で受け取ったwordファイルやPDFファイルを
perlで書いたCGIプログラムのほうで、MYSQLのデータベースへ保存したいのですが
どのように書けばいいのかわかりません。
保存する型はBLOB型でよいといくつかのサイトで書いてあるのですが、
SQL文の書き方や、フォームから受け取ったデータの処理の仕方などの詳細が
わかりません。
フォームで受け取ったファイルをデータベース(mysql)へ保存する
簡単なサンプルコードなどが知りたいです。
よろしくお願いいたします。
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モジュールなども多く使われています。ご自分の環境や技量に応じて使いやすいものを選ぶといいでしょう。
この回答への補足
すいません、wordファイルは保存することができたのですが、
1メガバイトほどのPDFファイルを選択すると保存ができなくなってしまいました。
カラムの型はLONGBLOBにしてあるのですが、PDFファイルの保存はできないのでしょうか?
何度も申し訳ございません。
わかりやすいサンプルをありがとうございます!
しっかりとファイルをデータベースに保存することができました。
perlもデータベースも最近始めたばかりですが、少しづつ勉強して使いこなせるようになりたいと思います。
本当にありがとうございました。
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 (無制限)のはずですのでたぶん無関係と思いますが、念のため存在だけご紹介しておきます。
この回答への補足
回答ありがとうございます。
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のサイズのほうについてもう少し調べてみようと思います。
No.1
- 回答日時:
この回答への補足
リンク先を参照させていただきましたが、こちらjavaで書かれているようでした。
また、独自のクラスメソッドなども使っているようでして、問題解決までにはいきませんでした。
参考にできる部分もあると思いますので、活用させていただきます。回答ありがとうございます。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- CGI htmlからパラメータで、cgiに渡したい。 1 2023/02/06 16:15
- その他(プログラミング・Web制作) 【GAS】Gmail本文をブラウザ表示された状態でPDFにしたいです 1 2022/12/12 09:54
- Excel(エクセル) PDFファイルに日付を名前にして保存したい。 エクセル2019でワークシートに請求書のフォームを作り 2 2023/05/27 11:13
- PDF 保存したPDFファイルが開けなくなり、困っています 1 2022/09/15 21:08
- Visual Basic(VBA) batからexeを実行し戻り値を受け取る バッチからEXEの結果を受け取りたいのですが、 下記のバッ 1 2023/07/04 15:13
- Excel(エクセル) エクセル2019でPDFファイル名に枝番号をつけたい。 アクティブワークシートを印刷した後の処理とし 4 2023/06/06 21:00
- Excel(エクセル) エクセル 任意の列数で分割する方法 3 2022/07/31 14:58
- PHP ここでの ②if($su_d<>"")の比較演算子 を使う理由は 1 2022/03/26 02:33
- Visual Basic(VBA) outlook マクロが終了しません。 1 2022/09/02 11:14
- Visual Basic(VBA) batからexeを実行し戻り値を受け取る EXEの実行内容の結果によって、戻り値を0か1かで返したい 1 2023/07/04 16:40
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
LCD ディスプレイを Raspberry ...
-
laravel 本番環境でメールが送...
-
:shared って何
-
警告を消したい
-
Excel VBAでリンク切れをチェッ...
-
Excel VBA 『Call』で呼び出す...
-
例外処理のフローチャートの記...
-
ユーザー定義関数に#NAME?が返...
-
VBAでoutlook365が起動しません。
-
VBAで別モジュールへの変数の受...
-
モジュールの最大数はいくつな...
-
ユーザーフォームに最小化・最...
-
VBでグローバル変数を宣言するには
-
'Range'メソッドは失敗しました
-
Excel VBAで、ユーザーフォーム...
-
サブルーチンを認識しません。
-
エクセルVBAでシートモジュール...
-
Excelシート内セル記述の違いに...
-
perl起動方法
-
【vba】フォームに書いてあ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
LCD ディスプレイを Raspberry ...
-
Perlで画像のサイズ取得する方法
-
"use CGI::Session"でエラーが...
-
DBIが入っているはずですが、、、
-
laravel 本番環境でメールが送...
-
Unicode::Japanese を継承できない
-
WWW::Mechanizeがプロシキ経由...
-
警告を消したい
-
PerlでHashのキーを制限したい
-
Chart::Gnuplotの使い方
-
リンク先の画像サイズの取得
-
perlで指定か所のurlを取り出し...
-
htmlフォームから受け取ったフ...
-
データベースに接続したい
-
エラーでハマっている為、use A...
-
perlからDBIを使用したpostgres...
-
(Perl CPAN) DBDがはいらない
-
例外処理のフローチャートの記...
-
Excel VBAでリンク切れをチェッ...
-
ユーザー定義関数に#NAME?が返...
おすすめ情報