2021/07/20

今回はピュアなPHPで実装する必要があったので 「php-markdown」を使ったMarkDown 処理を試してみました。

php-markdown

Composer でインストール

Composermichelf/php-markdown をインストールします。

% composer require michelf/php-markdown

コードブロックの対応は MarkdownExtra を使う

単純にマークダウンを使うときは、Markdown で大丈夫ですが、コードブロックの pre, code タグに対応していません。

use Michelf\Markdown;

コードブロックに対応するには、MarkdownExtra を利用します。

use Michelf\MarkdownExtra;

MarkDown を HTML に変換する

MarkDown を HTML に変換するのはこれだけです。

$markdown = new MarkdownExtra();
$content = $markdown->transform($content);

ただ、 prism.js にも対応させたいので code_class_prefixlanguage- をつけておきます。関数とかにまとめるとこんな感じです。

function markdownToHtml($content){
    $markdown = new MarkdownExtra();
    $markdown->code_class_prefix = 'language-';
    return $markdown->transform($content);
}

//マークダウン文章
$markdown = "
    ``` php
    function hoge($value)
    {
        return $value;
    }
    ```
";

//HTMLに変換
$html = markdownToHtml($markdown);

MarkdownExtra の pre, code 処理

これはマニュアルに載ってないので MarkdownExtra のソースコードを調べてみました。 $matches は文章に正規表現をかけた配列で、クラス名は index=2 にマッチします。あとは、 $code_class_prefix をくっつけてますね。

        protected function _doFencedCodeBlocks_callback($matches) {
        $classname =& $matches[2];
        $attrs     =& $matches[3];
        $codeblock = $matches[4];

        if ($this->code_block_content_func) {
            $codeblock = call_user_func($this->code_block_content_func, $codeblock, $classname);
        } else {
            $codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES);
        }

        $codeblock = preg_replace_callback('/^\n+/',
            array($this, '_doFencedCodeBlocks_newlines'), $codeblock);

        $classes = array();
        if ($classname !== "") {
            if ($classname[0] === '.') {
                $classname = substr($classname, 1);
            }
            $classes[] = $this->code_class_prefix . $classname;
        }
        $attr_str = $this->doExtraAttributes($this->code_attr_on_pre ? "pre" : "code", $attrs, null, $classes);
        $pre_attr_str  = $this->code_attr_on_pre ? $attr_str : '';
        $code_attr_str = $this->code_attr_on_pre ? '' : $attr_str;
        $codeblock  = "<pre$pre_attr_str><code$code_attr_str>$codeblock</code></pre>";

        return "\n\n".$this->hashBlock($codeblock)."\n\n";
    }

  2021/07/20

protonemedia/laravel-ffmpeg

Laravel で動画エンコードするライブラリ、「protonemedia/laravel-ffmpeg」を利用します。

ffmpg のインストール

「laravel-ffmpeg」を利用する前に、 ffmpg のインストールが必要です。ここでは Macでのインストールを説明します。

Homebrew でffmpg をインストールします。また XCode Tools も事前インストールしておいてください。


% brew install ffmpeg

ffmpeg のバージョンを確認します。


% ffmpeg -version 
ffmpeg version 4.3.2 Copyright (c) 2000-2021 the FFmpeg developers

Laravel の設定

Composer で laravel-ffmpeg をインストール

Composer で laravel-ffmpeg をインストールします。


% composer require pbmedia/laravel-ffmpeg

artisan で publish

artisan コマンドで laravel-ffmpeg をパブリッシュします。

ファイル指定する場合


php artisan vendor:publish --provider="ProtoneMedia\LaravelFFMpeg\Support\ServiceProvider"

番号指定する場合


% php artisan vendor:publish

ProtoneMedia\LaravelFFMpeg\Support\ServiceProvider の番号を入力します。


...
  [13] Provider: Livewire\LivewireServiceProvider
  [14] Provider: ProtoneMedia\LaravelFFMpeg\Support\ServiceProvider
  [15] Tag: config
...
>14

「Publishing complete」が表示されれば成功です。


Publishing complete.

laravel-ffmpeg.php の確認

パブリッシュが成功すると「config/laravel-ffmpeg.php」が作成されます。 「config/laravel-ffmpeg.php」の内容は以下の通りです。


