SQLiteな休日
1. 準備 SQLiteなお気に入り

それではもうちょっと手を加えて実際に使用したくなるようなものにしてみます。(主に見栄え)

カテゴリ項目を追加して区切りをつけます。それにより項目は
id 〕, 〔 category 〕, 〔 sitename 〕, 〔 url 〕, 〔 comment 〕, 〔 sort 〕の6つとします。

今回は新規にデータベースファイルを作成しますが、テーブル定義まで含めphpスクリプトから作成しました。
下図のように 〔 db 〕 ディレクトリ(書込権限有り)を準備してから set.php を実行すると、テーブル定義済みのデータベースファイル favorites.db を作成します。

以下、 set.php のソース。

<?php
mb_language("ja");
mb_internal_encoding("UTF-8");
?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>DB_SET</title>
</head>
<body>
<?php
$file = "./db/favorites.db"; //データベースファイル定義
if (file_exists("$file")) { //データベースファイルがあれば
print "データベースは存在します。";
}
else {
$data = sqlite_open("$file"); //作成
$query = "create table table1 (id INTEGER PRIMARY KEY,category VARCHAR(50),sitename VARCHAR(50),url VARCHAR(50),comment VARCHAR(200),sort INTEGER(10))"; //クエリの定義
$result = sqlite_query ($data,$query); //実行
sqlite_close($data); //切断
print "データベースを作成しました。";
}
?>
</body>
</html>

2. 多重書込を防止するため処理の順序を変更

前回までは無視していましたが、多重書込を防止するために処理の順序を変更しています。
(このリンク集の場合書き込むのは本人だけですし、間違って2重に書き込んでしまったとしても削除すれば良いのですが。)
処理の流れだけ書くと、

POSTで "pass" があった場合…
 "delline" があった場合…削除処理後 Locationでスクリプトを呼び出して終了する。
 "ediline" があった場合…編集処理後 Locationでスクリプトを呼び出して終了する。
 それ以外…新規書込処理後 Locationでスクリプトを呼び出して終了する。

以上の処理を
<html>
出力前に行っています。

3. スクリプトのソース

それではソースです。
6行目から、〔スクリプト名〕、〔データベース名〕、〔管理者パスワード〕、〔最大保存件数〕 を設定する行をもうけました。
この4項目に関して、以降は変数名を使用しています。
(ほとんど無意味なんですが、いちおう 〔最大保存件数〕 を越えると sort 最下位の行を自動で削除します。)

<?php
mb_language("ja");
mb_internal_encoding("UTF-8");

//設定開始
$filename = "./index.php"; //スクリプト名
$dbname = "./db/favorites.db"; //データベース名
$adpass = "hoge"; //管理者パスワード
$maxline = 99999; //最大保存件数
//設定終わり

$dline = $maxline-1; //自動消去の設定

