数珠繋ぎのツイートシステムに予約機能を付けました😂 #php #code

2022.10.07

Logging

おはようございます、偏頭痛持ちは雨が降るが一番大変です☔。

先日、数珠繋ぎのツイートシステムを作ったのですが、そのシステムに予約機能を付けました。尚、TwitterAPIのバージョン2でスケジュールのパラメーターが今のところ無いですね。これから先、機能が付くかも知れないですが今のところ無いようです。因みにソースコードは近日中にQiitaGithubにUPします。此処ではソースコードの一部を掲載します(※記事を更新しました下へスクロール🫠)。

Twitter API v2 ツイート数珠繋ぎ

尚、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

著者名  @taoka_toshiaki

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

タグ

2, , 39, Asia, Code, crontab, date, default, github, ini, lt, php, qiita, Se, set, Sqlite, timezone, Tokyo, TwitterAPI, UP, コード, これ, システム, スクロール, スケジュール, ソース, ツイート, ところ, バージョン, パラメーター, ファイル, 一部, , 予定, 予約, 事項, , 使用, 偏頭痛, , 先日, 変更等, 大変, 投稿, 掲載, 数珠繋ぎ, 更新, 機能, 機能等, 此処, 注意, 管理, 編集, 記事, 近日, 追加, ,

1万件のCSVを読み込みテーブルに保存する雛形コード #PHPCode

2022.09.08

Logging

おはようございます、徐々に秋ぽっい日差しになってきましたね(まだ暑いけども😌)。

今日は、1万件のCSVを読み込みテーブルに保存する雛形コードを昨日、ちょちょっと書きましたので記載します。ファイルをダウンロードして使いたい方はGithubのリンクを下に貼っときますので、ご使用頂けたらと思います。尚、テーブルなどはCSVを参考にご自身で構えてください。

※動作環境はPHP8系です、なのでPHP7系では一部エラーが出ます。fgetcsv…nullを0へ変更。

Githubのリンクはこちら

Qiitaの方に記載しようかどうしようか、迷ったのですが第一弾目がアクセス数がそこそこ伸びたのでこれ以上、注目されるのは嫌なのでブログの方に記載しました。1万件のCSVを簡単に読み込ませる方法はPHPコードを書くのではなく、SQLのコマンドで実行した方が実は早いですけど・・・。

https://twitter.com/taoka_toshiaki/status/1567489169919975424
有言実行

早いですけど、その場合、CSVがちゃんとしたファイルではないと上手くテーブルに保存されない場合や、そもそもコマンドラインで操作出来ない場合もあったりしてPHPコードなどで制御しないと駄目な事もあります。そんな時に、このコードをサンプルとして使って頂ければ良いなと思い作りました。

1万件のCSVを読み込ませるPHPコード雛形。

そんなにコードを書かなくてもまぁ動くんですよ。ちなみにソースコードには、あまりコメントを書いていないですが、プログラマーなら大体の人が理解できるレベルかと思います。

<?php
//ini_set("display_errors","On");
session_start();
require "db_config.php";

//読み込みCSVファイル名セット
class csv
{
    /**
     * @param string $filename
     * @param int $cnt
     * @return Object
     */
    public function ini_csv($filename = "", $cnt = 0)
    {
        return new csv_read($filename, $cnt);
    }
}

//CSVデータを読み込ます
class csv_read
{
    var $max = 10000;
    var $cnt = 0;
    var $handle = null;
    /**
     * @param string $filename
     * @param int $cnt
     */
    public function __construct($filename = "", $cnt = 0)
    {
        $this->cnt = $cnt;
        $this->handle =  fopen($filename, "r");
        $_SESSION["offset"] ? fseek($this->handle, $_SESSION["offset"]) : $this->handle;
    }
    /**
     * @param int $header_skip
     * @return Object
     */
    public function reader($header_skip = 0)
    {
        if ($this->handle !== FALSE) {
            $response = null;
            $data = fgetcsv($this->handle, null, ",");
            if (!$header_skip || $_SESSION["offset"]) {
                if ($data !== FALSE) {
                    $_SESSION["offset"] = ftell($this->handle);
                    $response["data"] = $data;
                    $response["cnt"] = $this->cnt > $this->max ? 0 : ($this->cnt + 1);
                    $flag = true;
                } else {
                    $_SESSION["offset"] = null;
                    $flag = false;
                }
            } else {
                $_SESSION["offset"] = ftell($this->handle);
                $response["cnt"] = $this->cnt > $this->max ? 0 : ($this->cnt + 1);
                $flag = false;
            }
        } else {
            $_SESSION["offset"] = null;
            $flag = false;
        }
        return new table_save($flag, $response);
    }
}

