Sqliteで作った簡易掲示板のコードを配布致します。#php #code
2022.09.20
おはようございます。台風は過ぎ去りましたがせっかくの三連休が残念です💦。
今日は先日、Sqliteを使用して簡易掲示板を作ってみましたのでコードを配布致します、尚、PHP8の環境下で動作させています(PHP7系でも動作すると思います)。
Sqliteってnow()関数がなかったりだとか、Deleteする時に、noカラムを昇順しlimitを使用して削除出来ないだとか、いろいろとMysqlとは違う所があり、面倒だなと思いながらコードを書きました、尚、SqliteはWebサーバーの階層に置かないように、置いても良いですが・・・。そのままの状態だと誰でもダウンロードが可能になってしまいますのでご注意ください。自分は地下に眠らしています😅。
一応、二重投稿防止の為に20秒経過しないと再投稿出来ないようにしています😌。トライしていない事は禁止ワード等がありません🤔。つけようと思ったのですがまぁ良いかなと、、、。
動作している環境のリンクはこちら。
軸となるPHPのソースコードを2つ貼っときますね。
<?php
session_start();
$toke_byte = openssl_random_pseudo_bytes(16);
$csrf_token = bin2hex($toke_byte);
$_SESSION['csrf_token'] = $csrf_token;
?>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<meta name="Description" content="Enter your description here" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/5.1.0/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
<link rel="stylesheet" href="assets/css/style.css?<?= time() ?>">
<title>掲示板</title>
</head>
<body class="p-3 text-white">
<div class="p-4 shadow rounded" style="background-color:#d6dbdf;">
<div class="container mt-5">
<div class="row">
<div class="col-12 text-center">
<h1 class="shadow" style="color:#195a57;">掲示板::version 2.5</h1>
</div>
<div class="col-12">
<div class="input-group shadow rounded">
<div class="input-group-append">
<span class="input-group-text bg-dark text-white" id="my-addon">ニックネーム</span>
</div>
<input class="form-control" type="text" name="name" placeholder="ニックネームを入力" aria-describedby="my-addon">
</div>
<div class="form-group shadow rounded">
<label for="my-textarea">コメント</label>
<textarea id="my-textarea" class="form-control" name="comment" rows="7"></textarea>
</div>
<button id="btn" class="mt-2 btn btn-info text-white shadow rounded" type="button">投稿する</button>
</div>
</div>
</div>
<div class="container mt-5">
<div class="row">
<div id="view" class="col-12"></div>
</div>
</div>
</div>
<footer>
<a href="/">TOP</a> :: © Reborn9.sakura.ne.jp <?=date("Y")?>
</footer>
<input type="hidden" name="csrf_token" value="<?= $csrf_token ?>">
<script src="https://code.jquery.com/jquery-3.2.1.min.js" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/2.9.2/umd/popper.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/5.1.0/js/bootstrap.min.js"></script>
<script src="assets/js/main.js?<?= time() ?>"></script>
</body>
</html>
<?php
class db
{
var $pdo = null;
function __construct()
{
try {
$this->pdo = new PDO("sqlite:../../bbs.sqlite3");
$this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); //code...
} catch (\Throwable $th) {
//throw $th;
print $th->getMessage();
}
}
function select_limit()
{
if($this->pdo){
$stmt = $this->pdo->prepare('select * from bbs order by no desc limit 0,5');
$stmt->execute();
$result = $stmt->fetchAll();
$stmt = null;
$this->pdo = null;
return new view($result);
}
}
function insert($name,$comment,$sns_cnt=0)
{
try {
$stmt = $this->pdo->prepare('INSERT INTO bbs (`time`,`name`,`comment`,sns_cnt)values(strftime(\'%Y年%m月%d日 %H時%M分%S秒\',CURRENT_TIMESTAMP, \'localtime\'),:name,:comment,:sns_cnt)');
$stmt->bindParam(':name', $name, PDO::PARAM_STR);
$stmt->bindParam(':comment', $comment, PDO::PARAM_STR);
$stmt->bindParam(':sns_cnt', $sns_cnt, PDO::PARAM_INT);
$stmt->execute();
$stmt = $this->pdo->prepare('DELETE FROM bbs WHERE bbs.no = (SELECT no from bbs ORDER BY no ASC LIMIT 1);');
$stmt->execute();
$stmt = null;
$this->pdo = null;
return true;
} catch (\Throwable $th) {
print $th->getMessage();
return false;
}
}
}
class view{
var $item = null;
function __construct($item)
{
$this->item = $item;
}
function view_item($item="")
{
try {
$item = $item?$item:$this->item;
ob_start();
?>
<?php
foreach($item as $key=>$value){
?>
<div class="mt-2 row txtbox shadow rounded">
<div class="col-3 name_<?=$value["no"]?> rounded-start fs-6">
ニックネーム::<?=$value["name"]?>さん
</div>
<div class="col-9 time_<?=$value["no"]?> fs-6">
投稿日時::<?=$value["time"]?>
</div>
<div class="col-12 comment_<?=$value["no"]?>">
<?= nl2br($value["comment"])?>
</div>
<div class="col-12 sns_cnt_<?=$value["no"]?>">
<!-- <?=$value["sns_cnt"]?> -->
</div>
</div>
<?php
}
?>
<?php
$ret["view"]= ob_get_clean();
$ret["msg"]= "done";
} catch (\Throwable $th) {
//throw $th;
$ret["msg"] = "error";
}
return $ret;
}
}
session_start();
$ret = null;
$mode = xss_defence($_POST["mode"]);
// $time = ;
$name = xss_defence($_POST["name"]);
$comment = xss_defence($_POST["comment"]);
$sns_cnt = (int)xss_defence($_POST["sns_cnt"]);
if (isset($_POST["csrf_token"])
&& $_POST["csrf_token"] === $_SESSION['csrf_token'] && (function($t){
return time() - $t > 20?true:false;
})($_SESSION["save"])) {
if($mode==="save"){
$name = !preg_replace("/[ | ]/","",$name)?"匿名":$name;
$comment = !preg_replace("/[ | ]/","",$comment)?"":$comment;
if($comment){
$db = new db();
$db->insert($name,$comment);
$_SESSION["save"] = time();
}
}
$db = null;
$db = new db();
$ret = $db->select_limit()->view_item();
print json_encode($ret);
}
function xss_defence($value){
if(is_array($value)){
foreach($value as $key=>$val){
$value["$key"] = strip_tags($val);
$value["$key"] = htmlspecialchars($value["$key"],ENT_QUOTES);
}
}else{
$value = strip_tags($value);
$value = htmlspecialchars($value);
}
return $value;
}
配布コードはこちらです。
著者名 @taoka_toshiaki
※この記事は著者が40代前半に書いたものです.
Profile
高知県在住の@taoka_toshiakiです、記事を読んで頂きありがとうございます.
数十年前から息を吸うように日々記事を書いてます.たまに休んだりする日もありますがほぼ毎日投稿を心掛けています😅.
SNSも使っています、フォロー、いいね、シェア宜しくお願い致します🙇.
SNS::@taoka_toshiaki
タグ
20, 7, 8, Code, Delete, LIMIT, MYSQL, no, Now, php, Sqlite, web, いろいろ, カラム, コード, ご注意, サーバー, せっかく, そのまま, ダウンロード, トライ, ワード, 三連, 事, 二, 今日, 休, 使用, 先日, 削除, 動作, 可能, 台風, 地下, 所, 投稿, 掲示, 昇順, 時, 残念, 為, 状態, 環境, 禁止, 簡易, 経過, 自分, 良, 誰, 配布, 関数, 防止, 階層, 面倒,
NO LIMIT[ノーリミット]栗城史多さんの場合:自分を超える方法。
2014.08.22
依然、登山家、栗城史多さんが書かれたノーリミットと言う本を読みました。その後、アルプス?の登山時に凍傷で指を切断しないといけないという事になりました。しかし彼、栗城史多さんは切断しないという選択枠を模索していろいろと試した方です。結局、指を切断するという事に至ったのですが、その模索する過程で、もがき苦しみ、いろいろと学んだことがあると思います。自分が思うに指が無くなってからの方が、何だか真の登山家に見えてしまうのは自分だけなのかな?今は指を失った彼ですが、再生医療によりこの指が再生できるようになるのは、本当にあともう少しの話だと思います。ちなみに紛失した指や手を再生する技術は出来ています。あとは国の認可が降りるのを待つだけなのです{細胞外マトリックス:まとめ参照}。
著者名 @taoka_toshiaki
※この記事は著者が30代前半に書いたものです.
Profile
高知県在住の@taoka_toshiakiです、記事を読んで頂きありがとうございます.
数十年前から息を吸うように日々記事を書いてます.たまに休んだりする日もありますがほぼ毎日投稿を心掛けています😅.
SNSも使っています、フォロー、いいね、シェア宜しくお願い致します🙇.
SNS::@taoka_toshiaki
タグ
LIMIT, no, あと, アルプス, いろいろ, こと, ノーリミット, まとめ, マトリックス, 事, 今, 再生, 凍傷, 切断, 医療, 参照, 史多, 国, 場合, 彼, 後, 手, 技術, 指, 方, 方法, 本, 本当, 栗城, 模索, 登山, 登山家, 真, 紛失, 細胞, 自分, 話, 認可, 過程, 選択枠,