こいちゃんの趣味全開!!

クリエイターズネットワーク参加サイトのひとつ。趣味を書き綴ります。そこのあなた、お願い、ひかないでーっ。

/wwwroot/write.php

2012.11/17 by こいちゃん

送られてきた投稿をデータベースの該当するテーブルに保存するスクリプト。

<?php
require_once('login.php');
require_once('function.php');
$bbs_target = target_set();
$location = "Location: ./bbs.php?target=$bbs_target";

#ユーザーのアクセス権を取得
if($Auth_data['username'] == 'admin') {
	if($bbs_target == 'history') {
		$usermod = 2;
	} else {
		#管理者は基本的に読み込みだけ
		$usermod = 1;
	}
} elseif($bbs_target == 'main') {
	#mainスレッドはだれでも読み書き可能
	$usermod = 2;
} else {
	$result_get_usermod = get_usermod($Auth_data['username'], $bbs_target);
	if($result_get_usermod[0]) {
		$usermod = $result_get_usermod[1];
	} else {
		echo 'get_usermod: '.$result_get_usermod[1];
	}
}
if($usermod == 0 or $usermod == 1) {
	echo "このスレッドに書き込む権限を持っていません。送信されたデータを破棄しました。<br />\n";
	echo "<a href=\"./bbs.php?target=$bbs_target\">戻る</a>";
	exit;
}

#データ整形
if($_POST['user'] == $Auth_data['username']) {
	$stmt = $db->prepare("SELECT id FROM auth WHERE username=:user");
	$stmt->bindParam(':user', $Auth_data['username']);
	$flag = $stmt->execute();
	if (!$flag) {
		$info = $stmt->errorInfo();
		echo($info[2]);
		echo("ユーザーIDが正常に取得できませんでした。\n書き込みを強制的に終了しました。<br />\n");
		echo("<a href=\"./bbs.php?target=$bbs_target\">戻る</a>");
		exit();
	}
	
	$id = $stmt->fetch();
	$id = (int) $id[0];
} else {
	echo "投稿者名が不正です。<br />\n";
	echo "<a href=\"./bbs.php?target=$bbs_target\">戻る</a>";
	exit;
}
if($_POST['sub'] != '') {
	$sub = htmlspecialchars($_POST['sub']);
} else {
	$sub = '<無題>';
}
$data = htmlspecialchars($_POST['data']);
$data = nl2br($data);
$data = preg_replace("{(https?|ftp)(://[[:alnum:]\+\$\;\?\.%,!#~\/:@&=_-]+)}", "<a href=\"$1$2\" target=\"_blank\">$1$2</a>", $data);		//URL自動リンク化
if(isset($_POST['monospace-font']) and $_POST['monospace-font'] == 'true') {
	$monospace = 1;
} else {
	$monospace = 0;
}
$date = date("Y.m/d (D) H:i:s");
$remote = $_SERVER['REMOTE_ADDR'];
$browser = $_SERVER['HTTP_USER_AGENT'];

if(strlen($data) == 0 and strlen($sub) == 0) {
	echo "件名、本文のどちらもデータがありませんでした。送信されたデータを破棄しました。<br />\n";
	echo "<a href=\"./bbs.php?target=$bbs_target\">戻る</a>";
	exit;
}

$sql = "INSERT INTO {$bbs_target} (user, subject, body, date, ip_addr, browser, monospace) ".
	"VALUES(:user, :sub, :body, :date, :ip_addr, :browser, :monospace)";
$stmt = $db->prepare($sql);
$stmt->bindParam(':user', $id, PDO::PARAM_INT);
$stmt->bindParam(':sub', $sub);
$stmt->bindParam(':body', $data);
$stmt->bindParam(':date', $date);
$stmt->bindParam(':ip_addr', $remote);
$stmt->bindParam(':browser', $browser);
$stmt->bindParam(':monospace', $monospace, PDO::PARAM_BOOL);

$flag = $stmt->execute();
if (!$flag) {
	$info = $stmt->errorInfo();
	echo($info[2]);
	echo("データベースへ書き込みが出来ませんでした。\n書き込みを強制的に終了しました。<br />\n");
	echo("<a href=\"./bbs.php?target=$bbs_target\">戻る</a>");
	exit;
} else {
	header($location);
	exit;
}
?>

基本的にこのページは何も出力しません。処理が終わったらさっさと元のページに転送してしまいます。

5行目
転送先ページのURLを作成します。

8~25行目
/wwwroot/load.phpと同じくユーザーのアクセス権を取得します。

26~30行目
念のため、書き込み権限を持っていないユーザーから書き込みリクエストが来た時のために、データを破棄する旨のメッセージを用意しておきます。

33~51行目
フォームデータで送られてきたユーザー名がログイン中のユーザー名と等しいか確認します。
等しければテーブルに書き込むために必要なユーザーIDをデータベースから取得し、変数$idに代入します。
等しくなければエラーメッセージを出力します。

52~56行目
フォームデータで送られてきた件名を確認します。
空であれば代わりに <無題> を、空でなければHTMLにおいて特殊な文字列を取り除いてから変数$subに代入します。

57~59行目
本文を整形します。
まず改行をHTMLで表現できるよう、<br />タグに置換します。
その後URLを正規表現で検索し、リンクに変換します。

60~64行目
固定幅フォントのフラグを検知し、フラグが立っていれば変数$monospaceに1を、立っていなければ0を代入します。

65~67行目
投稿日時、投稿者のIPアドレス、使っているブラウザの種類をあらかじめ取得しておきます。

69~73行目
本文・件名どちらも空だった場合は保存を中止して元のページに戻します。

75~84行目
ここまでで整形したデータをデータベースに保存するためのSQLを作成します。
SQLインジェクションを防ぐため、ステートメントを使ってデータを挿入します。記事通し連番はデータベース側が自動的につけるので指定する必要はありません。
手順としては穴だらけのSQLテンプレートを一時的に変数に保存し、SQLテンプレートを確定させます。その後穴を埋めるように整形した変数値で穴を置換していきます。

86~96行目
完成したSQLを実行します。
エラーが発生した場合はエラーメッセージを、正常に完了した場合は元のページに転送します。

Tags: ,

Posted in PHPで動く掲示板プログラム |

Comments are closed.