//tableにCSVデータを保存
class table_save
{
    var $flag = false;
    var $result = null;
    /**
     * @param boolean $flag
     * @param array  $response
     * @return void
     */
    public function __construct($flag, $response)
    {
        $this->flag = $flag;
        $this->result = $response;
        $this->column_name = "name,,...";
    }
    /**
     * @param string  $column_name
     * @return void
     */
    public function tbl_save($column_name = "")
    {
        if ($this->flag) {
            $column = $column_name ? $column_name : $this->column_name;
            $is_column = explode(",", $column);
            foreach ($is_column as $key => $val) {
                $is_value[$val] = $this->result["data"][$key];
            }
            try {
                $pdo = new PDO(DSN, USERNAME, PASSWORD);
                $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
                $sql = (function ($is_column) {
                    $INSERTFIRST = null;
                    $INSERTLAST = null;
                    foreach ($is_column as $key => $val) {
                        $INSERTFIRST[] = "$val";
                        $INSERTLAST[] = ":$val";
                    }
                    $INSERTSQL = "(" . implode(",", $INSERTFIRST) . ")values(" . implode(",", $INSERTLAST) . ")";
                    $UPDATESQL = null;
                    foreach ($is_column as $key => $val) {
                        $UPDATESQL[] = "$val = :$val";
                    }
                    return "INSERT INTO " . TABLENAME . $INSERTSQL . " ON DUPLICATE KEY UPDATE " . implode(",", $UPDATESQL) . ";";
                })($is_column);

                $stmt = $pdo->prepare($sql);
                foreach ($is_value as $key => &$value) {
                    $is_type = ($key === "test3" || $key === "test13") ? PDO::PARAM_INT : PDO::PARAM_STR;
                    $stmt->bindValue(":$key", $value, $is_type);
                }
                $this->result["sql"] = $stmt->execute();
            } catch (\Throwable $th) {
                //throw $th;
                $this->result = null;
                print $th->getMessage();
            }
        }
        print json_encode($this->result);
    }
}

//RUN...POST DATA
if (isset($_POST["csrf_token"])  && d_xss($_POST["csrf_token"]) === $_SESSION['csrf_token']) {

    $_SESSION["offset"] = (int)d_xss($_POST["reset_flag"]) === 1 ? null : d_xss($_SESSION["offset"]);
    $filename = d_xss($_POST["filename"]);
    $cnt = (int)d_xss($_POST["cnt"]);

    $column_name = "test1,test2,test3,test4,test5,test6,test7,test8,test9,test10,test11,test12,test13,test14,test15";
    $header_skip = 1;

    $csv = new csv();
    $csv->ini_csv($filename, $cnt)->reader($header_skip)->tbl_save($column_name);
    $csv = null;
} else {
    print "";
}
function d_xss($data){
    $data = strip_tags($data);
    $data = htmlspecialchars($data,ENT_QUOTES);
    return $data;
}
<?php
 // ログインした状態と同等にするためセッションを開始します
 session_start();
 // 暗号学的的に安全なランダムなバイナリを生成し、それを16進数に変換することでASCII文字列に変換します
  $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.4/css/all.min.css">
<title>CSV</title>
</head>
<body>
    <input type="hidden" name="csrf_token" value="<?=$csrf_token?>">
    <span class="h3" id="cnt"></span><br><br>
    <span class="h4" id="read_csv"></span><br><br>
    <span class="h4" id="debug"></span><br><br>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.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>
