Perlで作った掲示板に添付ファイルを貼り付けたいのですが

[上に] [前に] [次に]
ほーちゃん 1998/08/27(木) 12:41:37
添付ファイルを掲示板上等に登録(アップロード)する方法が勉強不足の為うまく出来ません。
サンプルプログラムがあれば教えて下さい。

匿名希望 1998/08/27(木) 14:47:47
質問の内容に関する確認を何点かさせて下さい。

1. 掲示板自体はほーちゃんさんのホームページのものですか
(ほーちゃんさんが普段ファイルをアップロードしているサーバ
かということも含めて)。
2. ファイルのアップロードは掲示板の中のスクリプトを利用している
ものですか。それとも普通のFTPソフトを利用したものですか。
3. 掲示板の中でタグは使えますか。
4. 添付するというのは、ただ単に、リンクをつけるだけなのか、
ファイルの内容を、掲示板の中に表示するのか。

1.は、レンタルの掲示板や、他の人の掲示板ではファイルをアップロード
したりはできないと思います。技術的にはできると思いますが、それを
やってしまうと管理上大変ですので。
2.は、前者であることはあまり無いと思います(理由は1.と同じ)。
後者ならば、掲示板の置いてあるディレクトリと、ファイルをアップする
ディレクトリを確認して下さい。
3.で使えないようでしたら、だめだと思います。使えるようにプログラムを
改造するか(この際、セキュリティに気をつけて。タグを使ったいたずらを
されることがあるかもしれません)、使えるようなプログラムを
探しましょう。
4.はリンクをつけるだけならば、2.で調べたディレクトリの指定さえ
間違っていなければ、<a>や<img>のタグでリンクをつけられると
思います。掲示板の中に直接表示する場合は、うーーんん、プログラムに
よるとしか言えません。

ちょっと、ふにゃふにゃな回答になってしまいましたが、
状況が分かればもう少し、しっかり答えられる思います。

tetsuya 1998/08/28(金) 00:57:43
 ふと思ったんですがご自分で作られたんですか?>掲示板
 Perlで作った、ということは自作の掲示板だろうと思いますが、
 それならファイルの置き場所なりの問題はないと思ってよいんでしょうか?

 それを前提にして話を進めます。

 「どっかに在る画像をIMGタグで張り付ける」のは簡単に出来るでしょうから
 これは省略。
 ホントにファイルをアップロードするのなら、
 要するにブラウザから実際にファイルをアップすると言う意味だと思います。
 これは「とほほのHTMLリファレンス」・・・
 http://www.tohoho-web.com/html/form.htm
 に基本的な使い方が書かれていますが、
 ミソは「ENCTYPE="multipart/form-data"」というところと、
 それから送られたファイルの中身の解析方法です。

 「とほほのHTMLリファレンス」にあるサンプル・・wwwupl.cgiは
 そのままでは使えなかったと思います。
 これと定番の「cgi--lib.pl」などを参考にして、
 「複数ファイル(に限らずFormのデータ)を抽出」
 する事さえ出来れば後は別に問題ないです。
 ファイルだったらmimeタイプもくっついてくるはずですから、
 それを元にプログラム側で処置してやるなどは簡単です。

#あ、そう言えば元々そういうライブラリもあったんでしたっけ・・覚えてないです

 私がやったときは結局「multipart版のcgi-lib.pl」を作ったようなものですが
 原理さえ飲み込めば難しくないです、頑張ってください。

ほーちゃん 1998/08/28(金) 09:55:43
わー、質問内容があいまいと言うか言葉足らずで申しわけありません。
掲示板と言うのは、自分で作ったものです(Perlで)。
その掲示板でブラウザから実際にファイルをアップすると言う意味で書きました。
tetsuyaさんが教えてくれている部分も参考にして作ったりしたのですが。。。出来ないのですよぉ
「ENCTYPE="multipart/form-data"」というところと、
それから送られたファイルの中身の解析方法がなんとなく分かったぐらい。
では添付ファイルのアップロードに成功しなかったので書かせてもらいました。

それで、気になった点があるのですがtetsuya さん定番の「cgi--lib.pl」って
何ですか?どこかに載ってますか?参考にしますので教えて下さい。

