# 数珠繋ぎのツイートシステムに予約機能を付けました😂 #php #code
おはようございます、偏頭痛持ちは雨が降るが一番大変です☔。
先日、[数珠繋ぎのツイートシステム](https://zip358.com/2022/10/04/twitter-api-v2%e3%83%84%e3%82%a4%e3%83%bc%e3%83%88%e6%95%b0%e7%8f%a0%e7%b9%8b%e3%81%8e-%e3%82%b3%e3%83%bc%e3%83%89%e5%85%ac%e9%96%8b-php.html)を作ったのですが、そのシステムに予約機能を付けました。尚、TwitterAPIのバージョン2でスケジュールのパラメーターが今のところ無いですね。これから先、機能が付くかも知れないですが今のところ無いようです。因みにソースコードは近日中に[Qiita](https://qiita.com/taoka-toshiaki)と[Github](https://github.com/taoka-toshiaki)にUPします。此処ではソースコードの一部を掲載します(**※記事を更新しました下へスクロール**🫠)。
[](https://www.youtube.com/watch?v=aaNzd5RsG4w)
尚、crontabでPHPファイルを叩くようにしています、あと注意事項ですが予約を一度した投稿については変更等は出来ません、編集機能等の機能追加の予定はないです。また、予約管理はsqlite3を使用して管理しています。
```
<?php
date_default_timezone_set('Asia/Tokyo');
ini_set("display_errors",0);
require_once "./data/tw-config-v2.php";
require_once "../vendor/autoload.php";
use Abraham\TwitterOAuth\TwitterOAuth;
class tw
{
var $connection = null;
var $pdo = null;
function __construct()
{
$this->connection = new TwitterOAuth(APIKEY, APISECRET, ACCESSTOKEN, ACCESSTOKENSECRET);
$this->connection->setApiVersion("2");
}
function db_connection()
{
try {
//code...
$res = $this->pdo = new PDO("sqlite:./data/tw-tweets-db.sqlite3");
} catch (\Throwable $th) {
//throw $th;
//print $th->getMessage();
$res = false;
}
return $res;
}
function timecheck($timeonoff, $times)
{
if (!$timeonoff) return true;
$n = new DateTime();
$t = new DateTime($times);
return $t <= $n ? true : false;
}
function pickup_tweets(mixed $tw_text = null, int $timeonoff = 0, mixed $times = null, string $id = "")
{
if (!$times) return false;
$obj = (object)[];
$times = preg_replace("/\-/", "/", $times);
$times = preg_replace("/T/", " ", $times);
if ($this->timecheck($timeonoff, $times)) {
if (isset($tw_text) && is_array($tw_text)) {
foreach ($tw_text as $key => $value) {
if (preg_replace("/[ | ]/", "", $value)) {
$obj = !$key ? ($this->connection->post("tweets", ["text" => $value], true)
) : ($this->connection->post("tweets", ["reply" => ["in_reply_to_tweet_id" => $obj->data->id], "text" => $value], true)
);
}
}
return true;
}
} else {
return $timeonoff ? $this->save_sqlite($tw_text, $timeonoff, $times, $id): true;
}
}
function save_sqlite($tw_text = null, int $timeonoff = 0, mixed $times = null, string $id = "")
{
if ($this->db_connection()) {
try {
//code...
if (isset($tw_text) && is_array($tw_text)) {
foreach ($tw_text as $key => &$value) {
if (preg_replace("/[ | ]/", "", $value)) {
$stmt = $this->pdo->prepare("insert into tweets (tw_id,user,times,tw_text)values(:tw_id,:user,:times,:tw_text)");
$stmt->bindValue(":tw_id", $key, PDO::PARAM_INT);
$stmt->bindValue(":user", $id, PDO::PARAM_STR);
$stmt->bindValue(":times", $times, PDO::PARAM_STR);
$stmt->bindValue(":tw_text", $value, PDO::PARAM_STR);
$stmt->execute();
}
}
}
$this->pdo = null;
return true;
} catch (\Throwable $th) {
//throw $th;
return false;
}
}
}
function tweets_load(string $id = "")
{
if (!$id) return false;
try {
//code...
$value = null;
if ($this->db_connection()) {
$stmt = $this->pdo->prepare("select * from tweets where user = :user order by times,tw_id asc;");
$stmt->bindValue(":user", $id, PDO::PARAM_STR);
$res = $stmt->execute();
$value = $res ? $stmt->fetchAll() : false;
$this->pdo = null;
}
return $value;
} catch (\Throwable $th) {
//throw $th;
return false;
}
}
function tweets_update(int $key = 0, int $timeonoff = 0, mixed $times = null, string $id = "",mixed $tw_text="")
{
try {
//code...
if(!preg_replace("/[ | ]{0,}/","",$tw_text))return false;
if ($this->db_connection()) {
$stmt = $this->pdo->prepare("update tweets set tw_text = :tw_text where tw_id = :tw_id and user = :user and times = :times");
$stmt->bindValue(":tw_id", $key, PDO::PARAM_INT);
$stmt->bindValue(":user", $id, PDO::PARAM_STR);
$stmt->bindValue(":times", $times, PDO::PARAM_STR);
$stmt->bindValue(":tw_text", $tw_text, PDO::PARAM_STR);
$stmt->execute();
$this->pdo = null;
}
} catch (\Throwable $th) {
//throw $th;
return false;
}
return true;
}
function tweets_delete(int $key = 0, int $timeonoff = 0, mixed $times = null, string $id = "")
{
try {
//code...
if ($this->db_connection()) {
$stmt = $this->pdo->prepare("delete from tweets where tw_id = :tw_id and user = :user and times = :times");
$stmt->bindValue(":tw_id", $key, PDO::PARAM_INT);
$stmt->bindValue(":user", $id, PDO::PARAM_STR);
$stmt->bindValue(":times", $times, PDO::PARAM_STR);
$stmt->execute();
$this->pdo = null;
}
} catch (\Throwable $th) {
//throw $th;
return false;
}
return true;
}
function bat_tweets(mixed $value = null)
{
if (!$value) return false;
$obj = (object)[];
$t = "";
foreach ($value as $key => $val) {
if ($this->timecheck(1, $val["times"])) {
$obj = ($val["times"]<>$t)? ($this->connection->post("tweets", ["text" => $val["tw_text"]], true)
) : ($this->connection->post("tweets", ["reply" => ["in_reply_to_tweet_id" => $obj->data->id], "text" => $val["tw_text"]], true)
);
$this->tweets_delete($val["tw_id"], 1, $val["times"], $val["user"]);
$t = $val["times"];
} else {
// var_dump($val);
// break;
}
}
}
}
if ($argv[0]) {
$tw = new tw();
$value = $tw->tweets_load(xss_d($argv[1]));
$tw->bat_tweets($value);
}
function xss_d($val = false)
{
if (is_array($val)) {
foreach ($val as $key => $value) {
$val[$key] = strip_tags($value);
$val[$key] = htmlspecialchars($val[$key]);
}
} else {
$val = strip_tags($val);
$val = htmlspecialchars($val);
}
return $val;
}
```
**追記:予約編集機能なども付けました🙄。**
GithubとQiitaのリンクはこちらです。
Github:<https://github.com/taoka-toshiaki/tweets-system-box1>
Qiita:<https://qiita.com/taoka-toshiaki/items/5ef12b60b267742bf584>
[  成功体験と成功の模倣.
](https://zip358.com/2026/02/05/%e6%88%90%e5%8a%9f%e4%bd%93%e9%a8%93%e3%81%a8%e6%88%90%e5%8a%9f%e3%81%ae%e6%a8%a1%e5%80%a3.html)
[  サイトを分離した話を黙々と書いていきます.
](https://zip358.com/2026/02/04/%e3%82%b5%e3%82%a4%e3%83%88%e3%82%92%e5%88%86%e9%9b%a2%e3%81%97%e3%81%9f%e8%a9%b1%e3%82%92%e9%bb%99%e3%80%85%e3%81%a8%e6%9b%b8%e3%81%84%e3%81%a6%e3%81%84%e3%81%8d%e3%81%be%e3%81%99.html)
[  半額セールでアドビ様を延長.
](https://zip358.com/2026/02/03/%e5%8d%8a%e9%a1%8d%e3%82%bb%e3%83%bc%e3%83%ab%e3%81%a7%e3%82%a2%e3%83%89%e3%83%93%e6%a7%98%e3%82%92%e5%bb%b6%e9%95%b7.html)
[  何の前触れもなく変えたのは初めてかも.
](https://zip358.com/2026/02/02/%e4%bd%95%e3%81%ae%e5%89%8d%e8%a7%a6%e3%82%8c%e3%82%82%e3%81%aa%e3%81%8f%e5%a4%89%e3%81%88%e3%81%9f%e3%81%ae%e3%81%af%e5%88%9d%e3%82%81%e3%81%a6%e3%81%8b%e3%82%82.html)
[  跳ねたいサイトで跳ねたい
](https://zip358.com/2026/02/01/%e8%b7%b3%e3%81%ad%e3%81%9f%e3%81%84%e3%82%b5%e3%82%a4%e3%83%88%e3%81%a7%e8%b7%b3%e3%81%ad%e3%81%9f%e3%81%84.html)