<script>
    window.onload = function(){
        read_csv(0,1);
    };
    function read_csv(cnt,reset_flag){
        try{
            $.ajax({
            type: "post",
            url: "./assets/php/class_csv.php",
            async: false,
            data: {csrf_token:document.getElementsByName("csrf_token")[0].value,reset_flag:reset_flag,filename:"dummy.csv",cnt:cnt},
            dataType: "json",
            success: function (response) {
                    if(response){
                        cnt = response.cnt;
                        document.getElementById("cnt").innerText = cnt;
                        if(response.data){
                            document.getElementById("read_csv").innerText = response.data[0] + response.sql;
                            document.getElementById("debug").innerText = cnt ===21?response.data:document.getElementById("debug").innerText;
                        }
                        setTimeout(function(){read_csv(cnt)},0);
                    }
                }
            });
        }catch(e){
            console.warn(e);
            read_csv(cnt);
        }
    }
</script>
</body>
</html>

著者名  @taoka_toshiaki

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

タグ

0, , 7, 8, CSV, fgetcsv, github, null, php, PHPCODE, qiita, SQL, アクセス, エラー, コード, こちら, コマンド, これ, ご使用, ご自身, ダウンロード, ちょ, テーブル, ファイル, ブログ, リンク, , 一部, , , 今日, 保存, 動作, 参考, 変更, 実行, , 方法, 日差し, 昨日, 有言実行, 注目, 環境, , 簡単, 記載, 雛形,

Photo by cottonbro on Pexels.com

新着記事が表示されるWPの非公式プラグインを作りました。

2022.07.24

Logging

こんにちは、朝の2時に起床し4時頃、ウォーキング。そして朝食後、コードを書いてその後、仮眠をとって今、記事を書いています。かなり不規則な生活リズムです😩、今日からは元の生活リズムへ戻そうと思っています。さて、WordPressの非公式プラグインを自前で制作致しましたのでお裾分けです。

今回はシングルページの記事の下に新着記事が表示されてカルーセルで動くというプラグインです。

新着記事が表示されるWPの非公式プラグインを作りました。

アイキャッチ画像の大きさなどはご自身でソースコードを変更してご使用ください。尚、アイキャッチ画像がないには対応しておりません。

いらないパラメーターを投げている所があります。そちらは御自身で修正をお願いします、因みに今は新着記事5記事を取得している感じです、そちらも変更はソースコードを修正してお使いいただければと思っています。

ダウンロードのURLは下記になります。

https://zip358.com/plugin/new-post.zip

追伸:カールセルUIはSlickを使用しております。

著者名  @taoka_toshiaki

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

タグ

2, 358, 4, 5, com, https, plu, url, WordPress, wp, www, zip, あい, ウォーキング, お使い, お裾分け, お願い, かなり, カルーセル, キャッチ, コード, ご自身, シングル, ソース, そちら, ダウンロード, パラメーター, プラグイン, ページ, リズム, , 下記, 不規則, , 今回, 今日, 仮眠, 使用, 修正, , 公式, 制作, 取得, 変更, 対応, , 感じ, , 新着, , 朝食, 生活, 画像, 自前, 自身, 表示, 記事, 起床,

Photo by Stanislav Kondratiev on Pexels.com

明日からのためにデスク周りを整理しました。DIYみたいな事を…。

2022.07.15

Logging

おはようございます。あっという間にこの日が・・・来ました。今後の事とかは明日、記事にします。

さて「明日からのためにデスク周りを整理しました」というタイトル通り、デスク周りのごちゃごちゃしていた部分をDIYして机の下に収納しました。この記事は予約投稿ですので正確には月曜日時点でデスク周りは綺麗に片付いている状態になっていると思います。

まず、使わなくなった携帯電話をWEBの動作確認用に使っているのですが、雑然と机の上に置いていたものを後付の机引き出し(収納)を購入しその中に入れるようにしました。その他、ipad proと旧型iPhone、メモ用の方眼紙、英単語帳も収納に入れています

https://www.youtube.com/watch?v=vNWDaAntLpU

次に動画にも写り込んでいると思いますが、机の上にコンセントを置いていたのですが、こちらも収納入れを購入し机の下に取り付けた形になります。

また、収納とは関係ないのですがDisplayPortを購入し全てのディスプレイをビデオボードに接続し出力出来るようにしました。今までマルチポートしてオンボードに刺していたのですが、イラストレーターなどの力を最大限に活かしたい場合はマルチポート設定はOFFにした方が良いとあるサイトに記載してあったので、そのように変更しています。

今回のDIYの費用は5000円程度になりますが、良くなった感じがします(自己満足ですけどね😆)。

