#author("2021-09-25T11:26:35+09:00;2020-02-02T17:52:42+09:00","default:inoue.ko","inoue.ko") #author("2026-07-28T16:02:46+09:00;2026-07-28T13:59:08+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/ -DEMO:https://design.cs.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/ -DEMO:https://design.cs.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/ -DEMO:https://design.cs.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) を利用しました。 ~ ~