tetsuya 1998/08/29(土) 00:19:25
 えーとcgi-lib.plっていうのは、perl4の時代に普及していたcgi用のライブラリです。
 5ではもっと新しいものが色々あるみたいなんですが、
 私はこれを使い慣れてしまったので離れられない(笑

 他のライブラリも含め、以下のところからたどれます。
 http://www.bekkoame.or.jp/~syunji/perl/cgi_sam1.html

 基本的な使用法は
 require 'cgi-lib.pl';
 &ReadParse(*opts);

 とすると、optsにハッシュとしてフォームデータが格納されます。
 キーはフォームで記述した各「NAME」です。


 んで例えば私がこれを元に作成したのは以下のようなモノ。
 限定用途なので改行の処理等はかなり適当です、気をつけてください。
 無茶苦茶いい加減な書き方をしてる気がするので、
 自分なりに書き起こす方が良いと思います。
 使用法は上に準じます。

#!/usr/bin/perl -- -*- C -*-
sub ReadData {
    ($ENV{'REQUEST_METHOD'} eq "POST") || return "error";
    local (*in) = @_ if @_;
    local ($s,$i,$key,$val);
    while(<STDIN>){
if (/(-+[0-9]+).*/) {
    $s = $1;
    last;
}
    }
    while ($i  = <STDIN>){
$i =~ /.*; name="(.*?)"/;
$key = $1;
if ($i =~ /.*filename="(.*?)"/){
    $i = <STDIN>;
    $i =~ /Content-Type: (.*)\015$/;
    $in{$key."_TYPE"} = $1;
}
<STDIN>;
while($i = <STDIN>){
    ( $i =~ /$s.*/ ) && last;
    $in{$key} .=$i;
}
chop($in{$key});
chop($in{$key});
($i =~ /$s--.*/) && return length($in);
    }
    return length($in);
}
1; #return true







 

スラきち [E-Mail] 1998/08/29(土) 00:41:27
私も掲示板を作っているときにこんなふうに処理していました。

sub read_formdata
  {
  local(@record,$buffer,$card);
  local($title,$data);
  undef(%formdata);
  if($ENV{'REQUEST_METHOD'} eq "POST")
    {
    read(STDIN,$buffer,$ENV{'CONTENT_LENGTH'});
    $formdata_method_post=1;
    }
  else
    {
    $buffer=$ENV{'QUERY_STRING'};
    $formdata_method_post=0;
    }
  if($formdata_method_post==1 && substr($ENV{'CONTENT_TYPE'},0,30) eq "multipart/form-data; boundary=")
    {
    if(read_formdata2($buffer)==1)
      {
      return;
      }
    }
  @record=split(/&/,$buffer);
  foreach $card(@record)
    {
    ($title,$data)=split(/=/,$card);
    $data=~ tr/+/ /;
    $data=~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg;
    $formdata{$title}=$data;
    }
  }

sub read_formdata2
  {
  local($buffer)=$_[0];
  local($splitter,@lines);
  local($data,$i,$title,$mode);
  $splitter="--".substr($ENV{'CONTENT_TYPE'},30);
  $buffer=~ s/\r\n\n/\n/g;
  $buffer=~ s/\r\n/\n/g;
  $buffer=~ s/\r/\n/g;
  @lines=split(/\n/,$buffer);
  if($lines[0] ne $splitter && $lines[0] ne $splitter."--")
    {
    return 0;
    }
  $mode=0;
  $data="";
  $title="";
  for($i=0;$i<scalar(@lines);$i++)
    {
    if($splitter eq $lines[$i])
      {
      if($mode==2 && $title ne "")
        {
        chop($data);
        $formdata{$title}=$data;
        }
      $mode=1;
      $title="";
      $data="";
      }
    elsif($splitter."--" eq $lines[$i])
      {
      if($mode==2 && $title ne "")
        {
        chop($data);
        $formdata{$title}=$data;
        }
      return 1;
      }
    elsif($mode==2)
      {
      $data.=$lines[$i]."\n";
      }
    elsif($lines[$i] =~ /^Content\-Disposition: form\-data; name=\"([^\"]*)\".*/ && $mode==1)
      {
      $title=$1;
      }
    elsif($lines[$i] eq "" && $mode==1)
      {
      $mode=2;
      }
    }
  return 1;
  }

これで、CGIの起動時に
read_formdata();
とすれば
%formdata
に全情報が格納される...はずです。

[上に] [前に] [次に]