尚、整理したデスク周りは近日中にこの記事に追加します。

追伸:収納引き出しを購入したのですが、ipadや方眼紙が入らなかったので机の上に置いた状態になってます。そしていつも使用するものは手元にある方が効率が良い・・・。

著者名  @taoka_toshiaki

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

タグ

DisplayPort, DIY, iPad, iPhone, Pro, web, あっという間, こちら, コンセント, その他, タイトル, ため, , デスク, メモ, もの, , , , 予約, , 今後, 全て, 動作, 動画, 収納, 周り, , 引き出し, , 後付, 投稿, 携帯, 整理, 方眼紙, , 旧型, 明日, 時点, 月曜日, , 正確, 状態, 確認, 綺麗, 英単語, 記事, 購入, 部分, 電話,

サーバーの引っ越しのヒントです。いや答えですねw😌

2022.06.16

Logging

おはようございます。あと一ヶ月もすれば炎天下の下でお仕事をする人もいるでしょう。大変ですね。

昔はよくサーバーの引っ越しを仕事でしていました。代わりに誰か出来る人もいなかったので自分が行っていましたが、サーバーの引っ越しほど時間のかかる仕事はありません。

scp -r -p /var/www/html/ user@example.com:/home/user/www/
scp [コピー元のファイル] [コピー先のユーザー名@コピー先のホスト] [コピー先のファイル]

何より責任、重大ですから色々と経験して思ったのは、サーバーの移行作業後に何らかの「動かない」というバグとりを速やかに行えるかどうかが大事かと思います。それはある意味、経験が物を言う世界かもしれません。こんなズブの素人でも少しだけサーバーの事を理解できたので、今思えば良いことなのかもしれません。

因みに上記に記述しているコマンドを旧サーバー環境で実行すれば新サーバーへファイル転送出来ます。いちいちFTPソフトでダウンロードしてアップロードするという事を行わなくて良いです。そして何よりパーミッションやタイムスタンプまで引き継いでくれるので便利かと思います。

著者名  @taoka_toshiaki

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

タグ

-p, -r, com, example, home, html, SCP, user, var, , www, お仕事, こと, コピー, コマンド, サーバー, それ, どり, バグ, ヒント, ファイル, ホスト, ユーザー, , 上記, , 世界, , , , 仕事, 何より, 作業, 大事, 大変, 実行, 少し, 引っ越し, 意味, , 時間, 炎天下, , 理解, 環境, 移行, 答え, 素人, 経験, 自分, 色々, 記述, , 責任,

らくてんのアフィリエイトを記事の下に取り付けるプラグインを作りました。

2021.11.02

Logging

らくてんの アフィリエイト を記事の下に取り付けるプラグインを作りました。Composerを使用して楽天のSDKを取ってきているので、そちらをプラグインの中にインストールする必要と アフィリエイト のAPIIDなども必要になりますのでそちらも御自身で構える必要がありますが、それ程難しいことはないプログラムコードだと思います。

あとCSSなどもご自身が使用するサイトのデザインに合わしてご使用ください。今回、WordPressのプラグインですがソースコードを見たいだければ分かる通り、AmzのSDKも取り入れようかなとか思ったのですが、処理が重たくなり表示速度が下がりそうだったので辞めました。因みにAmzのSDKはComposerに公開していないようです。公式サイトからzipでダウンロードするか、githubから入手する方法しかないようですね。

仕様として、タグのワードから商品を検索し表示する方法とショートカットを使用して商品を表示させる方法があります。例えばRakuten_Seller_param type=”search” word=”ひろゆきのシン・未来予測”このようにショートコード書くと下記のように表示されます。また記事の最後に自動で紹介商品も表示されます。

追記:リクエストが多くなるとバグるみたいな‥‥。いまいち下記が表示されていない原因がわからない

追記:記事の最後に自動で紹介する機能は、このサイトでは一旦停止しています。

[Rakuten_Seller_param type=”search” word=”ひろゆきのシン・未来予測”]

トイウコトデ、WordPressのソースコードになります。

<?php
/*
Plugin Name: Rakuten_Seller
Plugin URI: https://zip358.com/
Description: 楽天アフィリエイトを表示
Author: @zip358com
Version: 0.1
Author URI: https://zip358.com/
*/
require_once plugin_dir_path( __FILE__ ).'/vendor/autoload.php';
define("RAKUTEN_YOUR_APPLICATION_ID","xxxxxxxxxxxxxxx");
define("RAKUTEN_YOUR_AFFILIATE_ID","xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");

