LogoMark.png

PHP/Sample02 の変更点


#author("2021-09-25T11:26:35+09:00;2020-02-02T17:52:42+09:00","default:inoue.ko","inoue.ko")
*PHP Sample Code
Counter / Simple Line BBS / File Upload
~


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

#contents2_1
#hr
~

***事例5:簡易アクセスカウンター

-DEMO:https://design.kyusan-u.ac.jp/SampleSite/PHP_AC/
-CODE:https://github.com/koichi-inoue/PHP_Sample05

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

-''index.php''
https://github.com/koichi-inoue/PHP_Sample05/blob/master/index.php

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

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

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

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


~

***事例6:簡易投稿掲示板
この事例では、投稿フォームからの送信に対して、自分自身をリロードする形で、データの書き込み処理と再表示を行っています。
-DEMO:https://design.kyusan-u.ac.jp/SampleSite/PHP_BBS/
~

''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()>http://php.net/manual/ja/function.htmlspecialchars.php]]という関数は、入力された文字列をそのまま処理系に渡すと、例えばHTMLタグに相当する文字がソースコードとして処理されてしまうなどの危険もあるので、念のためです。
// pass: webdesign
~
~

***事例7:画像投稿掲示板
-DEMO:https://design.kyusan-u.ac.jp/SampleSite/PHP_PHOTO/
~

''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) を利用しました。
~
~