if ($_POST["pass"] == $adpass) { //パスワードが正しければ
if ($_POST["sort"]) {
$sort = $_POST["sort"];
$sort = trim(mb_convert_kana($sort, "a")); //全角を半角に
$sort = htmlspecialchars ($sort); //HTMLタグ禁止
if( get_magic_quotes_gpc() ) { $sort = stripslashes("$sort"); } //クォートをエスケープする
$sort = mb_strimwidth ($sort, 0, 5, "", "UTF-8"); //長いデータを5バイトでカット
}
else {
$sort = 1;
}
$sortmax = 0; //$sort の値を決める
$file = $dbname; //データベースファイル定義
$data = sqlite_open("$file"); //オープン
$query = "select * from table1"; //クエリの定義(SelectAll)
$result = sqlite_query ($data,$query); //実行

$i = 1;
while ($scan[$i] = sqlite_fetch_array ($result)) { //全ての行(レコード)を配列に入れる
if ($scan[$i][5] > $sortmax) {
$sortmax = $scan[$i][5]; //最大値
}
$i++;
}
$sortmax++; //最大値+1
if ($sort < 1) {
$sort = 1;
}
else {
if ($sort > $sortmax) {
$sort = $sortmax;
}
if (!preg_match("/^[0-9]+$/",$sort)) { //半角数字でない
$sort = 1;
}
sqlite_close($data); //切断
if ($_POST["sitename"] != "") { //サイト名に入力があれば
$sitename = $_POST["sitename"]; //POSTのデータを変数$sitenameに格納
$sitename = htmlspecialchars ($sitename); //HTMLタグ禁止
if( get_magic_quotes_gpc() ) { $sitename = stripslashes("$sitename"); } //クォートをエスケープする
$sitename = mb_strimwidth ($sitename, 0, 40, "", "UTF-8"); //長いデータを40バイトでカット

$category = $_POST["category"]; //POSTのデータを変数$categoryに格納
$category = htmlspecialchars ($category); //HTMLタグ禁止
if( get_magic_quotes_gpc() ) { $category = stripslashes("$category"); } //クォートをエスケープする
$category = mb_strimwidth ($category, 0, 1000, "", "UTF-8"); //長いデータを100バイトでカット

$url = $_POST["url"]; //POSTのデータを変数$urlに格納
$url = htmlspecialchars ($url); //HTMLタグ禁止
if( get_magic_quotes_gpc() ) { $url = stripslashes("$url"); } //クォートをエスケープする
$url = mb_strimwidth ($url, 0, 200, "", "UTF-8"); //長いデータを200バイトでカット

$comment = $_POST["comment"]; //POSTのデータを変数$commentに格納
$comment = htmlspecialchars ($comment); //HTMLタグ禁止
$comment = str_replace("¥r¥n", "¥r", $comment); //Windowsの改行コードを置き換え
$comment = str_replace("¥r¥n", "¥r", $comment); //Windowsの改行コードを置き換え
$comment = str_replace("¥r", "¥n", $comment); //Machintoshの改行コードを置き換え
$comment = str_replace("¥n", "<br />", $comment); //¥nを<br />に変換(保存・表示用)
if( get_magic_quotes_gpc() ) { $url = stripslashes("$url"); } //クォートをエスケープする
$comment = mb_strimwidth ($comment, 0, 200, "", "UTF-8"); //長いデータを200バイトでカット

}

if ($_POST["delline"]) { //削除処理
$delline = $_POST["delline"]; //削除行の特定(GETされた id による)
$file = $dbname; //データベースファイル定義
$data = sqlite_open("$file"); //オープン
//削除に伴う sort の書き替え
$query = "select * from table1"; //クエリの定義(SelectAll)
$result = sqlite_query ($data,$query); //実行
$i = 1;
while ($scan[$i] = sqlite_fetch_array ($result)) {
$i++;
}
for($i=0; $i<count($scan); $i++) { //1行づつ走査しながら表示
if ($scan[$i][5] > $sort) {
$id = $scan[$i][0];
$oldsort = $scan[$i][5];
$newsort = $oldsort - 1;
$query = "update table1 set sort='$newsort' where id='$id'"; //クエリの定義(update による更新)
$result = sqlite_query ($data,$query); //実行
}
}
$query_del = "delete from table1 where id='$delline'"; //クエリの定義(削除)
$result_del = sqlite_query ($data,$query_del); //実行
sqlite_close($data); //切断
header("Location: $filename"); //本スクリプトをを呼び出して
exit; //終了する
}

elseif ($_POST["ediline"]) { //編集処理
$ediline = $_POST["ediline"]; //編集行の特定(GETされた id による)
$file = $dbname; //データベースファイル定義
$data = sqlite_open("$file"); //オープン
$query = "update table1 set category='$category',sitename='$sitename',url='$url',comment='$comment',sort='$sort' where id='$ediline'"; //クエリの定義(update による更新)
$result = sqlite_query ($data,$query); //実行
sqlite_close($data); //切断
header("Location: $filename"); //本スクリプトをを呼び出して
exit; //終了する
}

else { //新規投稿処理
$sortm = $sort-1;
$file = $dbname; //データベースファイル定義
$data = sqlite_open("$file"); //オープン
//回しながら sort の+1
$query = "select * from table1"; //クエリの定義(SelectAll)
$result = sqlite_query ($data,$query); //実行
$i = 0;
while ($scan[$i] = sqlite_fetch_array ($result)) { //全ての行(レコード)を配列に入れる
$id = $scan[$i][0];
$newsort = $scan[$i][5];
if ($newsort > $sortm) {;
$newsort++;
if ($newsort > $dline) { //貯めるのは(最大保存件数)行
$query_del = "delete from table1 where id='$id'"; //クエリの定義(削除)
$result_del = sqlite_query ($data,$query_del); //実行
}
else {
$query_up = "update table1 set sort='$newsort' where id='$id'"; //クエリの定義(update による更新)
$result_up = sqlite_query ($data,$query_up); //実行
}
}
$i++;
}
$id = $scan[$i][0];
$query = "insert into table1 values(null,'$category','$sitename','$url','$comment','$sort')"; //クエリの定義(レコード追加)
$result = sqlite_query ($data,$query); //実行
sqlite_close($data); //切断
}
}
header("Location: $filename"); //本スクリプトをを呼び出して
exit; //終了する
}