define("AMAZON_YOUR_ACCESS_KEY_ID","");
define("AMAZON_YOUR_SECRET_KEY","");
define("AMAZON_YOUR_ENDPOINT","");
define("AMAZON_YOUR_URL","");


function Rakuten_Seller_content_plus($content) {
    if(is_single()) {
       $content.='[Rakuten_Seller_param type="auto"]';
    }
    return $content;
}

function Rakuten_Seller($params = array()){
     $htmlcode = "";
    extract(shortcode_atts(array(
        'type'=>'',
        'word'=>''
    ), $params));
    $client = new RakutenRws_Client();
    // アプリID (デベロッパーID) をセットします
    $client->setApplicationId(RAKUTEN_YOUR_APPLICATION_ID);
     
    // アフィリエイトID をセットします(任意)
    $client->setAffiliateId(RAKUTEN_YOUR_AFFILIATE_ID);

    if($type==="auto"){
        $tags = get_the_tags();
        $htmlcode.= "<div class='rakuten_seller_div'>";
        foreach( $tags as $tag) { 
            $htmlcode.= Rakuten_code($client,$tag->name);
        }        
        $htmlcode.= "</div>";
        
    }elseif($type==="search"){
        $htmlcode.= "<div class='rakuten_seller_div'>";
        $htmlcode.= Rakuten_code($client,$word);
        $htmlcode.= "</div>";
    }

    return $htmlcode;
 }

function Rakuten_code($client,$word="JavaScript"){
    $htmlcode = "";
   
    // IchibaItem/Search API から、keyword=$word を検索します
    $response = $client->execute('IchibaItemSearch', array(
      'keyword' => $word,
      'genreInformationFlag' => 1
    ));
    // レスポンスが正しいかを isOk() で確認することができます
    $cnt = 0;
    if ($response->isOk()) {
        foreach ($response as $item) {
           $htmlcode.= "<div class='rakuten_seller_item'>".
           "<img src='".$item["mediumImageUrls"][0]["imageUrl"]."'>".
           "<p>".$item["itemName"]."</p>".
           "<a class='rakuten_btn' href='".$item["affiliateUrl"] . "' title='".$item["itemName"]."'><span>楽天で購入"."</span></a></div>";
           $htmlcode.= amazon_code($item["isbn"],$item["jan"]);
           if($cnt>0){
                break;
           }
           $cnt++;
        }

    } else {
        //echo 'Error:'.$response->getMessage();
    }
    return $htmlcode;
}

function amazon_code($isbn="",$jan=""){
    $htmlcode = "";

    return $htmlcode;
}


add_shortcode('Rakuten_Seller_param', 'Rakuten_Seller');
add_filter('the_content', 'Rakuten_Seller_content_plus');

著者名  @taoka_toshiaki

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

タグ

Amz, APIID, Composer, css, github, SDK, WordPress, zip, あと, アフィリエイト, インストール, コード, こと, ご自身, サイト, ショート, ソース, そちら, ダウンロード, タグ, デザイン, プラグイン, プログラム, らくてん, ワード, , , 今回, 仕様, 使用, 入手, 公式, 公開, 処理, 商品, 必要, 方法, 検索, 楽天, 自身, 表示, 記事, 通り, 速度,

SEOって意味があるのかわからないけれどAll in One SEOの採点は気にしてる。

2021.05.14

Logging

SEOって意味があるのかわからないけれどAll in One SEOの採点は気にしてる自分。ワードプレス(WordPress:WP)にはオールインワンSEO(エスイオー)というプラグインがあり、最新版には記事単位でSEO採点をしてくれる機能が無料でついている。このWPプラグインのコード(中身の処理)がどうなっているかは知らないけれど、恐らく記事のデータはWPプラグインの提供元(All in One SEO)へデータを送信していることは間違いないのではないかと思っています。このSEO採点基準は投稿フォームの下の方にヒントとして記載されているので、その基準に記事を書けばスコアは最低でも70点以上の採点になるはずです。

【2021年度版】All in One SEO(WordPressプラグイン)の設定方法