return [
    'ffmpeg' => [
        'binaries' => env('FFMPEG_BINARIES', 'ffmpeg'),
        'threads'  => 12,
    ],
    'ffprobe' => [
        'binaries' => env('FFPROBE_BINARIES', 'ffprobe'),
    ],
    'timeout' => 3600,
    'enable_logging' => true,
    'set_command_and_error_output_on_exception' => false,
    'temporary_files_root' => env('FFMPEG_TEMPORARY_FILES_ROOT', sys_get_temp_dir()),
]

ffmpeg のパスを設定

ffmpeg、ffprobeのパスをターミナルで調べます。


% which ffmpeg
/usr/local/bin/ffmpeg

% which ffprobe 
/usr/local/bin/ffprobe

ffmpeg、ffprobeのパスを環境設定ファイル .env に ffmpeg 設定します。


FFMPEG_BINARIES=/usr/local/bin/ffmpeg
FFPROBE_BINARIES=/usr/local/bin/ffprobe

Providor と alias の設定

config/app.php に Providor と Facade の alias を設定をします。 namespace は「Pbmedia\LaravelFFMpeg\」です。


    'providers' => [
        ...
        ProtoneMedia\LaravelFFMpeg\Support\ServiceProvider::class,
        ...
    ],
    ...
    'providers' => [
        ...
        'FFMpeg' => ProtoneMedia\LaravelFFMpeg\Support\FFMpeg::class,
        ...
    ]

mp4 をストレージにアップ

storage/app/public/mp4/ に .mp4 ファイルをアップしておきます。 今回は「sample.mp4」とします。

動画情報の取得

Laravel の Controller などで確認してみましょう。


...
use ProtoneMedia\LaravelFFMpeg\Support\FFMpeg
...
class HomeController extends Controller
{
    ...
    public function index()
    {
        $media = FFMpeg::fromDisk('public')->open('mp4/sample.mp4');
        $mediaStreams = $media->getStreams();
        $duration = $media->getDurationInSeconds();
        $codec = $mediaStreams[0]->get('codec_name');
        return view('admin.index')->with(
            [
                'mediaStreams' => $mediaStreams,
                'duration' => $duration,
                'codec' => $codec
            ] 
        )
    }
    ...
}

  2021/07/04

Let's Encrypt の無料証明書を発行・管理する certbot-auto が Debian/Ubuntu OS で非対応になりました。certbot と python3-certbot-apache をインストールしてサーバ証明書の管理をします。

Apache の ServerName 設定

/etc/apache2/sites-available/000-default.conf ファイルで ServerName にドメインを設定します。


$ sudo vi /etc/apache2/sites-available/000-default.conf

        ServerName ドメイン
...

certbot と python3-certbot-apache のインストールと設定

certbot で Apache の設定を読み込んで実行し、各設問に答えて設定します。

更新通知のメールアドレスを入力します。


$ sudo certbot --apache
Saving debug log to /var/log/letsencrypt/letsencrypt.log Plugins selected: Authenticator apache, Installer apache Enter email address (used for urgent renewal and security notices) (Enter 'c' to cancel):メールアドレス

A を入力して同意します。


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must agree in order to register with the ACME server at https://acme-v02.api.letsencrypt.org/directory
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
(A)gree/(C)ancel: A

Electronic Frontier Foundation からのお知らせを受けてとるか答えます。


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let's Encrypt project and the non-profit
organization that develops Certbot? We'd like to send you email about our work
encrypting the web, EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: N

対象のドメインを番号で選択します。


Which names would you like to activate HTTPS for?
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
1: xxxxxxxxx
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
Select the appropriate numbers separated by commas and/or spaces, or leave input blank to select all options shown (Enter 'c' to cancel):1

HTTP接続のときに HTTPSにリダイレクトするかを選択します。


Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
1: No redirect - Make no further changes to the webserver configuration. 
2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for new sites, or if you're confident your site works on HTTPS. You can undo this change by editing your web server's configuration.
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 2

Congratulations! のメッセージが表示されれば設定完了です。


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
Congratulations! You have successfully enabled https://logicoya.com You should test your configuration at: https://www.ssllabs.com/ssltest/analyze.html?d=xxxx 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
...

サーバ証明書の有効期限更新を確認

今回の設定でサーバ証明書が自動更新されますが、certbot.timer でサーバ証明書の有効期限や次回更新日時を確認できます。


$ sudo systemctl status certbot.timer
● certbot.timer - Run certbot twice daily
     Loaded: loaded (/lib/systemd/system/certbot.timer; enabled; vendor preset: enabled)
     Active: active (waiting) since Sun 2021-07-04 15:06:16 JST; 44min ago
    Trigger: Mon 2021-07-05 09:59:24 JST; 18h left
   Triggers: ● certbot.service

