タックス研究室、ここも研究室かよ
プログラミング

【Webアプリ】ファイルを添付できる掲示板の作成#4

今まで行ってきた知識のまとめとしてファイルを添付できる掲示板を作成しました。

ローカルで使うことを目的としたため(掲示板なのに)、セキュリティ面は考慮していません。そのうちセキュリティ対策も学びたい。

ソースコードは公開しますが必ずローカル環境で使用してください。

私の動作環境はxamppを使用しています。

ソースコード

下記の「input.php」と「dl.php」は同じディレクトリに配置してください。

また、そのディレクトリに「files」という名前のファイル,「data.csv」という名前のcsvファイルを生成してください

input.php(掲示板画面)

<?php session_start(); ?>
<?php
$fp = fopen('data.csv', 'a+b');
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    fputcsv($fp, [$_POST['name'], $_POST['comment'],$_FILES["f"]["name"]]);
    rewind($fp);
    header('Location: ' . $_SERVER[‘SCRIPT_NAME’]); //更新で2重投稿防止
}
while ($row = fgetcsv($fp)) {
    $rows[] = $row;
}
fclose($fp);
?>
<!DOCTYPE html>
<html>
    <head>
        <title>form</title>
        <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <style>
            #p{
                background-color: #c2f2bb;
                padding-left: 10px;
                padding-right: 10px;


            }
            body{
                background-color: #c2f2bb;
                font-family: Quicksand, 游ゴシック体, YuGothic, 'ヒラギノ角ゴシック Pro',メイリオ, Meiryo,'MS Pゴシック', sans-serif;
            }
            h2#t{
                text-align:center;
            }
            

        
        
        </style>

    </head>
<body>
    <h2 id='t'>掲示板</h2>
    <form action="" method="post" enctype="multipart/form-data">
    <table cellpadding="1" cellspacing="1">
        <tbody><tr><td><b>名前</b></td><td><input type="text" name="name" size="28" value=""></td></tr>
        
        <tr><td colspan="2"><b>本文</b><br>
        <textarea name="comment" cols="80" rows="7" wrap="soft"></textarea></td></tr>
        <tr><td colspan="2"><input type="submit" value="送信する"><input type="reset" value="リセット">  
        <b>添付File</b><input type="file" name="f" size="36">
        
        </tbody></table>
        
        
    </form>
    <hr>
    <h2>投稿一覧</h2>
    <?php date_default_timezone_set('Asia/Tokyo');?>
    <div id='p'>
    <?php if (!empty($rows)): ?>
        <?php $i=1;?>    
    <?php foreach ($rows as $row): ?>
            <div id=post>
            <div> <?="[". $i ."]"?><?= date("m/d H:i:s");?> NAME:<?=$row[0]?></div>
            <?php if(!empty($row[1])){
                    echo '<div>'.$row[1].'</div><br>';

                }?>
           
                <?php if(!empty($row[2])){
                    echo '添付ファイル:<a href="dl.php">'.$row[2].'</a>';

                }
                ?>
                    <?php if($i==20){
                        echo ("Please update stylesheet");

                    }
                    ?>
            </div>
            
            <hr>
    <?php endforeach; ?>
          
    <?php else: ?>
        <p>投稿はまだありません</p>
    <?php endif; ?>
            </div>
</body>
<?php
if(!empty($_FILES["f"])){
    
if (is_uploaded_file($_FILES["f"]["tmp_name"])) {
    if (move_uploaded_file($_FILES["f"]["tmp_name"],  "files/" .$_FILES["f"]["name"])) {
      chmod("files/" .$_FILES["f"]["name"], 0644);
      
      $_SESSION['file'] = "files/" .$_FILES["f"]["name"];
      
    }
}
}
?>
</body>
</html>

dl.php(ファイルダウンロード)

<?php
session_start();
$file = $_SESSION['file'];
header('Content-Type: application/force-download');
header('Content-Length: '.filesize($file));
header('Content-Disposition: attachment; filename="'.$file.'"'); 

readfile($file);

?>

動作確認

input.phpのページに飛ぶと下の画像の画面が表示されます。(クリックで拡大)

試しにコメントと添付ファイルを送信してみたいと思います。

しっかりと表示されますね。

添付ファイルのリンクを押すと、ダウンロードすることができます。この役割はdl.phpが担っています。

感想

セキュリティ面を考慮するならば、ファイル名もしっかり変えたほうがよさそうです。データベースはcsvファイルを用いましたが、MySQLなども今後使ってみたいです。

今回の実装を通してネットの某特大掲示板の仕組みも少し分かりました。

参考サイト

(1)https://www.dt30.net/gachinko/?p=507

(2)https://dev-lib.com/php-file-download/

(3)http://www.php-labo.net/tutorial/php/upload.html

(4)https://i-bitzedge.com/html-css/how-to-create-bulletin-board-1