因みにこの頃、書いている自分の記事は大体、80点以上の採点になることが多くなってきている。この機能が導入されてから記事を見返したり、SEOの得点を気にするようになった。それでも前から言っているように最終的に記事を読むのは人なので人が読んで評価が良いものを投稿する事こそが最強のSEOだと思っています。

しかし記事が検索サイトに表示されないと人目につかないので、SEOはある程度意識しないといけないなというのが今の自分の考えだったりします。昔に比べて検索の上位を狙うのが難しくなっていることは確かな事で数撃ちゃ当たる戦法はもう難しくなってきています。YOUTUBEは今の所、それが通用するみたいです。

なぜ、数撃ちゃ当たるの戦法が難しくなってきているかといえば、SEOを熟した企業が記事を量産しているから、個人で記事を書いている人が太刀打ちが難しくなってきているのが現状です。

https://twitter.com/zip358com/status/1389684900937097217

ならば、プログラムで記事を量産させようと思い立ち、先日、記事を自動生成するサービスをいろいろ調べていた。調べると量産させるサービスがあった。そのサービスは「Articoolo(日本語はベータ版:2021年)」というサービスで人工知能の機能を使用し記事が作成されるものだった。試してみた結果、日本語が整っていなく未完成な記事が生成された、今のところは使用できるレベルではない(2021/05)。

【取材】超巨大言語モデルの開発を発表したLINEさんにその裏側を聞いてみた!

まだ、先の話になるのだけどこんな取り組みがある。LINEは日本語に特化した人工知能モデルを作ろうとしている。そのサービスが完成すればそれを使用して記事の自動制作を行えないかという事を自分は考えています。おそらくベータ版サービスは無料で作成できそうなので精度が良ければ使用してみたいと思っています。

今でも自然言語処理と人工知能のことを正しく理解している人であれば、記事を量産できるかもしれないが・・・。

著者名  @taoka_toshiaki

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

タグ

70, 80, all, in, one, SEO, WordPress, wp, エスイ, オー, オールインワン, コード, こと, スコア, データ, パス, ヒント, フォーム, プラグイン, プレス, ワード, , 中身, 処理, 単位, 基準, 大体, 導入, 得点, 意味, 投稿, 採点, 提供, , 最低, 最新版, 機能, , 無料, 自分, 記事, 記載, 送信, ,

「友情、努力、勝利」は少年ジャンプ。じゃ現実は?

2021.04.26

Logging

「友情、努力、勝利」は少年ジャンプのヒット作の法則はこれらを掛け合わせたものらしいことを映画、バクマンから知りました。じゃ現実はなんだろうかと思ったときに、現実はそんなんじゃないよねって事が頭をよぎりましたので考えてみました。まず、映画はどうだろうかと?映画は少年ジャンプと同じような法則でヒットすると思います。現実は厳しいから夢や成功ストーリーがヒットする。当てはまります。

佐藤健×神木隆之介×大根仁!映画『バクマン。』予告編

夢売る商売はこれでヒットするのだと思います。それ以外の商売は夢を売っている訳ではないのでこの法則が当てはまらない場合があります。商売が成功する要因は値段よりお得だったと思わすことだと思います。それがヒットや売上に直結していくのだと、どんなに営業が下手くそでも商品がよく満足できる商品なら売れます。

結局、ここは映画、漫画、音楽などと同じで商品が満足できるかどうかだと思います。支払ったお金と商品を天秤にかけて商品が下に下がればお得だと感じます。当たり前のことなんだけど、そこが一番難しいだと感じます。「友情、努力、勝利」の法則が分かっていてもヒットするというのは大変な事と同じです。

少し脱線しますが経営者や人と関わり方、多様性の話を記載します。経営者は縁(えにし)を大事にする人が多いように思えます。特に中小企業や零細企業の方は縁や風水など、目には見えないものや験を担ぐ(げんをかつぐ)人も多いと思います。持ちつ持たれつがどの世界にもあるという事の現れなんだと思います。

商売でもなんでもそうですが人との関係は始まりより終わり方が大事じゃないかなと思います。上手く終われる人はなかなかいない。飛ぶ鳥跡を濁さずというコトワザもあるように去るときが大事になると思います。

30分で判る 経済の仕組み Ray Dalio

