20200523のPHPに関する記事は14件です。

Cookieの削除の話

はじめに

Cookieをプログラムで使用する時に、「Cookieの削除はいつから有効になるのか」ふと疑問思ったので、
軽く実験してみました。
おそらく、HTTPプロトコルについての基本がわかっている人はそんなの当たり前に知っているという人が多いでしょう笑

webアプリを開発時、Cookieの処理を実装しようとした時にどうするかを考えた時に、この処理の時はあるCookieを削除して、
その後の処理を分岐させたいというアイデアが出たのですが、それって多分できないよねって話になりました。

多分っていうのが気持ち悪かったので、PHPで試しに実験してみました。

環境

環境

PHP7
CakePHP3

実験

  1. ブラウザに Cookie名: name Cookie値: bellcrud を登録する
  2. プログラムで Cookie[name]をログ出力
  3. プログラムで Cookie[name]を削除
  4. プログラムで Cookie[name]をログ出力
CookiesController.php
public function index()
    {
        $this->log('----クッキー取得');
        $this->log($this->Cookie->read('name')); // CakePHPの用意しているライブラリで取得
        $this->log($_COOKIE); // 素のPHPので取得

        $this->log('----クッキー削除');
        $this->Cookie->delete('name'); // CakePHPの用意しているライブラリで削除
        $this->log($this->Cookie->read('name'));// CakePHPの用意しているライブラリで取得
        $this->log($_COOKIE); // 素のPHPので取得
    }
error.log
2020-05-23 10:26:06 Warning: DebugKit not enabled. You need to either install pdo_sqlite, or define the "debug_kit" connection name.
2020-05-23 10:26:06 Error: ----クッキー取得
2020-05-23 10:26:06 Error: bellcrud // 取得できたことを確認
2020-05-23 10:26:06 Error: Array
(
    [Phpstorm-8ff1daf1] => ************************************
    [remember_web_*********] => ************************************
    [csrfToken] => ************************************
    [name] => bellcrud
)

2020-05-23 10:26:06 Error: ----クッキー削除
2020-05-23 10:26:06 Error:        // 取得できていない!!!
2020-05-23 10:26:06 Error: Array
(

    [Phpstorm-8ff1daf1] => ************************************
    [remember_web_*********] => ************************************
    [csrfToken] => ************************************
    [name] => bellcrud // 削除されていない!!!
)

・ CakePHPの用意しているCookieComponentでは削除された扱い
・ PHPの用意している$_COOKIEでは削除されていない

結論

「正確にいうと削除されません。」
CakePHPの用意しているライブラリでは削除扱いになっていますが、実際のところは素のPHPでのCOOKIE取得でわかる通り削除されていません
COOKIEはを削除するというのは、有効期限切れにするという処理をクライアント側で完了して削除されたということ。
サーバー上で削除するというのが、そもそもの考えが意味わからないということですね。

ただ、フレームワーク側で用意されたライブラリを使うと、削除された扱いとなり取得できなくなるようにすることができる。

所感

cookieを扱う時は一貫した扱い方をしないと、わけわからなくなるため、気をつけないといけないことがわかりました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

laravel-mix調査の備忘録

概要

Laravel-Mix調査で知らない単語がたくさん出てきたのでそれのメモ。
そもそもLaravel-Mixなんで使うの?って理由ですが

  • 複数のjsファイルを一つにバンドルしたい
  • キャッシュが原因でjs, cssの変更が反映されない問題を解決したい
  • npmコマンド叩きたい(今の主流はyarnらしいですが...)

上記のような理由です。

参照ページ

Laravel Mixとは

Laravel 公式ドキュメントより

Laravel Mixは多くの一般的なCSSとJavaScriptのプリプロセッサを使用し、Laravelアプリケーションために、構築過程をwebpackでスラスラと定義できるAPIを提供しています。シンプルなメソッドチェーンを使用しているため、アセットパイプラインを流暢に定義できます。例を見てください。

全然わからん。こちとらwebpackが何者なのかすら理解できていない。
色々調べたが大体こんな感じ。

  1. webpack君は複数ファイルを一つにまとめてくれるモジュールバンドラツール
  2. webpack君をそのまま使うのはダルい
  3. Laravel Mixを使うと簡単に書ける

完全に理解した。

browserSyncとは

コードを変更、保存したら自動でブラウザを更新してくれる賢いヤツ。
Laravel-Mixだと簡単に書ける。

mix.browserSync({
    proxy: '192.168.99.100',
    open: false, // ブラウザを自動で開かない
    files: [ // 監視対象のファイル
        'resources/**/*',
    ],
    watchOptions: {
        usePolling: true,
        interval: 500,
      },
    })

自前のdocker環境用の書き方だけどざっくりこんな感じです。
resources配下のファイルを変更した際に画面が自動reloadされます。
bladeの変更がリロードなしで即反映されるので開発が捗る捗る。

UglifyJSとは

JavaScriptのコードを圧縮、軽量化(minify)したり難読化するためのツールです。
Laravel-mixの場合、コマンドによってminifyされるか否かが決まります。

npm run dev ⇒ minifyされない
npm run prod ⇒ minifyされる

    "scripts": {
        "dev": "npm run development",
        "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
        "watch": "npm run development -- --watch",
        "watch-poll": "npm run watch -- --watch-poll",
        "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --disable-host-check --config=node_modules/laravel-mix/setup/webpack.config.js",
        "prod": "npm run production",
        "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
    }
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravel 7 バッチ処理でusersテーブルのメールアドレスにビューファイルをベースとしたメールを送る

目的

  • ビューファイルを用いたメールをバッチファイルから送信する方法をまとめる

実施環境

  • ハードウェア環境(下記の二つの環境で確認)
項目 情報
OS macOS Catalina(10.15.3)
ハードウェア MacBook Pro (16-inch ,2019)
プロセッサ 2.6 GHz 6コアIntel Core i7
メモリ 16 GB 2667 MHz DDR4
グラフィックス AMD Radeon Pro 5300M 4 GB Intel UHD Graphics 630 1536 MB
  • ソフトウェア環境
項目 情報 備考
PHP バージョン 7.4.3 Homwbrewを用いて導入
Laravel バージョン 7.0.8 commposerを用いて導入
MySQLバージョン 8.0.19 for osx10.13 on x86_64 Homwbrewを用いて導入

前提情報

概要

  1. バッチファイルの作成
  2. メール用のビューファイル設定
  3. 確認