?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>SQLiteなお気に入り</title>
<style type="text/css"><!--
body {
margin:0;
padding:0;
}
br {
letter-spacing:0;
}
input {
border:1px solid lightsteelblue;
}
textarea {
border:1px solid lightsteelblue;
}
a:link { color:blue;text-decoration:none; }
a:active { text-decoration:none; }
a:visited { color:blue;text-decoration:none; }
a:hover { text-decoration:underline; }
.top {
padding:4px;
width:100%;
background-color:steelblue;
text-align:center;
color:white;
}
.frame {
width:100%;
text-align:center;
}
.main {
width:740px;
margin-left:auto;
margin-right:auto;
}
td.space {
width:740px;
height:12px;
}
td.category {
width:740px;
background-color:lightsteelblue;
padding-top:3px;
padding-bottom:1px;
padding-left:12px;
text-align:left;
color:steelblue;
}
table.maintable {
width:740px;
margin-left:auto;
margin-right:auto;
}
td.id {
width:40px;
padding:4px;
font-size:85%;
text-align:right;
line-height:130%;
color:lightsteelblue;
}
td.itemsort {
width:40px;
padding:4px;
font-size:85%;
text-align:right;
line-height:130%;
color:steelblue;
border-bottom-width:1px;
border-bottom-style:dotted;
border-bottom-color:lightsteelblue;
}
td.itemed {
width:30px;
padding:4px;
font-size:85%;
text-align:center;
line-height:130%;
color:lightsteelblue;
border-bottom-width:1px;
border-bottom-style:dotted;
border-bottom-color:lightsteelblue;
}
td.item240 {
width:240px;
padding:4px;
font-size:85%;
text-align:left;
line-height:130%;
color:steelblue;
border-bottom-width:1px;
border-bottom-style:dotted;
border-bottom-color:lightsteelblue;
}
td.item360 {
width:360px;
padding:4px;
font-size:85%;
text-align:left;
line-height:130%;
color:steelblue;
border-bottom-width:1px;
border-bottom-style:dotted;
border-bottom-color:lightsteelblue;
}
.for {
width:460px;
margin-top:80px;
margin-bottom:40px;
text-align:left;
margin-left:auto;
margin-right:auto;
}
.foritem {
font-size:85%;
color:steelblue;
margin-top:6px;
margin-bottom:2px;
}
.bottom {
width:100%;
margin-bottom:12px;
font-size:75%;
letter-spacing:1px;
color:lightsteelblue;
text-align:center;
}
--></style>
</head>
<body>
<div class="top">SQLiteなお気に入り</div>
<?php

if ($_GET["edit"]) { //編集画面(Edi クリックで来た場合)
$edit = $_GET["edit"]; //編集行の特定(GETされた id による)
$file = $dbname; //データベースファイル定義
$data = sqlite_open("$file"); //オープン
$query = "select id,category,sitename,url,comment,sort from table1 where id='$edit'"; //クエリの定義(value= 用に category とsitename と url と comment と sort を取り出す)
$result = sqlite_query ($data,$query); //実行
$scan = sqlite_fetch_array ($result); //配列に入れる
sqlite_close($data); //切断
print "<div class='frame'>¥n";
print "<div class='for'>¥n";
print "<div class='foritem'>▼編集する</div>¥n";
print "<form method='POST' action='" . $filename . "'>¥n";
print "<div class='foritem'>カテゴリ</div>¥n";
print $scan[1] . "<br />¥n";
print "<div class='foritem'>サイト名</div>¥n";
print "<input type='text' name='sitename' size='50' value='" . $scan[2] . "' /><br />¥n";
print "<div class='foritem'>URL</div>¥n";
print "<input type='text' name='url' size='50' value='" . $scan[3] . "' /><br />¥n";
print "<div class='foritem'>コメント</div>¥n";
$edcomment = str_replace("<br />", "¥n", $scan[4]); //<br />を¥nに変換
print "<textarea name='comment' rows='4' cols='60'>" . $edcomment . "</textarea><br />¥n";
print "<div class='foritem'>パスワード</div>¥n";
print "<input type='password' name='pass' size='20' /><br />¥n";
print "<input name='ediline' type='hidden' value='" . $edit . "' />¥n";
print "<input name='category' type='hidden' value='" . $scan[1] . "' />¥n";
print "<input name='sort' type='hidden' value='" . $scan[5] . "' />¥n";
print "<div class='foritem'><input type='submit' value='送信' /></div>¥n";
print "</form>¥n";
print "</div>¥n";
print "</div>¥n";
}

