Photo by NEOSiAM 2021 on Pexels.com

Sqliteで作った簡易掲示板のコードを配布致します。#php #code

2022.09.20

Logging

おはようございます。台風は過ぎ去りましたがせっかくの三連休が残念です💦。

今日は先日、Sqliteを使用して簡易掲示板を作ってみましたのでコードを配布致します、尚、PHP8の環境下で動作させています(PHP7系でも動作すると思います)。

Sqliteってnow()関数がなかったりだとか、Deleteする時に、noカラムを昇順しlimitを使用して削除出来ないだとか、いろいろとMysqlとは違う所があり、面倒だなと思いながらコードを書きました、尚、SqliteはWebサーバーの階層に置かないように、置いても良いですが・・・。そのままの状態だと誰でもダウンロードが可能になってしまいますのでご注意ください。自分は地下に眠らしています😅。

一応、二重投稿防止の為に20秒経過しないと再投稿出来ないようにしています😌。トライしていない事は禁止ワード等がありません🤔。つけようと思ったのですがまぁ良いかなと、、、。

動作している環境のリンクはこちら。

https://reborn9.sakura.ne.jp/

軸となる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

OFUSEで応援を送る

タグ

20, 7, 8, Code, Delete, LIMIT, MYSQL, no, Now, php, Sqlite, web, いろいろ, カラム, コード, ご注意, サーバー, せっかく, そのまま, ダウンロード, トライ, ワード, 三連, , , 今日, , 使用, 先日, 削除, 動作, 可能, 台風, 地下, , 投稿, 掲示, 昇順, , 残念, , 状態, 環境, 禁止, 簡易, 経過, 自分, , , 配布, 関数, 防止, 階層, 面倒,

簡易的なメールフォームとメール送信のプログラムを書くのにかかる時間は?

2021.05.28

Logging

簡易的なメールフォームとメール送信のプログラムを書くのにかかる時間は?大体10分?15分ぐらいかと思います。本当はエラーチェックなどの機能をちゃんとした物に置き換える必要があるけど、ざっくり考え方はこれだけで良いじゃないかなと思っています。下記のコードを制作するのに参考にしたサイトのリンクを貼っときますね。

https://www.youtube.com/watch?v=xqg-zp2cHW8

https://techplay.jp/column/550https://techacademy.jp/magazine/19300

上記のコードを拝借してコードを書き、簡易的な二重送信防止対策と簡易的なエラーチェックをプログラミングしていますが、ここにreCAPTCHAなどの機能を入れてあげるとボット対策にもなるので良いかもしれません。ソースコードを見て後から気づいたのですが、ポストしているnameのデータを受け取っていない事があとから気づきました。因みにPOSTの生データが欲しいと言うときはこのように書くと取得することが可能ですよ。

<?php
 $data = file_get_contents('php://input');
?>
reCAPTCHA ENTERPRISE Updated Video
<?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/4.6.0/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.2/css/all.min.css">
<link rel="stylesheet" href="assets/css/style.css">
<title>sendmail</title>
</head>
<body>
	<div class="container">
		<div class="row">
			<div class="col-12">
				<form method="post" action="./sendmail.php">
					name<input class="form-control" type="text" name="name">
					email<input class="form-control" type="text" name="email">
					<div class="form-group">
						<label for="my-textarea">Text</label>
						<textarea id="my-textarea" class="form-control" name="text" rows="3"></textarea>
					</div>
					<input type="hidden" name="csrf_token" value="<?=$_SESSION['csrf_token']?>">
					<?=$_SESSION["sendmail"]!=="ok"?'<button class="btn btn-primary" type="submit">submit</button>':"NG"?>
				</form>
			</div>
		</div>
	</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.slim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.1/umd/popper.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.6.0/js/bootstrap.min.js"></script>
</body>
</html>
<?php
session_start();
?>
<!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/4.6.0/css/bootstrap.min.css">
	<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.2/css/all.min.css">
	<link rel="stylesheet" href="assets/css/style.css">
	<title>sendmail</title>
</head>

<body>
	<div class="container">
		<div class="row">
			<div class="col-12">
				<?= EmailSend() ?>
			</div>
		</div>
	</div>
	<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.slim.min.js"></script>
	<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.1/umd/popper.min.js"></script>
	<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.6.0/js/bootstrap.min.js"></script>
</body>

</html>
<?php

function EmailSend()
{

	$check = function ($val = "") {
		return isset($val) ? $val : false;
	};

	mb_language("Japanese");
	mb_internal_encoding("UTF-8");

	$to = $_POST['email'];
	$title = "test-mail";
	$message = $_POST['text'];
	$headers = "From: from@example.com";
	if (
		isset($_POST["csrf_token"])
		&& $_POST["csrf_token"] === $_SESSION['csrf_token']
	) {
		if (($check($to) && $check($title) && $check($message)) && mb_send_mail($to, $title, $message, $headers)) {
			$_SESSION["sendmail"] = "ok";
			return "メール送信成功です";
		} else {
			$_SESSION["sendmail"] = "ng";
			return "メール送信失敗です";
		}
	} else {
		return "不正なリクエストです";
	}
	return false;
}

