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