概要

  1. バッチファイルの作成

    1. アプリ名ディレクトリで下記コマンドを実行してバッチファイル(コマンドファイル)を作成する。ファイル名を「SendMailCommand.php」とする。

      $ php artisan make:command SendMailCommand
      
    2. アプリ名ディレクトリで下記コマンドを実行して先に作成したコマンドファイルを開く。

      $ vi app/Console/Commands/SendMailCommand.php
      
    3. 開いたコマンドファイルを下記の様に修正する。(開いたファイルで作成するコマンドでメールの送信処理を行う)

      アプリ名ディレクトリ/app/Console/Commands/SendMailCommand.php
      <?php
      
      namespace App\Console\Commands;
      
      use Illuminate\Console\Command;
      //下記を追加する
      //usersテーブル用のモデルファイルを紐づける
      use App\User;
      //メール送信用ファサードを紐づける
      use Illuminate\Support\Facades\Mail;
      use App\Mail\SendMail;
      //上記までを追加する
      
      class SendMailCommand extends Command
      {
          /**
           * The name and signature of the console command.
           *
           * @var string
           */
          //下記を修正する
          protected $signature = 'app:send_mail_users';
      
          /**
           * The console command description.
           *
           * @var string
           */
          //下記を修正する
          protected $description = 'usersテーブルのemail全てにメールを送信する';
      
          /**
           * Create a new command instance.
           *
           * @return void
           */
          public function __construct()
          {
              parent::__construct();
          }
      
          /**
           * Execute the console command.
           *
           * @return mixed
           */
          public function handle()
          {
              //下記を追加・修正する
              $users_infos = User::all();
      
              foreach ($users_infos as $users_info) {
                  echo $users_info['email']."\n";
                  Mail::to($users_info['email'])->send(new SendMail());
              }
              //上記までを追加・修正する
          }
      }
      
  2. メール用のビューファイル設定

    1. アプリ名ディレクトリで下記コマンドを実行してビューファイルをメールで使用するためのクラス(Mailable)ファイルを用意する。

      $ php artisan make:mail SendMail
      
    2. アプリ名ディレクトリで下記コマンドを実行して先に作成したメール送信専用のクラスファイルを開く

      $ vi app/Mail/SendMail.php
      
    3. 開いたクラスファイルを下記の様に修正する。

      アプリ名ディレクトリ/app/Mail/SendMail.php
      <?php
      
      namespace App\Mail;
      
      use Illuminate\Bus\Queueable;
      use Illuminate\Contracts\Queue\ShouldQueue;
      use Illuminate\Mail\Mailable;
      use Illuminate\Queue\SerializesModels;
      
      class SendMail extends Mailable
      {
          use Queueable, SerializesModels;
      
          /**
           * Create a new message instance.
           *
           * @return void
           */
          public function __construct()
          {
          }
      
          /**
           * Build the message.
           *
           * @return $this
           */
          public function build()
          {
              //下記を追記
              return $this->view('mails.test');
          }
      }
      
    4. アプリ名ディレクトリで下記コマンドを実行してメールとして表示したいビューファイルを格納するディレクトリを作成する。

      $ mkdir resources/views/mails
      
    5. アプリ名で下記コマンドを実行してメールとして表示したいビューファイル作成する。

      $ vi resources/views/mails/test.blade.php
      
    6. 開いたメールとして表示したいビューファイルを下記の様に編集する。

      アプリ名ディレクトリ/resources/views/mails/test.blade.php
      これはテストメールです
      
  3. 確認

    1. アプリ名ディレクトリで下記コマンドを実行してコマンドが追加されている事を確認する。

      $ php artisan list
      
    2. 先のコマンドの出力の中にapp:send_mail_usersがある事を確認する。

    3. アプリ名ディレクトリで下記コマンドを実行してバッチ処理が正常に動作するか確認する。(実際にメールが送信されるため注意する!!!)

      $ php artisan app:send_mail_users
      
    4. usersテーブルに登録されているメールアドレスの受信ボックスを確認し、下記の様なメールが届いていれば実装完了である。

      Test_Mail_-_shun_okawa_gmail_com_-_Gmail-2.png

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Mac Laravel 7 Authを用いたユーザ登録 ログイン ログアウトなどの機能を作成する ver 2.0

目的

実施環境

  • ハードウェア環境
項目 情報
OS macOS Catalina(10.15.3)
ハードウェア MacBook Pro (16-inch ,2019)
プロセッサ 2.6 GHz 6コアIntel Core i7
メモリ 16 GB 2667 MHz DDR4
グラフィックス AMD Radeon Pro 5300M 4 GB Intel UHD Graphics 630 1536 MB
  • ソフトウェア環境
項目 情報 備考
PHP バージョン 7.4.3 Homwbrewを用いて導入
Laravel バージョン 7.0.8 commposerを用いて導入
MySQLバージョン 8.0.19 for osx10.13 on x86_64 Homwbrewを用いて導入

条件

  • $ laravel newコマンドが実行できること。

概要

  1. アプリの作成
  2. DBの作成と設定
  3. マイグレーション
  4. 確認

詳細

  1. アプリの作成

    1. Laravelアプリを作成したいディレクトリにターミナルで移動する。
    2. 下記コマンドを実行してLaravelのアプリを作成する。

      $ laravel new アプリ名 --auth
      
  2. DBの作成と設定

    1. 下記コマンドを実行してMySQLにターミナルからログインする。MySQLのルートユーザのパスワードを忘れた方はこちら→MySQL 8.0.18 のrootパスワードを忘れた時のリセット方法

      $ mysql -u root -p
      
    2. 下記コマンドを実行して

    3. アプリ名ディレクトリ/databases

  3. マイグレーション

    1. 先のコマンドにて作成されたアプリ名ディレクトリに移動する。
    2. 下記を実行してマイグレーションを行う.

      $ php artisan migrate 
      
  4. 確認

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Windows10 home +VirtualBox + Vagrantの仮想環境にCentOS6 + Apache2.4 + PHP5.3 + MySQL5.5を入れる

Windowsの設定

Windows homeならBIOSを開いて、仮想化支援機構を有効化し、Hyper-Vを無効化する。

BIOS

基本的というか大体のPCでは下記の手順でBIOSにアクセスできる。
BIOSにアクセスできなかったら、各メーカーやPCの製品名のBIOSへアクセスする手順を調べる。

1. Shiftキーを押しながらシャットダウン。
2. F2キーを押しながら起動
3. AdvancedタブのCPU Configuration欄にあるIntel(R) VirtualizationTechnologyEnabledにする

3はメーカーやBIOSによって名前などが異なることがあるので、記載されてなかったら調べる。

Hyper-Vの無効化

1. 管理者権限でをコマンドプロントを開いて、下記のコードを実行する。
コードはWin10にVirtualBox+Vagrantを用いた環境構築する為の下準備から。

> bcdedit /copy {current} /d "Disable Hyper-V"
エントリは {文字列X} に正常にコピーされました。

>bcdedit /set {文字列X} hypervisorlaunchtype off

2. Shiftを押しながら電源を再起動
3. 再起動するとWindows 10 homeDisable Hyper-Vを選択できる画面が表示されるので、Disable Hyper-Vを選択。

VirtualBox + Vagrant + CentOS

VirtualBox: windowsといったPCに搭載されているホストOSの上で実行できるゲストOSを実行できるソフトウェア
Vagrant: VirtualBoxといったゲストOSでの仮想環境を実用的なものにするためのソフトウェア

以上を参考に、導入していく。

1. VirturalBoxとVagrantのインストール

VirtualBoxVagrantからWindows用の実行パッケージをインストールして実行。
~.exeを起動しても特に注意すべき点などはないので各自の作業環境に合わせて導入。

2. VirtualBoxにCentOSを登録する

Vagrantbox.esから導入したいCentOSのBOXのURLをコピーし、$ vagrant box addを実行。
今回はCentOS6を導入したいので、CentOS 6.6 x64 (Minimal, VirtualBox Guest Additions, Puppet 3.7.5 - see here for more infos)を選ぶ。

コマンドの意味はvagrant box {付けたい名前} {boxのURL}

$ vagrant box add CentOS6.6 https://github.com/tommy-muehle/puppet-vagrant-boxes/releases/download/1.0.0/centos-6.6-x86_64.box
==> box: Box file was not detected as metadata. Adding it directly...
==> box: Adding box 'CentOS6.6' (v0) for provider:
    box: Downloading: https://github.com/tommy-muehle/puppet-vagrant-boxes/releases/download/1.0.0/centos-6.6-x86_64.box
    box:
==> box: Successfully added box 'CentOS6.6' (v0) for 'virtualbox'!

3. Vagrant用のディレクトリを作成する

BOXの追加に成功したら、仮想環境用のディレクトリを作成

C:\>mkdir CentOS6.6
C:\>cd CentOS6.6

4. 仮想環境を定義する.Vagrantfileなどの初期化を行う

C:\CentOS6.6>vagrant init CentOS6.6
A `Vagrantfile` has been placed in this directory. You are now
ready to `vagrant up` your first virtual environment! Please read
the comments in the Vagrantfile as well as documentation on
`vagrantup.com` for more information on using Vagrant.

5. 初期化が完了したら、CentOSを起動する

C:\CentOS6.6>vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Importing base box 'CentOS6.6'...
==> default: Matching MAC address for NAT networking...
==> default: Setting the name of the VM: CentOS66_default_1589977223313_63395
==> default: Clearing any previously set forwarded ports...
==> default: Clearing any previously set network interfaces...
==> default: Preparing network interfaces based on configuration...
    default: Adapter 1: nat
==> default: Forwarding ports...
    default: 22 (guest) => 2222 (host) (adapter 1)

  (中略)

==> default: Mounting shared folders...
    default: /vagrant => C:/CentOS6.6

6. ssh接続を行う

sshクライアントがないようだったら、Tera TermCygwinを用意する。
ターミナルからの接続だと、ログインするときにパスワードを聞かれることがある。
パスワードはvagrantで大丈夫(なはず)。

C:\CentOS6.6>vagrant ssh

その後、現在のディレクトリを確認。
今後の導入作業でディレクトリを転々とすることが多いので、最初はどこに居たのか覚えておく。

[vagrant@localhost ~]$ pwd
/home/vagrant

8. localeの変更

localeは言語や日時などの設定。
今回導入したCentOSは初期設定だとドイツ語だったので、作業しやすいように日本語に変更する。
locale変更方法(CentOS6.5) - Qiitaを参考に実行していく。

$ localeで現在の設定を確認。

[vagrant@localhost ~]$ locale
LANG=de_DE.UTF-8
LC_CTYPE="de_DE.UTF-8"
LC_NUMERIC="de_DE.UTF-8"
LC_TIME="de_DE.UTF-8"
LC_COLLATE="de_DE.UTF-8"
LC_MONETARY="de_DE.UTF-8"
LC_MESSAGES="de_DE.UTF-8"
LC_PAPER="de_DE.UTF-8"
LC_NAME="de_DE.UTF-8"
LC_ADDRESS="de_DE.UTF-8"
LC_TELEPHONE="de_DE.UTF-8"
LC_MEASUREMENT="de_DE.UTF-8"
LC_IDENTIFICATION="de_DE.UTF-8"
LC_ALL=

$ locale -aで設定できるlocale一覧を表示。
一覧の中にja_JP.utf8があるのを確認する。

[vagrant@localhost ~]$ locale -a
[vagrant@localhost ~]$ sudo vim /etc/sysconfig/i18n

LANG="ja_JP.UTF-8"にする。

LANG="ja_JP.UTF-8"
SYSFONT="latarcyrheb-sun16"

. {ファイル}で{ファイル}を読み込む。
最後に$ localeを入力して、ja_JP.UTF-8になっているかを確認。

[vagrant@localhost ~]$ . /etc/sysconfig/i18n
[vagrant@localhost ~]$ locale
LANG=ja_JP.UTF-8
LC_CTYPE="ja_JP.UTF-8"
LC_NUMERIC="ja_JP.UTF-8"
LC_TIME="ja_JP.UTF-8"
LC_COLLATE="ja_JP.UTF-8"
LC_MONETARY="ja_JP.UTF-8"
LC_MESSAGES="ja_JP.UTF-8"
LC_PAPER="ja_JP.UTF-8"
LC_NAME="ja_JP.UTF-8"
LC_ADDRESS="ja_JP.UTF-8"
LC_TELEPHONE="ja_JP.UTF-8"
LC_MEASUREMENT="ja_JP.UTF-8"
LC_IDENTIFICATION="ja_JP.UTF-8"
LC_ALL=

9. 既存パッケージのアップグレード

CentOsではyumというパッケージマネージャーが使用されている。
これから色んなソフトをインストールしていくのに備えて、yumで管理されているパッケージのアップグレードを行う。

[vagrant@localhost ~]$ sudo yum -y upgrade

Apache2.4

Apache: 世界中で利用されているWebサーバーツール。

以下の記事を参考にApacheを導入していく。
基本は、

エラーの対応に使ったのは、

1. ディレクトリの移動

[vagrant@localhost /]$ cd /usr/local/src

2. Apacheの導入に必要なyumパッケージのインストール

[vagrant@localhost src]$ sudo yum install -y wget apr-devel apr-util-devel gcc pcre pcre-devel perl perl-devel libtool libtool-devel systemd-devel

3. Apacheの構築に必要なアプリをインストール

makeyumなどとは違う方法でアプリをインストールする方法。
Index of /apache/aprから最新のapr-{バージョン},apr-util-{バージョン}を確認。下記は実行当時の物。
pcrePCRE - Browse /pcre/8.44 at SourceForge.netから最新のバージョンを確認し、pcre-{バージョン}.tar.gzを入力。

[vagrant@localhost src]$ sudo wget http://mirrors.ocf.berkeley.edu/apache//apr/apr-1.7.0.tar.gz
[vagrant@localhost src]$ tar xzf apr-1.5.2.tar.gz
[vagrant@localhost src]$ cd apr-1.7.0
[vagrant@localhost apr-1.7.0]$ ./configure
[vagrant@localhost apr-1.7.0]$ make
[vagrant@localhost apr-1.7.0]$ make install

[vagrant@localhost apr-1.7.0]$ cd ..
[vagrant@localhost src]$ sudo wget http://mirrors.ocf.berkeley.edu/apache//apr/apr-util-1.6.1.tar.gz
[vagrant@localhost src]$ sudo tar xzf apr-util-1.6.1.tar.gz 
[vagrant@localhost src]$ cd apr-util-1.6.1
[vagrant@localhost apr-util-1.6.1]$ sudo ./configure --with-apr=/usr/local/src/apr-1.7.0
[vagrant@localhost apr-util-1.6.1]$ sudo make
[vagrant@localhost apr-util-1.6.1]$ sudo make install

[vagrant@localhost apr-util-1.6.1]$ cd ..
[vagrant@localhost src]$ sudo wget https://sourceforge.net/projects/pcre/files/pcre/8.44/pcre-8.44.tar.gz
[vagrant@localhost src]$ sudo tar xzf pcre-8.44.tar.gz
[vagrant@localhost src]$ cd pcre-8.44
[vagrant@localhost pcre-8.44]$ sudo ./configure
[vagrant@localhost pcre-8.44]$ sudo make
[vagrant@localhost pcre-8.44]$ sudo make install

4. Apacheのインストール

httpd: CentOSなどのサーバーに在住してるHTTPSの処理を行うデーモン
Index of /software/apache/httpdからhttpd-{バージョン}.tar.gzを確認。下記は実行当時の物。

