PHP Sample Code
Counter / Simple Line BBS / File Upload
アクセスカウンター、簡易掲示板、画像のアップロードについて紹介します。ソースコード中の関数の詳細については(PHPマニュアル)で確認して下さい。
ここでのサンプルは、サーバー内のデータを書き換えたり、フォルダ内にデータを送り込んだりするものです。しかし、一般にサーバーの初期設定ではサーバー内の操作を認めていませんので、「このファイルはオーナー以外の人の操作でも書き換えて構いません」という設定に変える必要があります。
サーバー内に設置したファイルやフォルダについては、必要に応じてパーミッションの変更を行って下さい。サーバーにアップしたファイル・フォルダについてはFTPソフトで属性の変更、XAMPP等で試している方は、ファイルのプロパティーを表示してアクセス権の変更…です。
事例5:簡易アクセスカウンター
- DEMO:https://design.kyusan-u.ac.jp/SampleSite/PHP_AC/
- CODE:https://github.com/koichi-inoue/PHP_Sample05
このサンプルでは、同一のディレクトリに、 index.php と count.txt の2つのファイルが必要です。
- count.txt
0
count.txt という名前のファイルを同一ディレクトリに置くことが必要です。
数字を1つ記憶しているだけなので、初期値として「 0 」のみ記述したファイルを準備して下さい。
尚、count.txt は 初期状態が 0 + 改行 ではダメなので、エディタが保存時に勝手に改行を書くようであれば、何も書かない空ファイルでお試し下さい。
2回め以降のアクセスでは、まずファイルからデータを取り出して、カウントを一つ増やして、また書き込む…という動作をします。
count.txt は書き込み可能であることが前提です。 FTPツールで、count.txt のパーミッションを書き込み可にして下さい。
<?php ~ ?>の部分のコードを既存のあなたのページのソースに加える形で、カウンターを設置することが可能です。但し拡張子は .php にすることと、サーバーがPHPに対応していることが前提です。
事例6:簡易投稿掲示板
この事例では、投稿フォームからの送信に対して、自分自身をリロードする形で、データの書き込み処理と再表示を行っています。
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:画像投稿掲示板
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) を利用しました。