Jul 04 15:06:16 xxxx systemd[1]: Started Run certbot twice daily.

サーバ証明書更新テスト

certbot でサーバ証明書の更新ができますが、 --dry-run でテストできます。


$ sudo certbot renew --dry-run

  2021/05/28

GitHub の「master」と「main」

2020年末頃から GitHub のデフォルトブランチが「master」から「main」に変更になりました。GitHub をはじめた人がこの変更を知らない人が手順を間違えて「master」に push して放置していることがあります。

手動で master に push してしまうのが原因?

これは GitHub でリポジトリ作成すると「main」ブランチがデフォルトになったにもかからわず、手動コマンドで「master」に push してしまうことが多いようです。


% git push origin master

「main」と「master」の食い違いは最終的に、ブランチを移動する作業が必要ですが、ここでは割愛します。

master を checkout する

今回はデフォルトが「main」ブランチで、「master」ブランチで管理されたソースを pull/checkout してみます。

Git clone する

まずリポジトリをクローンして、プロジェクトフォルダに移動します。


% git clone https://github.com/アカウント名/リポジトリ名.git
% cd プロジェクト名

リモートブランチ(master)をローカルブランチ(master)に checkout

リモートブランチは「master」になっているので、ローカルブランチも「master」にあわせて checkout します。 -b は新しくブランチを作成してくれるオプションです。


% git checkout -b master origin/master
Branch 'master' set up to track remote branch 'master' from 'origin'.
Switched to a new branch 'master'

これでリモートブランチ「master」からソースもダウンロードされます。

ローカルブランチや origin の確認

ローカルブランチが「master」ブランチに変わったことを確認します。


% git branch
  main
* master

また origin を確認するとメインが main でその他 master ブランチも追跡していることがわかります。


% git remote show origin
* remote origin
  Fetch URL: https://github.com/アカウント名/リポジトリ名.git
  Push  URL: https://github.com/アカウント名/リポジトリ名.git
  HEAD branch: main
  Remote branches:
    main   tracked
    master tracked
  Local branches configured for 'git pull':
    main   merges with remote main
    master merges with remote master
  Local refs configured for 'git push':
    main   pushes to main   (up to date)
    master pushes to master (up to date)

  2021/03/08

Laravel では Auth や Jetstream で認証機能を実装できますが、マルチログインは結構面倒です。

例えば未認証のリダイレクト処理はミドルウェアの Authenticate->redirectTo() で処理していますが、シングルログイン(user)の記述です。

Authenticate のデフォルト設定

app/Http/Middleware/Authenticate.php


    protected function redirectTo($request)
    {
        if (!$request->expectsJson()) {
            return route('login');
        }
    }

ここで user、admin 2つのマルチドメイン認証で「/user/xxx」「/admin/xxx」にアクセスしたとき、上記のルーティングでは「/login」にリダイレクトされてしまいます。

また「/login」でなく「/user/login」「/admin/login」でルーティングすると当然ながら Routing エラーになります。


Symfony\Component\Routing\Exception\RouteNotFoundException
Route [login] not defined.

Authenticate の修正

2つの認証「user」「admin」が未承認時、「/user/login」「/admin/login」 にリダイレクトするよう修正します。今回は直接「user」「admin」と直接設定しましたが、ループ処理は guard の設定と連携してもよいかと思います。


    protected function redirectTo($request)
    {
        if (!$request->expectsJson()) {
            foreach (['user', 'admin'] as $user) {
                if ($request->routeIs("{$user}.*)) {
                    return route("{$user}.login");
                }
            }
        }
    }

また、認証処理を user、admin の各コントローラーのコンストラクタやサービスなどで認証する場合は、 Authenticate->redirectTo() は無効にする必要があります。

  2021/03/05

Redis インストール

brew コマンドで redis をインストールします。


$ brew update
$ brew install redis

brew で redis サーバを起動します。


$ brew services start redis

redis サーバが起動しているか確認します。


$ brew services list
Name          Status  User Plist
mysql         started yoo  /Users/yoo/Library/LaunchAgents/homebrew.mxcl.mysql.plist
php@7.4       started yoo  /Users/yoo/Library/LaunchAgents/homebrew.mxcl.php@7.4.plist
postgresql@12 started yoo  /Users/yoo/Library/LaunchAgents/homebrew.mxcl.postgresql@12.plist
redis         started yoo  /Users/yoo/Library/LaunchAgents/homebrew.mxcl.redis.plist

redis-cli の確認

Redis クライアントでログインし、Redis コマンドで操作してみます。

redis-cli ログイン


$ redis-cli

データ登録


127.0.0.1:6379> set mykey "hello"
OK

データ取得


127.0.0.1:6379> get mykey
127.0.0.1:6379> keys *
1) "mykey"