著者名  @taoka_toshiaki

※この記事は著者が40代前半に書いたものです.

Profile
高知県在住の@taoka_toshiakiです、記事を読んで頂きありがとうございます.
数十年前から息を吸うように日々記事を書いてます.たまに休んだりする日もありますがほぼ毎日投稿を心掛けています😅.
SNSも使っています、フォロー、いいね、シェア宜しくお願い致します🙇.
SNS::@taoka_toshiaki

OFUSEで応援を送る

タグ

10, 15, 2, 550, 8, cHW, column, com, https, jp, name, POST, reCAPTCHA, techplay, watch, www, xqg-zp, youtube, あと, エラー, コード, ここ, これだけ, サイト, ソース, チェック, デー, データ, フォーム, プログラミング, プログラム, ポスト, ボット, メール, リンク, 上記, 下記, , , 制作, 参考, 大体, 対策, , 必要, 拝借, 時間, 本当, 機能, , , 簡易的, 考え方, 送信, 防止,

不老不死研究をしている機関

2020.05.15

Logging

たまには、こういうネタも?

キャラコという企業は老化やそれに伴う疾病を防止することに取り組んでいる。この企業、グーグルの機関であり、真剣に不老不死の研究を行っている。まずはアンチエイジングだけど、最終目標は不老不死だから・・・。

不老不死になるというのは、いまはまだ難しいかもしれないけれど、老化を遅らすのは可能かなと思っています。何故なら20代ではわからないだろうけど、30代、40代になるとよく分かるかと思います。同じ40代、30代を並べると老化している人とそうではない人とがよく分かるのです。これは生活習慣による老化や遺伝的に老化が早いひとがいるためです。みんな同じ様に老化すると思って20代を過ごしてしまうと30代、40代、50代になると差が広がっていきます。

いま、20代、30代の方、ご注意くださいね。ただ年相応に見られないと苦労することもありますが、若くいるということは最終的にはお得感があります。自分は若いまま長く生きたいと感じます。もしキャラコが老化防止する薬や若返りの薬を開発したのなら、間違いなくそれを購入します。

最後に興味がある方はどうぞ(リンクを貼っときます。)

https://www.calicolabs.com/

著者名  @taoka_toshiaki

※この記事は著者が40代前半に書いたものです.

Profile
高知県在住の@taoka_toshiakiです、記事を読んで頂きありがとうございます.
数十年前から息を吸うように日々記事を書いてます.たまに休んだりする日もありますがほぼ毎日投稿を心掛けています😅.
SNSも使っています、フォロー、いいね、シェア宜しくお願い致します🙇.
SNS::@taoka_toshiaki

OFUSEで応援を送る

タグ

20, 30, 40, 50, いま, エイジング, お得感, キャラコ, グーグル, こと, これ, ご注意, それ, たま, ため, ネタ, ひと, まま, みんな, 不老不死, , 企業, 可能, , 年相応, , 最終, 機関, 生活, 疾病, 目標, 真剣, 研究, 習慣, 老化, 自分, 苦労, 防止,

お部屋の温度と湿度を表示しています。密かに?

2020.04.26

Logging

お部屋の温度と湿度を表示しています、その情報を残すようにコードを書きました、スマホなどでは表示できないけれどPCでは表示可能です。自分が引き篭もりってあの時は寒かったなぁとかあの日は暑かったなぁという事を思い出すために作りました。因みにMY-ROOMのソースコードを見ると大体どんな仕様かわかると思います。

基本的に暑い日でも昼間はあまり冷房をつけないようにしていましたが、ここ数年、じぶんの暑さの限度を超えている日があり、そういう日はエアコンをつけてます。暑さは我慢できないのだけど、高知県ということもあり寒さにはある程度、我慢できて足温器だけで何とか生きていけます。今年はそれほど寒い日もなく暖冬かなと思います。ただ今年はとても暑くなりそうな気がします。

温暖化防止したいだけど・・・かなり暑いだよね。フロンは出していないのですが、それでも温暖化に影響有るだろうなぁと思いつつ。エアコンをつけてます。

ごめんなさい。

最後にMY-ROOMはこちら
https://zip358.com/my-room/

著者名  @taoka_toshiaki

※この記事は著者が40代前半に書いたものです.

Profile
高知県在住の@taoka_toshiakiです、記事を読んで頂きありがとうございます.
数十年前から息を吸うように日々記事を書いてます.たまに休んだりする日もありますがほぼ毎日投稿を心掛けています😅.
SNSも使っています、フォロー、いいね、シェア宜しくお願い致します🙇.
SNS::@taoka_toshiaki

OFUSEで応援を送る

タグ