elseif ($_GET["delete"]) { //削除画面(Del クリックで来た場合)
$delete = $_GET["delete"]; //削除行の特定(GETされた id による)
$file = $dbname; //データベースファイル定義
$data = sqlite_open("$file"); //オープン
$query = "select id,category,sitename,url,comment,sort from table1 where id='$delete'"; //クエリの定義(category と sitename と url と comment と sort を取り出す)
$result = sqlite_query ($data,$query); //実行
$scan = sqlite_fetch_array ($result); //配列に入れる
sqlite_close($data); //切断
print "<div class='frame'>¥n";
print "<div class='for'>¥n";
print "<div class='foritem'>▼以下の記事を削除する</div>¥n";
print "<form method='POST' action='" . $filename . "'>¥n";
print "<div class='foritem'>【カテゴリ】</div>¥n";
print $scan[1] . "<br />¥n";
print "<div class='foritem'>【サイト名】</div>¥n";
print $scan[2] . "<br />¥n";
print "<div class='foritem'>【URL】</div>¥n";
print $scan[3] . "<br />¥n";
print "<div class='foritem'>【コメント】</div>¥n";
print $scan[4] . "<br />¥n";
print "<div class='foritem'>【パスワード】</div>¥n";
print "<input type='password' name='pass' size='20' /><br />¥n";
print "<input name='delline' type='hidden' value='" . $delete . "' />¥n";
print "<input name='sort' type='hidden' value='" . $scan[5] . "' />¥n";
print "<div class='foritem'><input type='submit' value='送信' /></div>¥n";
print "</form>¥n";
print "</div>¥n";
print "</div>¥n";
}

else { //編集画面・削除確認画面以外

$file = $dbname; //表示(データベースファイル定義)
$data = sqlite_open("$file"); //オープン
$query = "select * from table1 order by sort"; //クエリの定義(sort の値順でソート)
$result = sqlite_query ($data,$query); //実行
$i = 0;
while ($scan[$i] = sqlite_fetch_array ($result)) { //全ての行(レコード)を配列に入れる
$i++;
}
$count = $i;

print "<div class='frame'>¥n";
print "<table border='0' class='maintable'>¥n";
$ca = "hoge";
for($i=0; $i<$count; $i++) { //1行づつ走査しながら表示します
if ($scan[$i][0] != "") {
if ($ca != $scan[$i][1]) {
print "<tr><td colspan='6' class='space'>&nbsp;</td></tr>¥n";
print "<tr><td colspan='6' class='category'>" . $scan[$i][1] . "</td></tr>¥n";
$ca = $scan[$i][1];
}
print "<tr><td class='id'>" . $scan[$i][0] . "</td><td class='item240'><a href='" . $scan[$i][3] . "' target='_blank'>" . $scan[$i][2] . "</a></td><td class='item360'>" . $scan[$i][4] . "</td><td class='itemsort'>" . $scan[$i][5] . "</td><td class='itemed'><a href='" . $filename . "?edit=" . $scan[$i][0] . "'>edi</a></td><td class='itemed'><a href='" . $filename . "?delete=" . $scan[$i][0] . "'>del</a></td></tr>¥n";
}
}
print "</table>¥n";
sqlite_close($data); //切断
?>
<div class="for">
<div class="foritem">▼ 追加する場合はこちらから(管理人のみ)</div>
<form method="POST" action="<?php print $filename; ?> ">
<div class="foritem"><input type="text" name="sort" size="3" /> 番目に追加する</div>
<div class="foritem">カテゴリ</div>
<input type="text" name="category" size="50" /><br />
<div class="foritem">サイト名</div>
<input type="text" name="sitename" size="50" /><br />
<div class="foritem">URL</div>
<input type="text" name="url" size="50" /><br />
<div class="foritem">コメント</div>
<textarea name="comment" rows="4" cols="60"></textarea><br />
<div class="foritem">パスワード</div>
<input type="password" name="pass" size="20" /><br />
<div class="foritem"><input type="submit" value="送信" /></div>
</form>
</div>
</div>
<?php
} //編集画面以外 終わり
?>
</body>
</html>

新しいウインドウで表示

 ↑ こちらは管理人のみ書き込み出来ます。試してみたい方は下記 zip ファイルをダウンロードしてご自身の環境でお試しください。


うまくスクリプトが書けない方、すぐには環境(エディタなど)が整わない方、とにかく設置して動作を見たい方のために こちら からzip形式をダウンロードできるようにしました。

2014.2.4 last edit

Produced by haku