全データ取得


127.0.0.1:6379> keys *
(empty array)

データ削除


127.0.0.1:6379> del mykey
(integer) 1

ログアウト


127.0.0.1:6379> exit

phpredis のインストールと設定

<

p>macOS の PHP で Redis を利用するには、PECL で Redis をインストールと設定する必要があります。

<

p>


$ pecl install redis

php.ini で redis.so を読み込む

php.ini ファイルをパスを確認します。 以下は /usr/local/etc/php/7.4/php.ini になっていますが、各環境で確認してください。


$ php -r "echo phpinfo();" | grep "php.ini"
Configuration File (php.ini) Path => /usr/local/etc/php/7.4
Loaded Configuration File => /usr/local/etc/php/7.4/php.ini

確認した php.ini を修正し redis.so を読み込むよう設定します。


extension="redis.so"

PHP 再起動

PHP を再起動します。以下は php@7.4 をインストールして有効にしている場合です。 (インストールしているパッケージにあわせてください)


$ brew services restart php@7.4

$ php -i | grep Redis

  2021/03/03

以前は、jQuery や JavaScript でスムーズスクロールをいろいろ実装していましたが、CSS3 で1行書くだけで対応可能です。


html{
    scroll-behavior: smooth;
}

ただ 2021/02 時点で IE はもとより Safari に対応していないので、実際には JavaScript での記述も必要になります。

  2021/02/24

EC-CUBE4 で Gmail の smtp の設定方法は、.env の MAILER_URL に記述します。

前提として、Googleセキュリティでの2段階認証が必要になります。

  • smtp: smtp.gmail.com
  • port: 465
  • encryption: ssl
  • auth_mode: login
  • username: Gmail アカウント(Gmail アドレス)
  • password: Google セキュリティの2段階認証で作成したパスワード(Gmail アカウントのパスワードではありません)

EC-CUBE の.env

EC-CUBE4 から Swift Mailer を利用しますが、smtpプロトコルの URLをパラメータ方式で設定します。


MAILER_URL=smtp://smtp.gmail.com:465?encryption=ssl&auth_mode=login&username=xxxxx@gmail.com&password=xxxxxx

  2021/02/02

amazon-linux-extras とは

AWS EC2 の AMI(マシンイメージ) で Amazon Linux 2 を選択してサーバ構築すると amazon-linux-extras コマンドが利用できます。

amazon-linux-extras は Amazon Linux 用のパッケージツールで、主要なソフトウェアをまとめてインストールできます。
ただし、amazon-linux-extras パッケージに含まれないソフトウェアは別途インストールする必要があります。

amazon-linux-extras のコマンドは単純で、以下の4つのコマンドが用意されています。

  • help:ヘルプ
  • info:パッケージ詳細
  • install:パッケージインストール
  • list:パッケージ一覧

トピック一覧確認

amazon-linux-extras でトピック一覧(パッケージ情報)を確認できます。 amazon-linux-extras list でも同様の動作をします。


$ amazon-linux-extras
...
 33  java-openjdk11           available    [ =11  =stable ]
 34  lynis                    available    [ =stable ]
 35  kernel-ng                available    [ =stable ]
 36  BCC                      available    [ =0.x  =stable ]
 37  mono                     available    [ =5.x  =stable ]
 38  nginx1                   available    [ =stable ]
...
 42  php7.4=latest            enabled      [ =stable ]
...

数字の次にの項目が amazon-linux-extras のトピック名(パッケージ名)です。実際にインストールする Linux のパッケージ名とは違うので注意が必要です。

available はインストール可能な状態、enabled は実際にインストールされた状態です。

パッケージの詳細を確認

また、amazon-linux-extras info でパッケージ内容を確認できます。例えば、php7.4 のパッケージを確認してみます。