これから先、多様性が重要視されるようになると思いますが、この日本が多様性を重視するにはかなり時間がかかると思っています。アメリカなどでも未だに根強い差別があるのですから、日本が多様性を受け入れるようになるにはかなり時間がかかると思います。なのでこれからも空気を読む社会が続くと思います。

最初の話しに戻り、話をまとめると「友情、努力、勝利」でヒットするのはエンターテイメントな業界の話、他の業界や個人が成功するには良い商品と値段の価値が関係してくる、そして縁を大事にしていかないと成功には近づけない。そのように考察しました。

尚、中小企業が10年以内に倒産する確率は50%前後だそうです。これからは個人が活躍していくと言われていますが自分はそうは思わなくて、これからも会社ファースト(優遇)な社会であり、そんな政治が続くと思っています。

著者名  @taoka_toshiaki

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

タグ

お金, ここ, こと, これ, これら, ジャンプ, ストーリー, それ, とき, なん, バクマン, ヒット, ヒット作, もの, , 下手くそ, , 値段, 努力, 勝利, 友情, 商品, 商売, 営業, 場合, , 天秤, 少年, 成功, 映画, 法則, 満足, 漫画, 現実, 直結, 要因, , 音楽, ,

ヒキコモリストのお姉さんが!

2021.03.15

Logging

ヒキコモリストのお姉さんこと、小森ひき子さん(YOUTUBER)は賢い人だと思います。このYOUTUBEチャンネルはなんだか、伸びそうなので紹介します。会社を辞めてデイトレ(デイトレーダー)とYOUTUBER兼業している人です。ひきこり一人暮らしの日常、ゲームなどや電子工作などのYOUTUBEに流しているだけど「えっ普通のOL」してた人には思えないぐらいです。確かにネットには方法が落ちているけど理解しているふうだし、サラッと説明は省いているところなど戦略的だなと思えます。賢いですよ・・・そんなことは本人は言いませんが。

【一人暮らし女部屋改造】デスクに置いた植物と機械を融合させる【生産性】

デイトレ投資の話、【削除するかも】と書かれているので下の動画は削除されるかもしれません。この動画で名言があります。それは「副業は全力でやるべきだ」という話です。

【削除するかも】デイトレ投資専業6年目の一人暮らしひきこもり女が投資についてやってはいけないことをお伝えします【デイトレのリアル】

最後にチャネル登録はこちら
https://www.youtube.com/c/小森ひき子ひきこもりLIFE/featured

著者名  @taoka_toshiaki

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

タグ

com, featured, https, LIFE, ol, www, youtube, YOUTUBER, お姉さん, ゲーム, こちら, こと, コモリ, スト, それ, チャネル, チャンネル, ディ, デイトレ, デイトレーダー, ところ, どれ, ネット, ヒキ, ひきこもり, ふう, 一人暮らし, , , 会社, 全力, 兼業, 削除, 副業, 動画, 名言, 小森, 工作, 投資, 方法, 日常, 普通, 最後, 本人, 理解, 登録, 紹介, , 説明, 電子,

クローラーするサービスの基礎。

2016.11.19

Logging

クローラーするサービスの基礎のソースを載せときます。殆どサイボウズ・ラボの人が書いたコードです。
このサンプルソースをそのまま貼り付けても一階層のリンクしか取得できません。
再帰処理の部分をコメントアウトしているからです。ちなみにコメントアウトを外してもメモリオーバーでおそらく
大体のサーバでエラーが出力されます。どうしたら良いのかといえば、DBに1階層目のリンクデータ、2階層目のリンクデータという様に保存する機能を施す。次にajaxで階層を受け渡しながら、再帰処理を行う。
再帰処理が終わる要素はそれ以上、下階層がないことを判断する。そのためには保存したデータを検索することが重要になる。=(イコール)
新規にデータを登録しているうちは、再帰処理を終わらせないようにすることが大事になる。
これの機能を加えることで巡回する事が可能になる。ここで注意しないといけないのが、外部リンクを保存しないことです。外部リンクまで保存していると巡回は永遠に終わらないでしょう・・・。
トイウコトデ
ほぼ??コピペソースを貼っときます。