[vagrant@localhost pcre-8.44]$ cd ..
[vagrant@localhost src]$ sudo wget http://ftp.tsukuba.wide.ad.jp/software/apache//httpd/httpd-2.4.43.tar.gz
[vagrant@localhost src]$ sudo tar xzf httpd-2.4.43.tar.gz
[vagrant@localhost src]$ sudo cp -Rp /usr/local/src/apr-1.7.0 /usr/local/src/httpd-2.4.43/srclib/apr
[vagrant@localhost src]$ sudo cp -Rp /usr/local/src/apr-util-1.6.1 /usr/local/src/httpd-2.4.43/srclib/apr-util
[vagrant@localhost src]$ cd httpd-2.4.43
[vagrant@localhost httpd-2.4.43]$ ./configure --with-pcre=/usr/local/src/pcre-8.44/pcre-config --enable-rewrite --with-icluded-apr

Server Version: 2.4.43
    Install prefix: /usr/local/apache2
    C compiler:     gcc -std=gnu99
    CFLAGS:          -g -O2 -pthread
    CPPFLAGS:        -DLINUX -D_REENTRANT -D_GNU_SOURCE
    LDFLAGS:
    LIBS:
    C preprocessor: gcc -E

[vagrant@localhost httpd-2.4.43]$ sudo make
[vagrant@localhost httpd-2.4.43]$ sudo make install

5. Apache起動スクリプトの作成

[vagrant@localhost httpd-2.4.43]$ cd /home/vagrant
[vagrant@localhost ~]$ sudo cp -ip /usr/local/src/httpd-2.4.43/build/rpm/httpd.init /etc/init.d/httpd
[vagrant@localhost ~]$ sudo vim /etc/init.d/httpd
/etc/init.d/httpd
#60行目あたり
httpd=${HTTPD-/usr/local/apache2/bin/httpd}
pidfile=${PIDFILE-/usr/local/apache2/logs/httpd.pid}
#追記
CONFFILE=/usr/local/apache2/conf/httpd.conf

yumなどを使ってパッケージインストールからApacheを導入したようにhttpdを使えるようにする。

[vagrant@localhost ~]$ sudo vim /usr/local/apache2/conf/httpd.conf
/usr/local/apache2/conf/httpd.conf
#164行目あたり
User apache
Group apache
[vagrant@localhost ~]$ sudo groupadd -g 48 apache
[vagrant@localhost ~]$ sudo useradd -g apache -u 48 apache

6. Apacheの起動

[vagrant@localhost ~]$ sudo chkconfig --add httpd
[vagrant@localhost ~]$ sudo chkconfig httpd on

一旦、仮想環境をシャットダウン。

[vagrant@localhost ~]$ sudo shutdown -h now

7. .Vagrantfileの編集

windowsのエディターとかから、仮想環境用のディレクトリにある.Vagrantfileを編集する。
この編集によって、windowsのブラウザからCentOSで操作したファイルを共有したり、ブラウザで確認できるようになる。
以下のように編集する。

Vagrantfile.
 (中略)

  # Create a private network, which allows host-only access to the machine
  # using a specific IP.
  config.vm.network "private_network", ip: "192.168.33.10"

  (中略)

  # Provider-specific configuration so you can fine-tune various
  # backing providers for Vagrant. These expose provider-specific options.
  # Example for VirtualBox:
  #
  config.vm.provider "virtualbox" do |vb|
    vb.customize ["modifyvm", :id, "--memory", "1024"]
  end
  #   # Display the VirtualBox GUI when booting the machine
  #   vb.gui = true
  #
  #   # Customize the amount of memory on the VM:
  #   vb.memory = "1024"
  # end
  #
  # View the documentation for the provider you are using for more
  # information on available options.

  # Enable provisioning with a shell script. Additional provisioners such as
  # Ansible, Chef, Docker, Puppet and Salt are also available. Please see the
  # documentation for more information about their specific syntax and use.
  # config.vm.provision "shell", inline: <<-SHELL
  #   apt-get update
  #   apt-get install -y apache2
  # SHELL
   config.vm.synced_folder "../VB_share", "/usr/local/apache2/htdocs", mount_options:['dmode=777','fmode=777']
end

仮想環境用のディレクトリを作成した所にVB_shareを作成。
その中に下記ファイルを追加。

index.html
 <h1>Helo,World!!</h1>

8. Apacheが稼働しているか確認

C:\CentOS6.6>vagrant reload
==> default: Clearing any previously set forwarded ports...
==> default: Clearing any previously set network interfaces...
==> default: Preparing network interfaces based on configuration...
    default: Adapter 1: nat
    default: Adapter 2: hostonly
==> default: Forwarding ports...
    default: 22 (guest) => 2222 (host) (adapter 1)
  
  (中略)

==> default: Mounting shared folders...
    default: /vagrant => C:/CentOS6.6
    default: /var/www/html => C:/VB_share
==> default: Machine already provisioned. Run `vagrant provision` or use the `--provision`
==> default: flag to force provisioning. Provisioners marked to run always will still run.

C:\CentOS6.6>vagrant ssh

以下のURLをクリックして、その下の画像のような表示がされたらApacheは無事起動している。
http://192.168.33.10/index.html

screeenshot.png

PHP5.3

atton.blog: php 5.x + apache httpd 2.4.x を make するを参考に進めていく。

1. PHPのインストール

PHP: Releasesから欲しいPHPのバージョンを確認。
今回は5.3系の中で一番新しい5.3.29を。

./configure --with-apxs2=/usr/local/apache2/bin/apxsApachePHP5系を認識してもらうlibphp5.soを作るためのもの。
これを書いておくとhttpd.confLoadModuleできる場所にlibphp5.soが自動で作成される。

[vagrant@localhost /]$ cd /usr/local/src
[vagrant@localhost src]$ sudo yum install -y libxml2 libxml2-devel
[vagrant@localhost src]$ sudo wget http://jp2.php.net/get/php-5.3.29.tar.gz/from/this/mirror -O php-5.3.29.tar.gz
[vagrant@localhost src]$ sudo tar xzf php-5.3.29.tar.gz
[vagrant@localhost src]$ cd php-5.3.29
[vagrant@localhost php-5.3.29]$ sudo ./configure --with-apxs2=/usr/local/apache2/bin/apxs

+--------------------------------------------------------------------+
| License:                                                           |
| This software is subject to the PHP License, available in this     |
| distribution in the file LICENSE.  By continuing this installation |
| process, you are bound by the terms of this license agreement.     |
| If you do not agree with the terms of this license, you must abort |
| the installation process at this point.                            |
+--------------------------------------------------------------------+

Thank you for using PHP.

[vagrant@localhost php-5.3.29]$ sudo make
[vagrant@localhost php-5.3.29]$ sudo make test
[vagrant@localhost php-5.3.29]$ sudo make install
[vagrant@localhost php-5.3.29]$ php -v
PHP 5.3.29 (cli) (built: May 21 2020 04:19:38)
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2014 Zend Technologies