MY-ROOM, PC, エアコン, お部屋, かなり, コード, ここ, こと, じぶん, スマホ, ソース, ため, フロン, , 今年, 仕様, 冷房, 可能, 影響, 情報, 我慢, , , 昼間, , 暖冬, , 温度, 温暖化, 湿度, 自分, 表示, 足温器, 防止, 限度, 高知県,

90歳ゲーマーYOUTUBERかなり!

2020.03.08

Logging

90歳のゲーマーYOUTUBERおばあちゃんが凄いというかかなり若い、先取りしていますね。おそらく日本でもこれから、こういうおばあちゃんやおじいちゃんが増えてくると思います。よくよく考えてください。いまのスマホ世代が高齢者になるとおそらくこういう老後生活になると思います。そして思うのです、手先も使うし頭も働かすからゲームってボケ防止にはかなり最適だと思いますし、孫とも会話が弾む可能性まであるだから良いのじゃないかと。

90歳オンラインゲーマーの日常 【ドーントレス】90-year-old gamer plays Dauntless

おばあちゃんゲーマーYOUTUBERは今の所、ニッチな分野ですね、当分は当たり前にならないと思いますので注目度があります、おばあちゃんは1930年生まれだということです、、、。その頃の写真があるかなとググって観たらいや凄いなと思いました。老いとは心が老いていくと駄目らしいですが、おばあちゃんからは、そういう事が微塵も感じませんゲームを楽しんでいらっしゃる!

最後にチャンネル登録はこちら
Gamer Grandma
https://www.youtube.com/channel/UCc7Ygo3HC1zWJOrtNiwuT3w/featured

著者名  @taoka_toshiaki

※この記事は著者が40代前半に書いたものです.

Profile
高知県在住の@taoka_toshiakiです、記事を読んで頂きありがとうございます.
数十年前から息を吸うように日々記事を書いてます.たまに休んだりする日もありますがほぼ毎日投稿を心掛けています😅.
SNSも使っています、フォロー、いいね、シェア宜しくお願い致します🙇.
SNS::@taoka_toshiaki

OFUSEで応援を送る

タグ

1930, 90, Gamer, Grandma, YOUTUBER, いま, おじいちゃん, おばあちゃん, かなり, ゲーマー, ゲーム, こちら, こと, これ, スマホ, チャンネル, ニッチ, ぼけ, 世代, , , 会話, , 写真, 分野, 可能性, , 当たり前, 当分, , , 手先, 日本, 最後, 最適, 注目, 生活, 登録, 老後, 防止, , , 駄目, 高齢者,

文字化けがモヤモヤした件:Unicodeめ!!とか機種依存文字とかの話。

2017.07.14

Logging


文字化けがモヤモヤした件:Unicodeめ!!とか機種依存文字とかの話。
会社でこちらの件でモヤモヤして最終的に解決できたのだけどなんだか腑に落ちないので自宅に帰って文字化けの検証をしてみました。勤めている会社はサイトコピー防止の為なのか、未だにEUC-JPコードで動いています(楽天とかもEUCだったりする🙄)。なので、会社のWEBシステムのファイルはEUCなのです。ブラウザ側がEUCだけどAjaxで送受信しているから強制的にUTF8で送られる?ので、PHP側で正しい文字コードで変換しないと文字化けするですね🤔。👈此処らへんサーバーサイドも絡んできます。
レスポンスされた文字コードも表面上は難なく表示されます。その戻ってきた文字をコピペしてWindowsのテキストファイルなどにペースト(貼り付ける)すると文字化けを起こす文字があります。
酷いときは文字が消える文字化け表示されるという問題がおきるのです。

その時、はてなって思った訳です🙄

何故・・・起きるのかPHPでエンコードするときの問題に変換にミスっていると思っていたが、そうではなかった。
WindowsエディタがSJISだったのです。要するにブラウザの文字コードとWINDOWSエディタの文字コードに違いがあった為、ある一部の文字コードで文字化けを起こしていました。

ブラウザ側がUTF8やEUC文字コードをエクセルファイルに貼り付けたら、一部の文字コードがバグったりします・・・。これは文字コードを扱うバイト領域等が違って起きる現象です。

追記2022/10/03:記事の文言を修正しました。

著者名  @taoka_toshiaki

※この記事は著者が30代前半に書いたものです.

Profile
高知県在住の@taoka_toshiakiです、記事を読んで頂きありがとうございます.
数十年前から息を吸うように日々記事を書いてます.たまに休んだりする日もありますがほぼ毎日投稿を心掛けています😅.
SNSも使っています、フォロー、いいね、シェア宜しくお願い致します🙇.
SNS::@taoka_toshiaki

OFUSEで応援を送る

タグ

8, ajax, EUC, euc-jp, php, Unicode, UTF-, web, Windows, コード, こちら, コピー, コピペ, サーバー, サイト, システム, テキスト, とき, ファイル, ブラウザ, ペースト, べん, レスポンス, , 会社, 依存, , 問題, 変換, 文字, 文字化け, 検証, 楽天, 機種, 此処ら, , , 自宅, 表示, 表面, 解決, , 送受信, 防止,