<?php
echo json_encode($obj);
exit;
function get_linkarray($link)
{
	$context = stream_context_create(array("http" => array("method" => "GET", "header" => "User-Agent: simplecrawler.library.php 0.0.1")));
	$resultR = array();
	$resultS = simplecrawler($context, $link, $link, parse_url($link));
	foreach ($resultS as $k => $v) {
		$resultR[] = $v;
	}
	return $resultR;
}
function simplecrawler($context, $link, $burl, $base, $linkArrayDat = array())
{
	$linkArrayPre = crawler_link(crawler_page($link, $burl, $base, $context), $link, parse_url($link));
	foreach ($linkArrayPre as $k => $v) {
		if (!isset($linkArrayDat[$v])) {
			$linkArrayDat[$v] = $v;
			//$linkArrayDat = array_merge($linkArrayDat, simplecrawler($context, $v, $burl, $base, $linkArrayDat));
		}
	}
	return $linkArrayDat;
}
function crawler_page($link, $burl, $base, $context)
{
	if (strpos($link, $burl) === 0) {
		$page = @file_get_contents($link, false, $context);
		return $page === FALSE ? null : $page;
	} else {
		return null;
	}
}
function crawler_link($page, $burl, $base)
{
	$linkArray = array();
	if ($page === null) {
		return $linkArray;
	}
	preg_match_all("/[\s\n\t]+href\s?=\s?”(.*?)”/i", $page, $href);
	for ($i = 0; $i < count($href[1]); $i++) {
		$link = $href[1][$i];
		if (preg_match("/^http(s)*\:\/\//", $link)) {
			$result = $link;
		} elseif (preg_match("/^\/.+$/", $link)) {
			$result = $base["scheme"] . "://" . $base["host"] . $link;
		} else {
			// echo $base["path"] . “\n”;
			$b = preg_split("/\//", dirname($base["path"]));
			$t = preg_split("/\//", $link);
			foreach ($t as $v) {
				$l = $v === "." ? true : ($v === ".." ? array_pop($b) : array_push($b, $v));
			}
			$result = $base["scheme"] . "://" . $base["host"] . join("/", $b);
		}
		$linkArray[$result] = $result;
	}
	return $linkArray;
}

著者名  @taoka_toshiaki

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

タグ

, 2, ajax, db, アウト, イコール, うち, エラー, オーバー, クローラー, コード, ここ, こと, コメント, これ, サーバ, サービス, サイボウズ, サンプル, ソース, それ, ため, データ, トイウ, メモリ, ラボ, リンク, , , , , 保存, 再帰, 処理, 出力, 判断, 取得, 可能, 基礎, 外部, 大事, 大体, 巡回, 新規, 検索, 機能, 殆ど, 永遠, 注意, 登録, 要素, 部分, 重要, 階層,

関数型プログラミングに目覚めた!IQ145の女子高校生の…

2015.08.20

Logging

関数型プログラミングに目覚めた!IQ145の女子高校生の先輩から受けた特訓5日間という本を買ったのですが、プログラミングの作法はあまり書かれていなく、どちらかと言えば解説が多い本です。ただ、自己流でいままで作ってきた人にはそれなりに知識の得られる本になっていると思います。自分はいままで誰かに習った経験がないので結構ためになった本です。習える環境がある人達を見ていた経験(派遣)から言うと羨ましい限りです。習えない環境の下で働いている人達の方が貪欲であることは確かだと思います。これって良い例かわからないですが、日本と昔のアフリカの教育みたいなものでアフリカの生徒たちは日本の生徒たちに比べて貪欲に学習します。教わることが当たり前の環境の下とそうでない違いは明らかに違ったりするのです。この「関数型プログラミングに目覚めた!」という本はそんな貪欲にプログラミングを学びたい方には結構ハードルが高いですが、勉強になることは確かだと思います。Amazonの評価は若干、低いものの、そう書いていることは悪く無いと感じました。

著者名  @taoka_toshiaki

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

タグ

145, 5, IQ, アフリカ, こと, これ, それなり, ため, どちらか, ハードル, プログラミング, もの, , , 作法, , 先輩, 勉強, 女子, 学習, 当たり前, 教育, , 日本, , , 派遣, 特訓, 環境, 生徒, 知識, 経験, 自分, 自己流, 解説, 誰か, 貪欲, 違い, 関数, 限り, 高校生,