2. httpd.conf`の編集

ApachePHP5.3を認識してもらえるように/usr/local/apache2/conf/httpd.confを編集する。

[vagrant@localhost php-5.3.29]$ sudo vim /usr/local/apache2/conf/httpd.conf
/usr/local/apache2/conf/httpd.conf
#あるか確認。なかったら追加。
LoadModule php5_module modules/libphp5.so

#一番下に追記。
<FilesMatch \.php$>
    SetHandler application/x-httpd-php
</FilesMatch>

3. ApacheがPHP5.3を認識しているか確認

先程index.htmlを作成したVB_shareに下記ファイルを追加。

info.php
<?php  phpinfo(); ?>

index.htmlの時と同様、下のURLをクリックして、その下の画像が表示されているか確認。

http://192.168.33.10/info.php
screeenshot.png

+a php.iniを編集

Apache2 PHP5 インストール | CentOSサーバー構築マニュアル.comを参考に、PHPの設定を行う。

[vagrant@localhost /]$ cd /usr/local/src/php-5.3.29
[vagrant@localhost php-5.3.29]$ sudo cp php.ini-development /usr/local/lib/php.ini
[vagrant@localhost php-5.3.29]$ sudo vim /usr/local/lib/php.ini

MySQL5.5

CentOSにMySQL 5.5をバージョン指定してインストール | 俺日記を参考に進めていく。

1. yumを使ったパッケージ操作

[vagrant@localhost ~]$ sudo yum remove mysql*
[vagrant@localhost ~]$ sudo yum -y install http://dev.mysql.com/get/mysql-community-release-el6-5.noarch.rpm
[vagrant@localhost ~]$ sudo vim /etc/yum.repos.d/mysql-community.repo

何も操作しないと、MySQL5.6がインストールされるため、MySQL5.5がインストールされるように、/etc/yum.repos.d/mysql-community.repoを編集する。

/etc/mysql-community.repo
# Enable to use MySQL 5.5
[mysql55-community]
name=MySQL 5.5 Community Server
baseurl=http://repo.mysql.com/yum/mysql-5.5-community/el/6/$basearch/
enabled=1
gpgcheck=1
gpgkey=file:/etc/pki/rpm-gpg/RPM-GPG-KEY-mysql

# Enable to use MySQL 5.6
[mysql56-community]
name=MySQL 5.6 Community Server
baseurl=http://repo.mysql.com/yum/mysql-5.6-community/el/6/$basearch/
enabled=0
gpgcheck=1
gpgkey=file:/etc/pki/rpm-gpg/RPM-GPG-KEY-mysql
[vagrant@localhost ~]$ sudo yum -y install mysql mysql-devel mysql-server mysql-utilities

2. MySQLの起動と確認

[vagrant@localhost ~]$ sudo service mysqld start
[vagrant@localhost ~]$ sudo chkconfig mysqld on
[vagrant@localhost ~]$ sudo service mysqld status
mysqld (pid  3173) を実行中...
[vagrant@localhost ~]$ mysql --version
mysql  Ver 14.14 Distrib 5.5.62, for Linux (x86_64) using readline 5.1

3. MySQLの設定

MySQLにとって重要なmysql.sockの場所を確認する。

[vagrant@localhost ~]$ sudo /usr/bin/mysqladmin -u root password "{好きなパスワードを設定}"
[vagrant@localhost ~]$ sudo mysql -u root -p
Enter password:
mysql> show variables like "%sock%";
+---------------+---------------------------+
| Variable_name | Value                     |
+---------------+---------------------------+
| socket        | /var/lib/mysql/mysql.sock |
+---------------+---------------------------+
1 row in set (0.00 sec)

MySQLの文字コードを確認する。

mysql> show variables like "%chara%";
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | utf8                       |
| character_set_connection | utf8                       |
| character_set_database   | latin1                     |
| character_set_filesystem | binary                     |
| character_set_results    | utf8                       |
| character_set_server     | latin1                     |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.00 sec)

mysql> exit
Bye

[vagrant@localhost ~]$

character_set_databasecharacter_set_serverをUTF-8に変更する。
mysqlで文字コードをutf8にセットする - Qiitaを参考に作業する。

[vagrant@localhost ~]$ sudo vim /etc/my.cnf
/etc/my.cnf
[mysqld]
character-set-server=utf8

[client]
default-character-set=utf8
[vagrant@localhost ~]$ sudo service mysqld restart
mysqld を停止中:                                           [  OK  ]
mysqld を起動中:                                           [  OK  ]
[vagrant@localhost ~]$ sudo mysql -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.5.62 MySQL Community Server (GPL)

Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show variables like "%chara%";
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | utf8                       |
| character_set_connection | utf8                       |
| character_set_database   | utf8                       |
| character_set_filesystem | binary                     |
| character_set_results    | utf8                       |
| character_set_server     | utf8                       |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.00 sec)

参考資料

Windowsの設定

VirtualBox + Vagrant + CentOS

Apache2.4

PHP5.3

MySQL5.5

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

MAMPのインストール

概要

自宅サーバーを立ち上げるため、MAMPを利用してみました。

MAMP とは

  • Mac
  • Apache
  • MySQL
  • PHP

の略と言われてるようですが、Win版もあるし、公式ページに特にこの事についての記載が発見できず、正確な情報は不明です。

パッケージのダウンロード

まずは、MAMP公式サイトからパッケージをダウンロードしましょう。
https://www.mamp.info/en/
公式サイトのFreeDonwloadをクリック
20190601171820-1024x725.png
Downloadページで mac のパッケージを選択
20190601171827-1024x725.png
バージョンはアクセスのタイミングで変わるかと思いますが、インストール用の pkg ファイルがダウンロードできます。
20190601171957.png

インストール

pkgファイルをダブルクリックすると、インストール手続きが始まります。

使用承諾やインストール先の選択等がありますので、指示に従いながら勧めていきます。
20190601172320.png
20190601172654.png

MAMPの起動

インストールが完了したら、MAMP起動します。デフォルト設定でインストールをしていれば、アプリケーションフォルダになっていると思うので、Launchpad等から起動できます。

※PROとFREE版があるので、FREEの方を起動。
20190601173135-1024x576.png
起動したらコントロール画面が表示されるので、「Start Servers」をクリックしてApacheとMySQLを起動します。20190601173503.png
起動が完了すると、「Start Servers」が緑になりブラウザで初期ページが表示されます。
20190601173729.png
20190601173749-1024x869.png
以上でインストールは完了です。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

MacにMAMPをインストールする

概要

自宅のMacにWebサーバーを立ち上げるため、MAMPを利用してみました。

MAMP とは

  • Mac
  • Apache
  • MySQL
  • PHP

の略と言われてるようですが、Win版もあるし、公式ページに特にこの事についての記載が発見できず、正確な情報は不明です。

インストール手順

パッケージのダウンロード

まずは、MAMP公式サイトからパッケージをダウンロードしましょう。
https://www.mamp.info/en/
公式サイトのFreeDonwloadをクリック
20190601171820-1024x725.png
Downloadページで mac のパッケージを選択
20190601171827-1024x725.png
バージョンはアクセスのタイミングで変わるかと思いますが、インストール用の pkg ファイルがダウンロードできます。
20190601171957.png

インストール

pkgファイルをダブルクリックすると、インストール手続きが始まります。

使用承諾やインストール先の選択等がありますので、指示に従いながら勧めていきます。
20190601172320.png
20190601172654.png

MAMPの起動

インストールが完了したら、MAMP起動します。デフォルト設定でインストールをしていれば、アプリケーションフォルダになっていると思うので、Launchpad等から起動できます。

※PROとFREE版があるので、FREEの方を起動。
20190601173135-1024x576.png
起動したらコントロール画面が表示されるので、「Start Servers」をクリックしてApacheとMySQLを起動します。20190601173503.png
起動が完了すると、「Start Servers」が緑になりブラウザで初期ページが表示されます。
20190601173729.png
20190601173749-1024x869.png
以上でインストールは完了です。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravelのアクセサ

はじめに

例えばviewで人の氏名を実装する時苗字+名前といちいち実装するのは手間がかかりますよね。
今回のお題であるアクセサというLaravelの機能を用いれば、Modelに苗字+名前と定義しておくだけで、viewで呼び出す時は氏名で一気にフルネームを呼び出すことができます。

アクセサを使って実装する

そもそもアクセサとは

アクセサを定義するには、アクセスしたいカラム名が「studlyケース(Upper Camel Case)」でFooの場合、getFooAttributeメソッドをモデルに作成します。以下の例では、first_name属性のアクセサを定義しています。first_name属性の値にアクセスが起きると、Eloquentは自動的にこのアクセサを呼び出します。
Eloquent:ミューテタ 7.x Laravel

Laravelの公式ドキュメントには上記のように定義されています。
簡単にまとめるとModelにget〜Attribute(今回の場合はgetFullNameAttribute)というメソッドを定義すると、それをuseしたControllerやviewでfull_name(今回の場合は$this->full_name)属性の値で呼び出せます。

Model
namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * ユーザーのフルネームを取得
     *
     * @return string
     */
    public function getFullNameAttribute()
    {
        return this->last_name . this->first_name;
    }
}
view
<?php

    {{ $this->full_name }}

おわりに

いかがでしたでしょうか。
今回のようにModelに定義しておくことでフルネームを表示するに「山田花子」「山田 花子」「山田 花子」みたいに人によってスペース開けたり開けなかったり、半角スペースだったりすると思うので、まとめて定義しておくと保守性が上がるでしょう。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

header(Location)へパラメーターIDを使用したい時

header("Location: index.php?=id".$REQUEST['id']) ;としてやると使用できる。

この時()内はシングルクォーテーションではなくダブルクォーテーションでないと動作しないので注意!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravelのログイン機能にSNS認証を追加する(socialite)

socialiteでSNSログインを実装

Laravelで、SNSのアカウントを使ったログインの実装をした時のメモです。

socialiteとは

soscialiteとは、Laravelで簡単にOAuth(SNS認証)を可能にするパッケージツールです。

はじめに、composerを使ってsocialiteをインストールします。

$ composer require laravel/socialite

コンフィグレーション

Socialiteを使用する前に、アプリケーションが使用するOAuthサービスの認証情報を設定します。

services.phpの設定

認証情報を必要とする各プロバイダーの設定を行います。

config/services.php
return [

    'github' => [
        'client_id' => env('GITHUB_CLIENT_ID'),
        'client_secret' => env('GITHUB_CLIENT_SECRET'),
        'redirect' => env('APP_URL') . '/login/github/callback',
    ],

    'google' => [
        'client_id' => env('GOOGLE_CLIENT_ID'),
        'client_secret' => env('GOOGLE_CLIENT_SECRET'),
        'redirect' => env('APP_URL') . '/login/google/callback',
    ],

    'facebook' => [
        'client_id' =>  env('FACEBOOK_APP_ID'),
        'client_secret' => env('FACEBOOK_APP_SECRET'),
        'redirect' =>  env('APP_URL') . '/login/facebook/callback',
    ],
];

app.phpでsocialiteの設定を行います。

config/app.php
    'providers' => [
        // 追加
        Laravel\Socialite\SocialiteServiceProvider::class,
    ],

    'aliases' => [
        // 追加
        'Socialite' => Laravel\Socialite\Facades\Socialite::class,
    ],

ルーティング

次に、ユーザーを認証する準備ができました。2つのルートが必要になります。

1つはユーザをOAuthプロバイダにリダイレクトするためのもので、もう1つは認証後にプロバイダからのコールバックを受け取るためのものです。

Socialite ファサードを使って Socialite にアクセスします。

Controllerの設定

設定した情報からSNS認証ログインを実装します。

App/Http/Controllers/Auth/LoginController.php
<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;

use Hash;
use Auth;
use Socialite;
use App\User;

class LoginController extends Controller
{
    use AuthenticatesUsers;

    protected $redirectTo = '/home';

    public function __construct()
    {
        $this->middleware('guest')->except('logout');
    }

    public function redirectToProvider($social)
    {
        return Socialite::driver($social)->redirect();
    }

    public function handleProviderCallback($social)
    {

        $socialUser = Socialite::driver($social)->user();

        // 第一引数の配列内の条件に合致するものがなければ、第二引数の配列内のkeyとvalueでDBへ作成
        $user = User::firstOrCreate(
            ['provider_id' => $socialUser->getId()],
            ['name' => $socialUser->getName(),
            'provider' => $social,
            'provider_id' => $socialUser->getId(),
            ]
        );

        Auth::login($user, true);
        return redirect('/home');
    }

}

Userクラスの設定

ログイン時に新規作成するUserテーブルは、挿入できるように追記しておきます。

App/User.php
class User extends Authenticatable
{
    use Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password', 'provider_id', 'provider', // カラムを追記
    ];

マイグレーションの設定

emailやpasswordがなくてもユーザー登録ができるように、nullable()を追記します。

database/migrations/2014_10_12_000000_create_users_table.php
class CreateUsersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('provider')->nullable();
            $table->string('provider_id')->nullable();
            $table->unique(['provider', 'provider_id']);
            $table->string('name');
            $table->string('email')->unique()->nullable();
            $table->string('password')->nullable();
            $table->rememberToken();
            $table->timestamps();
        });
    }

web.phpの設定

web.phpにてログイン画面でボタンをクリックしたときのリンクを設定します。

たとえば、シンプルにGitHubだけで実装する場合には下記のようになります。

web.php
Auth::routes();
Route::get('/home', 'HomeController@index')->name('home');

Route::get('login/github', 'Auth\LoginController@redirectToProvider');
Route::get('login/github/callback', 'Auth\LoginController@handleProviderCallback');

複数のプロバイダーで認証を実装する場合は、引数に変数を用いて変換します。

web.php
// SNS認証 ログインボタンのリンク
Route::get('/login/{social}', 'Auth\LoginController@redirectToProvider')->where('social', 'github|google|facebook');
// コールバック用
Route::get('/login/{social}/callback', 'Auth\LoginController@handleProviderCallback')->where('social', 'github|google|facebook');

Viewの設定

ログイン画面のテンプレートに追記します。
(※下記の例では、Bootstrapを使用しています。)

login.blade.php
    <div class="form-group row mt-5">
        <label for="name" class="col-sm-4 col-form-label text-md-right">SNSログイン</label>
        <div class="col-md-6">
            <a href="{{ url('login/google')}}" class="btn btn-danger"><i class="fa fa-google"> Google</i></a>
            <a href="{{ url('login/facebook')}}" class="btn btn-primary"><i class="fa fa-facebook"> Facebook</i></a>
            <a href="{{ url('login/github')}}" class="btn btn-secondary"><i class="fa fa-github"> GitHub</i></a>
        </div>
    </div>

デフォルトのログインテンプレートに追記すると、このように表示されます。
スクリーンショット 0032-05-23 8.16.02.png

.envの設定

.envファイルにて各SNSで取得したクライアントIDとシークレットIDを設定。

GITHUB_CLIENT_ID=xxxxxxxxxxxxxxxxxxxx
GITHUB_CLIENT_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

GOOGLE_CLIENT_ID=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=xxxxxxxxxxxxxxxxxxxxxxxx

FACEBOOK_APP_ID=xxxxxxxxxxxxxxx
FACEBOOK_APP_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Gutenberg で生成されてしまう空の <p></p> タグを the_content() 読み込み時に削除する方法

WordPressの Gutenberg エディターでは、新規ブロックが自動生成されて、空の <p></p> が保存されてしまうことがよくある。

この問題には、functions.php などに次のコードを追記することで対処できる。

// the_content 用フィルター.
add_filter(
    'the_content',
    function ( $content ) {
        $content = str_replace( '<p></p>', '', $content );
        return $content;
    }
);

これで、the_content() で、<p></p> が削除された状態の記事本文が読み込まれるようになる。

なお、get_the_content() は、フィルターが適応されていない状態の記事を取得するので、要注意。

関連ドキュメント

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

PHPで将棋のUSIプロトコルに挑戦

はじめに

PHPで将棋のUSIプロトコルに挑戦します。→JScript版はこちら
将棋ソフトは各自用意してください。

USIプロトコルの例

USIプロトコルの例です。これをPHPで書いていきます。

将棋ソフトと通信を開始し、初手76歩とした局面を1秒間検討し、評価値や読み筋を取得するのが目的です。
>で始まる行はコマンド送信、それ以外は受信となります。

>usi
id name NNUE-v1.0 64SSE2 (based on YaneuraOu 2018 Otafuku 4.82)
id author by yaneurao, extended by ynasu87
option name Threads type spin default 4 min 1 max 512
option name Hash type spin default 16 min 1 max 1048576
option name MultiPV type spin default 1 min 1 max 800
option name WriteDebugLog type check default false
option name NetworkDelay type spin default 120 min 0 max 10000
option name NetworkDelay2 type spin default 1120 min 0 max 10000
option name MinimumThinkingTime type spin default 2000 min 1000 max 100000
option name SlowMover type spin default 100 min 1 max 1000
option name MaxMovesToDraw type spin default 0 min 0 max 100000
option name DepthLimit type spin default 0 min 0 max 2147483647
option name NodesLimit type spin default 0 min 0 max 9223372036854775807
option name Contempt type spin default 2 min -30000 max 30000
option name ContemptFromBlack type check default false
option name EnteringKingRule type combo default CSARule27 var NoEnteringKing var CSARule24 var CSARule27 var TryRule
option name EvalDir type string default eval
option name SkipLoadingEval type check default false
option name NarrowBook type check default false
option name BookMoves type spin default 16 min 0 max 10000
option name BookIgnoreRate type spin default 0 min 0 max 100
option name BookFile type combo default standard_book.db var no_book var standard_book.db var yaneura_book1.db var yaneura_book2.db var yaneura_book3.db var yaneura_book4.db var user_book1.db var user_book2.db var user_book3.db var book.bin
option name BookEvalDiff type spin default 30 min 0 max 99999
option name BookEvalBlackLimit type spin default 0 min -99999 max 99999
option name BookEvalWhiteLimit type spin default -140 min -99999 max 99999
option name BookDepthLimit type spin default 16 min 0 max 99999
option name BookOnTheFly type check default false
option name ConsiderBookMoveCount type check default false
option name PvInterval type spin default 300 min 0 max 100000
option name ResignValue type spin default 99999 min 0 max 99999
option name nodestime type spin default 0 min 0 max 99999
option name Param1 type spin default 0 min 0 max 100000
option name Param2 type spin default 0 min 0 max 100000
option name EvalSaveDir type string default evalsave
option name ConsiderationMode type check default false
option name OutputFailLHPV type check default true
usiok

>isready
readyok

>usinewgame
>position startpos moves 7g7f
>go byoyomi 1100
info depth 1 seldepth 1 score cp -84 nodes 82 nps 41000 time 2 pv 8c8d
info depth 2 seldepth 2 score cp -60 nodes 121 nps 40333 time 3 pv 8c8d 2g2f
info depth 10 seldepth 12 score cp -41 nodes 41683 nps 150480 time 277 pv 3c3d 2g2f 4a3b 5i6h 5a4b 4i5h 8c8d 6i7h 2b8h+
bestmove 3c3d ponder 2g2f

>quit

infoで始まる行にて、評価値や読み筋を取得できます。
score cpに続く数字が評価値、pvに続く文字列が読み筋です。

PHPでの記述例

PHPではproc_open()fgets()fwrite()の3つを使用します。
もっと良い方法があると思いますが、分かりません。

<?php
$process = proc_open('YaneuraOu.exe', [['pipe','r'],['pipe', 'w']], $pipe);
if (!is_resource($process)) {
    exit;
}

fwrite($pipe[0], "usi\n");

while(1){
    $line = fgets($pipe[1]);
    print $line;
    if(preg_match('/^usiok/', $line)){
        break;
    }
}

fwrite($pipe[0], "isready\n");
print fgets($pipe[1]);

fwrite($pipe[0], "usinewgame\n");
fwrite($pipe[0], "position startpos moves 7g7f\n");
fwrite($pipe[0], "go byoyomi 1100\n");

while(1){
    $line = fgets($pipe[1]);
    print $line;
    if(preg_match('/^bestmove/', $line)){
        break;
    }
}

fwrite($pipe[0], "quit\n");
proc_close($process);

続けて2手目(34歩)を検討するには、quitの前に次のようなコマンドを送信します。
指し手を2つ書くだけなので簡単です。

>position startpos moves 7g7f 3c3d
>go byoyomi 1100

7g7fなどの指し手の表記方法については、以下の説明と参考サイトを参考にしていください。

筋に関しては1から9までの数字で表記され、段に関してはaからiまでのアルファベット(1段目がa、2段目がb、・・・、9段目がi)というように表記されます。
位置の表記は、この2つを組み合わせます。5一なら5a、1九なら1iとなります。
そして、指し手に関しては、駒の移動元の位置と移動先の位置を並べて書きます。7七の駒が7六に移動したのであれば、7g7fと表記します。(駒の種類を表記する必要はありません。)
駒が成るときは、最後に+を追加します。8八の駒が2二に移動して成るなら8h2b+と表記します。
持ち駒を打つときは、最初に駒の種類を大文字で書き、それに*を追加し、さらに打った場所を追加します。金を5二に打つ場合はG*5bとなります

参考サイト

http://shogidokoro.starfree.jp/usi.html
https://qiita.com/tag1216/items/aa4ddc9354c83c66d1b4

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravelでメールを送信する

参考:Laravelのmailableクラスでメール送信を行う[導入/入門編]

mailableクラス

$ php artisan make:mail sampleMailClass.php

を実行後、以下のように記述

laravel-project/app/Mail/sampleMailClass.php
<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use App\Encyclopedia;

class sampleMailClass extends Mailable
{
    use Queueable, SerializesModels;

    protected $name; // メンバ変数
    protected $content;

    /**
     * Create a new message instance.
     *
     * @return void
     */
    public function __construct($mailData) // コンストラクタ
    {
        $this->name = $mailData['name'];
        $this->content = $mailData['content'];
    }

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
         $this->text('view.page') // メール本文のイメージを記述したview 後ほど記述
                ->subject('お問い合わせが届きました')// メールタイトル
                ->with([
                    'name'    => $this->name,
                    'content' => $this->content
                ]); // viewに渡す引数
    }
}

簡単なビューページ

page.blade.php
<form action="controller">
 <label for="name">名前:</label>
 <input type="text" name="name" value="">
 <br>
<label for="content">内容</label> 
<textarea name="content" value=""></textarea>
 <br>
<button type="submit"  class="btn btn-primary">
 送信
 </button>


メールを送りました!!

名前:{{$name ?? ''}} {{-- 空チェック --}}
<br>
本文{{$content ?? ''}} {{-- 空チェック --}}

ルーティング

ルーティングは以下のように設定

web.php
Route::get('controller', 'Controller@notification'); 

コントローラー

$ php artisan make:controller Controller

実行後、以下のように記述

laravel-project/app/Mail/Controller.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;
use App\Mail\SendContact;

class Controller extends Controller
{
    public function notification(Request $request)
    {
        $contactData = [
            'name' => $request->name,
            'content' => $request->content                   
        ];
        $name = $request->name;
        $content = $request->content;
        $to = 'utsupedia@gmail.com';
        Mail::to($to)->send(new SendContact($contactData));

        return view('contact.result', ['contactData' => $contactData]);
    }
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

PHPのCallableについて完全に理解する

はじめに

Callable という擬似型は PHP 5.4 系で導入されていたようなのですが、ある値が Callable かどうかがどのように決まるのかさっぱり理解できず、業務で使う機会もそんなになかったことから放置していました。

業務で使う機会が出てきたというわけでも全くもって全くないのですが、ふと考えてみたら完全に理解できた気がしてしまったので、ツッコミ覚悟で記事にまとめることにしました。

この記事ではどんな値を is_callable() に渡したら true を返されるのかを探っていきます。 is_callable()true を返す値はそのまま call_user_func() , call_user_func_array() などに渡して呼び出すことが可能です。

var_dump() を含んだコードの動作確認は paiza.IO で行っています。執筆時のPHPバージョンは PHP 7.4.1 でした。

この記事のスコープ外

「関数やクラスがどの時点で定義されるのか」というのは、これはこれで複雑な話題です。

この記事では、「関数やクラスが定義されているかどうか」を明確にした上で Callable かどうかの判定方法を理解したいため、関数やクラスの定義方法は最もシンプルなもののみを用います。

<?php

// シンプルな関数定義
function someFunction() {}

// シンプルなクラス定義
class SomeClass()
{
    public static funcion SomeClassMethod() {}
    public function SomeObjectMethod() {}
}

// シンプルでない関数定義たち
if (true) {
    function anotherFunction() {}
}
function defineYetAnotherFunction()
{
    function yetAnotherFunction() {}
}

// シンプルでないクラス定義たち
if (true) {
    class AnotherClass()
    {
        public static funcion AnotherClassMethod() {}
        public function AnotherObjectMethod() {}
    }
}
function defineYetAnotherClass()
{
    class YetAnotherClass()
    {
        public static funcion YetAnotherClassMethod() {}
        public function YetAnotherObjectMethod() {}
    }
}

:: を含まない文字列

文字列と同じ名前の関数が定義されている場合は Callable であり、そうでない場合は Callable でない、と判定されます。

<?php

function is_odd(int $int): bool
{
    return $int % 2 === 1;
}

var_dump(is_callable('is_odd'));
// => bool(true)

var_dump(is_callable('is_even'));
// => bool(false)

:: の両側になんかある文字列

:: の左側の文字列と同じ名前のクラスが定義されていて、かつ :: の右側の文字列と同じ名前のメソッドが定義されていて public な場合は Callable であり、そうでない場合は Callable でないと判定されます。

<?php

class SomeClass
{
    public    static function somePublicClassMethod() {}
    protected static function someProtectedClassMethod() {}
    private   static function somePrivateClassMethod() {}
    public           function somePublicObjectMethod() {}
    protected        function someProtectedObjectMethod() {}
    private          function somePrivateObjectMethod() {}
}

var_dump(is_callable('SomeClass::somePublicClassMethod'));
// => bool(true)
var_dump(is_callable('SomeClass::someProtectedClassMethod'));
// => bool(false)
var_dump(is_callable('SomeClass::somePrivateClassMethod'));
// => bool(false)
var_dump(is_callable('SomeClass::somePublicObjectMethod'));
// => bool(true)
var_dump(is_callable('SomeClass::someProtectedObjectMethod'));
// => bool(false)
var_dump(is_callable('SomeClass::somePrivateObjectMethod'));
// => bool(false)

var_dump(is_callable('AnotherClass::somePublicClassMethod'));
// => bool(false)
var_dump(is_callable('AnotherClass::somePublicObjectMethod'));
// => bool(false)

var_dump(is_callable('SomeClass::anotherPublicClassMethod'));
// => bool(false)
var_dump(is_callable('SomeClass::anotherPublicObjectMethod'));
// => bool(false)

クラスのメソッド内で Callable かどうかを判定する場合、 :: の左側の文字列には追加で self , parent が許可され、 :: の右側の文字列には追加で protected , private なメソッドの名前が許可されます。

<?php

class ParentClass
{
    public static function somePublicClassMethod() {}
    public        function somePublicObjectMethod() {}
}

class SomeClass extends ParentClass
{
    public static function classMethod()
    {
        var_dump(is_callable('SomeClass::somePublicClassMethod'));
        // => bool(true)
        var_dump(is_callable('self::somePublicClassMethod'));
        // => bool(true)
        var_dump(is_callable('parent::somePublicClassMethod'));
        // => bool(true)
        var_dump(is_callable('SomeClass::someProtectedClassMethod'));
        // => bool(true)
        var_dump(is_callable('SomeClass::somePrivateClassMethod'));
        // => bool(true)

        var_dump(is_callable('SomeClass::somePublicObjectMethod'));
        // => bool(true)
        var_dump(is_callable('self::somePublicObjectMethod'));
        // => bool(true)
        var_dump(is_callable('parent::somePublicObjectMethod'));
        // => bool(true)
        var_dump(is_callable('SomeClass::someProtectedObjectMethod'));
        // => bool(true)
        var_dump(is_callable('SomeClass::somePrivateObjectMethod'));
        // => bool(true)
    }

    public    static function somePublicClassMethod() {}
    protected static function someProtectedClassMethod() {}
    private   static function somePrivateClassMethod() {}


    public function objectMethod()
    {
        var_dump(is_callable('SomeClass::somePublicClassMethod'));
        // => bool(true)
        var_dump(is_callable('self::somePublicClassMethod'));
        // => bool(true)
        var_dump(is_callable('parent::somePublicClassMethod'));
        // => bool(true)
        var_dump(is_callable('SomeClass::someProtectedClassMethod'));
        // => bool(true)
        var_dump(is_callable('SomeClass::somePrivateClassMethod'));
        // => bool(true)

        var_dump(is_callable('SomeClass::somePublicObjectMethod'));
        // => bool(true)
        var_dump(is_callable('self::somePublicObjectMethod'));
        // => bool(true)
        var_dump(is_callable('parent::somePublicObjectMethod'));
        // => bool(true)
        var_dump(is_callable('SomeClass::someProtectedObjectMethod'));
        // => bool(true)
        var_dump(is_callable('SomeClass::somePrivateObjectMethod'));
        // => bool(true)
    }
    public    function somePublicObjectMethod() {}
    protected function someProtectedObjectMethod() {}
    private   function somePrivateObjectMethod() {}
}

SomeClass::classMethod();
(new SomeClass())->objectMethod();

Closure オブジェクト

無名関数式を使って作成した Closure オブジェクトは Callable と判定されます。

<?php

var_dump(is_callable(function (): bool { return true; }));
// => bool(true)

__invoke() を実装したオブジェクト

public function __invoke() を実装したオブジェクトは Callable と判定されます。

<?php

var_dump(is_callable(new class() {
    public function __invoke(): bool
    {
        return true;
    }
}));
// => bool(true)

[クラス名, ::を含まない文字列]

※力尽きたので一旦記事は公開する

[クラス名, ::の両側になんかある文字列]

※力尽きたので一旦記事は公開する

[オブジェクト, ::を含まない文字列]

※力尽きたので一旦記事は公開する

[オブジェクト, ::の両側になんかある文字列]

※力尽きたので一旦記事は公開する

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む