LogoMark.png

PHP/Sample02

PHP Sample Code

Counter / Simple Line BBS / File Upload

アクセスカウンター、簡易掲示板、画像のアップロードについて紹介します。ソースコード中の関数の詳細については(PHPマニュアル)で確認して下さい。
 ここでのサンプルは、サーバー内のデータを書き換えたり、フォルダ内にデータを送り込んだりするものです。しかし、一般にサーバーの初期設定ではサーバー内の操作を認めていませんので、「このファイルはオーナー以外の人の操作でも書き換えて構いません」という設定に変える必要があります。
 サーバー内に設置したファイルやフォルダについては、必要に応じてパーミッションの変更を行って下さい。サーバーにアップしたファイル・フォルダについてはFTPソフトで属性の変更、XAMPP等で試している方は、ファイルのプロパティーを表示してアクセス権の変更…です。



事例5 →DEMO 簡易アクセスカウンター

このサンプルでは、同一のディレクトリに、以下の index.phpcount.txt の2つのファイルが必要です。

index.php


count.txt

0

count.txt という名前のファイルを同一ディレクトリに置くことが必要です。
数字を1つ記憶しているだけなので、初期値として「 0 」のみ記述したファイルを準備して下さい。

尚、count.txt は 初期状態が 0 + 改行 ではダメなのでエディタが保存時に勝手に改行を書くようであれば、何も書かない空ファイルでお試し下さい
 2回め以降のアクセスでは、まずファイルからデータを取り出して、カウントを一つ増やして、また書き込む…という動作をします。

count.txt は書き込み可能であることが前提です。 FTPツールで、count.txt のパーミッションを書き込み可にして下さい。

<?php ~ ?>の部分のコードを既存のあなたのページのソースに加える形で、カウンターを設置することが可能です。但し拡張子は .php にすることと、サーバーがPHPに対応していることが前提です。


事例6 →DEMO 簡易投稿掲示板

この事例では、投稿フォームからの送信に対して、自分自身をリロードする形で、データの書き込み処理と再表示を行っています。

index.php

<!DOCTYPE html>
<html lang="ja">

    <head>
        <meta charset="utf-8">
        <title>LINE BBS</title>
    </head>

    <body>
        <p>LINE BBS with PHP</p>
        <form action="./index.php" method="POST">
            NAME : <input type="text" name="name" size="8" > 
            COMMENT : <input type="text" name="message" size="56" > 
            PASSWORD : <input type="password" name="password" size="10" >
            <input type="submit" value="SUBMIT" >
        </form>
        <?php
            $file = "log.txt";
            $log = "";
            if(file_exists($file)) {
                $log = file_get_contents($file);
            }	
            if( $_POST["name"] != "" && $_POST["message"] != "" ){
                if( $_POST["password"] != "******" ){
                    echo "<hr>"."Password does not match.";
                } else {
                    $name    = htmlspecialchars( $_POST["name"]; );
                    $message = htmlspecialchars( $_POST["message"] );
                    $line = "<p>$name : $message</p>\n";
                    $log  = $line . $log;
                    file_put_contents($file, $log);
                }
            } 
            echo "<hr>".$log;
        ?>	
    </body>

</html>

投稿されたメッセージは、log.txt という名前のファイルに逐次蓄積されていきます。「投稿」というのは、誰が何を書くかわからない…という点で、注意を要します。この事例では、受講生の方のみが動作確認できるようパスワードの入力を求めるようにしています(パスワードは授業中に伝えます)。
 htmlspecialchars()という関数は、入力された文字列をそのまま処理系に渡すと、例えばHTMLタグに相当する文字がソースコードとして処理されてしまうなどの危険もあるので、念のためです。



事例7 →DEMO 画像投稿掲示板

index.php

<!DOCTYPE html>
<html lang="ja">

    <head>
        <meta charset="utf-8">
        <title>PHOTO STOCK</title>
    </head>

    <body style = "line-height:180%;">

        <p>PHOTO STOCK with PHP</p>
        <form enctype="multipart/form-data" method="POST">
            FILE : <input type="file" name="photo" ><br>
            COMMENT : <input type="text" name="comment" size="60"><br>
            PASSWORD : <input type="password" name="password" size="10">
            <input type="submit" value="UPLOAD">
        </form>

        <?php
            $dir = "images/";
            $file = "log.txt";
            $log = array();
            if( ! is_writable ( $file ) ){
                echo "<hr>"."SYSTEM ERROR : Can't open log file."."<br>";
                exit;
            }
            $log = file($file);
            do {
                if( ! is_uploaded_file( $_FILES['photo']['tmp_name'] ) 
                                          || $_POST["comment"] == "" ){
                    $err = "<hr>"."ERROR : Upload error."."<br>";
                    break; // 画像とコメントがアップされていない
                }
                if( $_POST["password"] != "******" ){
                    $err = "<hr>"."ERROR : Password error"."<br>";
                    break; // パスワードが一致しない
                }
                $imageSize = getimagesize($_FILES['photo']['tmp_name']);
                if( $imageSize[2] != 2 ){     // 1:GIF 2:JPEG 3:PNG
                    $err = "<hr>"."ERROR : JPEG format only."."<br>";
                    break; // 画像の形式が一致しない
                }
                $tmp = $_FILES['photo']['tmp_name'];
                $name = $_FILES['photo']['name'];
                $namePlus = date("YmdHis");
                $imageName = $dir.$namePlus."_".urlencode(basename($name));
                $comment = htmlspecialchars( $_POST["comment"] );
                move_uploaded_file($tmp, $imageName) 
                // 画像データをリサイズ
                list($w, $h) = getimagesize($imageName);
                $width = 480;
                $height = floor($h * ($width / $w));
                $inputImage  = imagecreatefromjpeg($imageName);
                $outputImage = imagecreatetruecolor($width, $height);
                imagecopyresampled(
                    $outputImage,$inputImage,0,0,0,0,$width,$height,$w,$h);
                imagejpeg($outputImage, $imageName);
                // ログファイルに追記
                $date = date("Y-m-d H:i:s");
                $newline = "{$imageName}\t{$comment}\t{$date}\n";
                array_unshift($log,$newline);
                file_put_contents($file, $log);
                $err = "";
                break; // 正常終了
            } while(0);
            echo $err;

            $html ="";
            // ログデータからHTMLを生成
            foreach($log as $line){
                list($imageName,$comment,$date) = split("\t",$line);
                $html .= <<<__DATA__
                    <hr>
                    <p><img src = '$imageName' width></p>
                    <p>$comment ($date) </p><br>
                __DATA__;
            }
            echo $html;
        ?>

    </body>
</html>

投稿された画像データと、コメントが逐次蓄積されていきます。

画像は幅480ピクセルにリサイズされて images フォルダに、またコメントは画像ファイル名と日付情報とともに log.txt というファイルに蓄積されます。
尚、事例6もパスワードがの入力と真偽判定を行う処理を追加しています。

プログラムの構文について
ちょっと変なかたちですが、do ~ while(0) という1回だけ動くループを使用しています。理由は、多数のチェック項目があるためです。投稿データはあるか?、パスワードは一致しているか?、データ形式はあっているか?、様々な条件をチェックし、異常があればそれに相当するエラーメッセージを生成して、処理を中断しなければなりません。if~ else だけで書くとプログラムが見づらくなるので、異常が発覚した時点で break で処理を抜けられるように do ~ while(0) を利用しました。



PAGES

GUIDE

DATA

Last-modified: 2020-02-02 (日) 17:52:42