$ amazon-linux-extras info php7.4
php7.4 recommends php-cli                    # yum install php-cli
php7.4 recommends php-pdo                    # yum install php-pdo
php7.4 recommends php-fpm                    # yum install php-fpm
php7.4 recommends php-json                   # yum install php-json
php7.4 recommends php-mysqlnd                # yum install php-mysqlnd

Amazon Linux 2 の Linux のディストリビューションは RHEL7 / CentOS7 を採用しています。よって、実際のパッケージインストールコマンドは yum install が実行されます。

amazon-linux-extras でインストール

amazon-linux-extras install でパッケージを管理者権限でインストールします。


$ sudo amazon-linux-extras install トピック名

トピック名 php7.4 をインストールする例です。


$ sudo amazon-linux-extras install php7.4

パッケージを無効にする

ヘルプにはありませんが amazon-linux-extras disable でパッケージの動作を無効にすることもできます。


$ sudo amazon-linux-extras disable トピック名

実際にパッケージが削除されるわけでなく yum remove などで削除すると、パッケージ依存の問題が発生する可能性があるので注意が必要です。

amazon-linux-extras はよく利用するパッケージのインストールを少しだけ楽にしてくれるツールであることがわかりました。

  2021/01/26

UNIQUE(重複)を含むデータの更新で、FormRequest や Validate で単純に unique を設定してしまうと、自分自身を更新できません。

code がユニークの場合

以下は、FormRequest の rulde() で items.code を UNIQUE 制約している例です。

配列の場合


'code' => ['required', 'string', 'unique:items'],

パイプの場合


'code' => 'required|string|unique:items',

この設定だと SQL の WHERE で更新しようとしてしまいます。


WHERE code = 'xxxx';

id を除外して code をユニークにする

よって items テーブルのプライマリーキー items.id を除外して更新するのがよいでしょう。

配列の場合


'code' => ['required', 'string', Rule::unique('items')->ignore($this->id)],

パイプの場合


'code' => "required|string|unique:items,code,{$this->id},id",

SQL の WHERE は以下のようになります。


WHERE code = 'xxxx' AND id <> 'xxxx'
<< Top < Prev Next > Last >>
php-markdown で バニラPHPなコードブロック処理
laravel-ffmpeg を使う
2021年版 Ubuntu + certbot + Let's Encrypt でサーバ証明書設定
GihHub のデフォルトでない master ブランチを checkout する
マルチログインで未認証のリダイレクト
Homebrew で Redis をインストール
CSS だけでスムーズスクロール
EC-CUBE4 で Gmail の smtp を利用する
Amazon Linux 2 の amazon-linux-extras とは
UNIQUE カラムのバリデーションで自分自身を除外して更新
フォーム有効期限切れで Page Expired をリダイレクト
ログを日付でローテーションやクリアや削除
Homebrew で PHP8.0 から PHP7.4 にダウングレード
Big sur で zsh 移行と Homebrew アップグレード
Mac に minikube をインストール
途中から .gitignore に追加する
Larevel 6.x から Laravel 8.x にバージョンアップ
Composer で Allowed memory size (メモリ不足)エラー
Blade でカスタムクラスを利用する
git push git pull にブランチ指定せずに実行する
git pull や git push できなくなったとき
Docker のコンテナからホストOS に接続
Mac で ローカル IP アドレス(ipv4)のみを表示する
ホストOS から Docker の MySQLコンテナに接続
caching_sha2_password のエラー
node-config で環境設定ファイルを利用する
rootパスワードを初期化(再設定)する
Git から clone したときのエラー対処
Mac に MySQL をインストール
Mac に PostgreSQL をインストール
Laravel 環境構築 - Mac ネイティブ編
Firebase 入門 - Firebase とは
Firebase 入門 - CLI インストールとデータベースの設定
AWS 無料枠(t2.micro)で容量とメモリエラー
Cloud9 を起動する -初心者編-
gcloud で GCEインスタンスを起動してみる
AWS CLI と jq でインスタンス一覧を整形して表示
React と Laravel7 のプロジェクトを作成する
Homebrewインストール-2020年版
3直線で囲まれた範囲塗りつぶし
PuLP で線形最適化問題を解く
カスタムのペジネーションを作る
node-sass を使って sass をコンパイルする
Log ファサードでSQLログを分離して書き出す
いちから始める Docker - 複数のコンテナを使う - (2020年)
いちから始める Docker - docker-compose を使う - (2020年)
AWS ECR を使ってみる
Laravel7 でマルチ認証
Mac に AWS Client を設定する
Laravel7 リリース