waste of time

主にPHP

Laravel5.2.x EloquentORM

これまで2年弱、PHPフレームワークといえばCakePHP2を使っていましたが、ここ2,3ヶ月ほど趣味でも仕事でもLaravel5を触っています。

Cake2.xからLaravel5.xに乗り換えて全然違うなぁと感じたのはDB操作周りです。いわゆるO/Rマッパーの使い勝手が結構違います。

問い合わせの結果はモデルインスタンス

CakePHP3もたぶんそうなってると思いますが、Laravel5は問い合わせの結果がモデルインスタンスとして返ってきます。first()やfind()のように結果が1件の場合はModelインスタンスがそのまま返ってきますが、get()やall()のように結果が複数件の場合はCollectionインスタンスが返ってきます。Collectionインスタンスにはイテレータが実装されており、普通の配列のようにforeachで回すことができます。(Collectionインスタンス複数のModelインスタンスにアクセスできる認識であってますかね?)

// Userモデルに対して制約を加えてモデルインスタンスを得る
$user = User::where('age', 20)
                ->orderBy('created_at', 'desc')
                ->first();

// 結果のフィールドにはプロパティとしてアクセスできる
echo $user->name;

// そのまま更新もできる
$user->name = 'ほげほげ';
$user->save();

クエリビルダと組み合わせての更新など、Modelクラスの実装を見るとだいたい何ができそうか確認できます。

https://laravel.com/api/5.2/Illuminate/Database/Eloquent/Model.html

リレーション/Eagerロード

Laravel5では、Illuminate\Database\Eloquent\Modelを継承したEloquentモデルにリレーションを記述します。 リレーションの定義を行った後であれば、Modelインスタンスから自由にリレーションにアクセスすることができます。

// articles -< comments のようなリレーションを仮定

// IDを指定してモデルインスタンスを得る
$article = Article::find(1);

// Articleモデルインスタンスからcommnetsテーブルのデータにアクセスできる
foreach($article->comments as $comment) {
    echo $comment->body;
}

これを見てEloquentの強力さに驚きました。驚きません?

ところが、上記のようにリレーションをループさせて取得する場合、クエリがループ回数分+1回発行されてしまう罠があります。リレーションのプロパティにアクセスする度にクエリを投げているわけです。 これを回避するため、Eagerロードという仕組みを使います。withメソッドでリレーションを指定すると、IN句で必要なデータを予めロードするようになります。

// articles -< comments のようなリレーションを仮定

// withメソッドでcommentsをEagerローディング
$article = Article::with('comments')->find(1);

// articlesに紐付くcommentsを事前に取得するため、クエリは2回しか発行されない
foreach($article->comments as $comment) {
    echo $comment->body;
}

おわり

もくもく開発してると知見が結構貯まっていくんですが、こうやって文章化すると復習になるし自分の中で整理されていい感じに定着して良いです。

hogeOrFuga()のような特殊なクエリビルダについて、便利で使う場面が多いのでまとめておきたい。 あと最近は認証系のコアトレイト拡張とかがっつりやったりしてるので、認証周りの拡張についてもあとでまとめておきたい。

VagrantにSSHログインしたときにアニメ放送情報を表示させる

f:id:tmysz:20160208020429p:plain

今日放送のアニメなんだっけ?と仕事中に気になることはよくあるはず。
見逃せないアニメの日は残業せず帰りたい。 そんな感じの需要を満たすかもしれないソリューションです。

SSHログインしたときに何か表示する

motd(message of the day)を使えば可能らしい。サーバにログインしたときに、/etc/motdの内容がコンソールに出力される。

アニメ放送情報を取得する

拙作Anitimeを使う。

anitimeをインストールする。

# cd ~/
# git clone https://github.com/tmysz/anitime.git
# cp ./anitime/anitime /usr/local/bin/
# chmod a+x /usr/local/bin/anitime

anitimeコマンドを実行すると記事冒頭画像のようにずらーっと放送情報が出てくるはず。表示する局の設定とかは、ホームディレクトリの.anitime/config.jsonに書けば読み込みます。

SSHログインした時にアニメ放送情報を表示させる

SSHログインしたときに、anitime実行結果をmotdに書き出せば良さそう。とりあえず、anitimeを実行してmotdに書き出すシェルスクリプトを準備する。
今環境のPHP環境がphpenvによるもののため、4行目でrbenvの初期化スクリプト(phpenvはrbenvに依存しているため)を実行しています。yum等で入れたPHPの場合は、anitime実行前にPHPのパスを設定する記述を代わりに入れてください。(yumインストールしたphpは何も書かなくてもこの時点で動く(パス通ってる)っぽい?)

#!/bin/sh

# phpenv init
source /etc/profile.d/rbenv.sh

echo -e "======\n`/usr/local/bin/anitime`\n======\n" > /etc/motd

試行錯誤

/etc/ssh/sshrcでupdate_motd.shを実行させようとした

SSHログイン時に/etc/ssh/sshrcが実行されるようなので、この中でupdate_motd.shを実行させてみた。 結果としては、/etc/ssh/sshrcが実行される前にmotdが出力されてしまうためボツ。

cronでupdate_motd.shを実行させようとした

crontabでは、分・時・日・月・週以外にも、@rebootと指定することでサーバ起動時のタスクを登録することが出来る。 vagrant upしたときにmotdに書き込んでくれれば良いので、/etc/crontabに以下のようにタスクを登録した。

@reboot root /etc/update_motd.sh
10 * * * * root /etc/update_motd.sh

サーバ起動時に加えて毎時10分にmotdを書き換えている。 こっちはうまくいった。

f:id:tmysz:20160208020432p:plain

職場の開発環境に入れれば捗るかもしれない。

vagrant upしたらマウントに失敗する件

virtualboxを再インストールしてvagrant upしたら、以下のようなエラーが出てディレクトリがマウントできない云々となりました。この問題は、GuestAdditionsを再ビルドすることで解決することができます。

> vagrant up
...
==> default: Mounting shared folders...
    default: /vagrant => D:/vm/php7
Failed to mount folders in Linux guest. This is usually because
the "vboxsf" file system is not available. Please verify that
the guest additions are properly installed in the guest and
can work properly. The command attempted was:

mount -t vboxsf -o uid=`id -u vagrant`,gid=`getent group vagrant | cut -d: -f3` vagrant /vagrant
mount -t vboxsf -o uid=`id -u vagrant`,gid=`id -g vagrant` vagrant /vagrant

The error output from the last command was:

/sbin/mount.vboxsf: mounting failed with the error: No such device

GuestAdditionsを再ビルドするには、kernel-develがインストールされている必要があります。 kernel-develがインストールされてない状態でGuestAdditionsの再ビルドを行おうとすると、ビルドに失敗してしまいます。
※以下ゲストマシンです

$ sudo /etc/init.d/vboxadd setup
Removing existing VirtualBox non-DKMS kernel modules       [  OK  ]
Building the VirtualBox Guest Additions kernel modules
The headers for the current running kernel were not found. If the following
module compilation fails then this could be the reason.
The missing package can be probably installed with
yum install kernel-devel-2.6.32-431.3.1.el6.x86_64

Building the main Guest Additions module                   [FAILED]
(Look at /var/log/vboxadd-install.log to find out what went wrong)
Doing non-kernel setup of the Guest Additions              [  OK  ]

kernel-deveが入っていない場合は、まずkernel-develをインストールします。 rpmからじゃなくてもいけるらしいですが、自環境だと元々除外してないっぽいのに出てこなかったので、こちらを参考にしてインストールしました。

$ sudo yum install -y http://bay.uchicago.edu/centos-vault/6.5/updates/x86_64/Packages/kernel-devel-2.6.32-431.3.1.el6.x86_64.rpm

kernel-develがインストール済みの状態でもう一度ビルドします。

$ sudo /etc/init.d/vboxadd setup
Removing existing VirtualBox non-DKMS kernel modules       [  OK  ]
Building the VirtualBox Guest Additions kernel modules
Building the main Guest Additions module                   [  OK  ]
Building the shared folder support module                  [  OK  ]
Building the OpenGL support module                         [  OK  ]
Doing non-kernel setup of the Guest Additions              [  OK  ]
Starting the VirtualBox Guest Additions                    [  OK  ]

追記(2016/1/16):
kernel-develインストール済みの状態でビルドに失敗する場合は、GuestAdditionsが求めているkernel-develのバージョンがより新しいものである可能性があります。上記の手順でkernel-develをインストール済みであれば、$ sudo yum -y upgrade kernel-develでアップデートできるので試してみてください。

ホストに戻ってvagrantを再起動すれば、マウントに成功することが確認できます。 ついでにGuestAdditionsのバージョンをホストとゲストでいい感じに揃えてくれるvagrant-vbguestもインストールしておきます。

> vagrant plugin install vagrant-vbguest
> vagrant reload

以下のコマンドでGuestAdditionsのバージョンを確認してみます。ホスト/ゲスト同じであればrunning --- OKな感じになって万事OKです。

> vagrant vbguest --status
GuestAdditions 5.0.12 running --- OK.

おまけ:
vagrant-vbguestを入れているとvagrant upする度にGuestAdditionsのバージョンチェックが走るので、それを止めたい場合は以下のようにVagrantfileに書けば良い。

config.vbguest.auto_update = false

PHPでSeleniumWebdriverを操作してヘッドレス化したChromeを動かす

ajaxでコンテンツを生成しているページをスクレイピングしようと思ったので、WebDriverを試してみました。本来の用途(E2Eテスト)とは少し違うとは思いますが、使えるものは使う方向で。
gccのビルドとかで長くなったので、ajaxコンテンツを取得するとか本当にやりたかったところまでは書いてません。とりあえず動くところまでです。

いろいろ準備

SeleniumServer(Standalone版)のダウンロード

$ wget http://selenium-release.storage.googleapis.com/2.48/selenium-server-standalone-2.48.2.jar

JDK, Xvfb, Firefoxのインストール

$ sudo yum install -y java-1.8.0-openjdk
$ sudo yum install -y xorg-x11-server-Xvfb firefox

Chromeインストール

ChromeCentOS向けに提供されていない?っぽいのでリチャードさんのスクリプトでインストールする

# wget http://chrome.richardlloyd.org.uk/install_chrome.sh
# chmod u+x install_chrome.sh
# ./install_chrome.sh

ChromeDriverのダウンロード

WebDriverからChromeを操作するためのドライバをダウンロードする

$ wget http://chromedriver.storage.googleapis.com/2.20/chromedriver_linux64.zip
$ unzip chromedriver_linux64.zip

日本語関連のパッケージをインストール

デフォルトだと文字化けしてしまうので。

$ sudo yum -y groupinstall "Japanese Support"

環境変数DISPLAYの設定

$ vi ~/.bash_profile
export DISPLAY=:3

$ source ~/.bash_profile

Xvfb起動

$ Xvfb :3 -screen 0 1024x768x24 &

SeleniumServer起動

$ java -jar selenium-server-standalone-2.48.2.jar

試してみる

ようやく準備が整ったので、実際に動かしてみる。とりあえずページのタイトルを取得させて動くか確認。

<?php
require_once 'vendor/autoload.php';

putenv("webdriver.chrome.driver=/hogehoge/chromedriver");

use Facebook\WebDriver\Remote\DesiredCapabilities;
use Facebook\WebDriver\Remote\RemoteWebDriver;

$host = 'http://localhost:4444/wd/hub';
$driver = RemoteWebDriver::create($host, DesiredCapabilities::chrome(), 5000);

$url = 'https://qiita.com/';
$driver->get($url);
echo $driver->getTitle() . "\n";
/usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.15' not found (required by /hogehoge/chromedriver)

動かない。ChromeDriverが要求してるバージョンGLIBCXX_3.4.15がないらしい。

GLIBCXX_3.4.15入りのlibstdc++.so.6を手に入れる

$ ls -la /usr/lib64/ | grep libstdc
708:lrwxrwxrwx   1 root root       19 2015-10-15 18:31 libstdc++.so.6 -> libstdc++.so.6.0.13
709:-rwxr-xr-x   1 root root   987096 2015-07-23 10:03 libstdc++.so.6.0.13

libstdc++.so.6libstdc++.so.6.0.13シンボリックリンクだったので、中身をみてみる。

$ strings /usr/lib64/libstdc++.so.6.0.13 | grep GLIBCXX
3658:GLIBCXX_3.4
3659:GLIBCXX_3.4.1
3660:GLIBCXX_3.4.2
3661:GLIBCXX_3.4.3
3662:GLIBCXX_3.4.4
3663:GLIBCXX_3.4.5
3664:GLIBCXX_3.4.6
3665:GLIBCXX_3.4.7
3666:GLIBCXX_3.4.8
3667:GLIBCXX_3.4.9
3668:GLIBCXX_3.4.10
3669:GLIBCXX_3.4.11
3670:GLIBCXX_3.4.12
3671:GLIBCXX_3.4.13
8088:GLIBCXX_FORCE_NEW
8151:GLIBCXX_DEBUG_MESSAGE_LENGTH

たしかにGLIBCXX_3.4.15が無い。 新しいgccをビルドすれば入手できるらしいので、現行と同じメジャーバージョンでマイナーバージョンが偶数gccをビルドする。

$ gcc -v
gcc version 4.4.7 20120313 (Red Hat 4.4.7-16) (GCC)

// GMP
$ wget http://ftp.gnu.org/gnu/gmp/gmp-6.1.0.tar.bz2
$ tar jxf gmp-6.1.0.tar.bz2

// MPC
$ wget http://ftp.gnu.org/gnu/mpc/mpc-1.0.3.tar.gz
$ tar zxf mpc-1.0.3.tar.gz

// MPFR
$ wget http://ftp.gnu.org/gnu/mpfr/mpfr-3.1.3.tar.bz2
$ tar jxf mpfr-3.1.3.tar.bz2

// GCC
$ wget http://ftp.tsukuba.wide.ad.jp/software/gcc/releases/gcc-4.8.5/gcc-4.8.5.tar.gz
$ tar zxvf gcc-4.8.5.tar.gz
$ cd gcc-4.8.5
$ ln -s ../gmp-6.1.0 gmp
$ ln -s ../mpc-1.0.3 mpc
$ ln -s ../mpfr-3.1.3 mpfr
$ ./configure --disable-bootstrap --build=x86_64-linux-gnu --disable-multilib
$ make
$ strings x86_64-linux-gnu/libstdc++-v3/src/.libs/libstdc++.so.6.0.19 | grep GLIBCXX
3769:GLIBCXX_3.4
3770:GLIBCXX_3.4.1
3771:GLIBCXX_3.4.2
3772:GLIBCXX_3.4.3
3773:GLIBCXX_3.4.4
3774:GLIBCXX_3.4.5
3775:GLIBCXX_3.4.6
3776:GLIBCXX_3.4.7
3777:GLIBCXX_3.4.8
3778:GLIBCXX_3.4.9
3779:GLIBCXX_3.4.10
3780:GLIBCXX_3.4.11
3781:GLIBCXX_3.4.12
3782:GLIBCXX_3.4.13
3783:GLIBCXX_3.4.14
3784:GLIBCXX_3.4.15
3785:GLIBCXX_3.4.16
3786:GLIBCXX_3.4.17
3787:GLIBCXX_3.4.18
3788:GLIBCXX_3.4.19
8176:GLIBCXX_FORCE_NEW
8396:GLIBCXX_DEBUG_MESSAGE_LENGTH

GLIBCXX_3.4.19を含むlibstdc++.soができたので、シンボリックリンクを置き換える。

$ sudo cp -a gcc-4.8.5/x86_64-linux-gnu/libstdc++-v3/src/.libs/libstdc++.so.6.0.19 /usr/lib64/

# cd /usr/lib64/
# mv libstdc++.so.6 libstdc++.so.6.bak
# ln -s libstdc++.so.6.0.19 libstdc++.so.6
# strings /usr/lib64/libstdc++.so.6 | grep GLIBCXX
3769:GLIBCXX_3.4
3770:GLIBCXX_3.4.1
3771:GLIBCXX_3.4.2
3772:GLIBCXX_3.4.3
3773:GLIBCXX_3.4.4
3774:GLIBCXX_3.4.5
3775:GLIBCXX_3.4.6
3776:GLIBCXX_3.4.7
3777:GLIBCXX_3.4.8
3778:GLIBCXX_3.4.9
3779:GLIBCXX_3.4.10
3780:GLIBCXX_3.4.11
3781:GLIBCXX_3.4.12
3782:GLIBCXX_3.4.13
3783:GLIBCXX_3.4.14
3784:GLIBCXX_3.4.15
3785:GLIBCXX_3.4.16
3786:GLIBCXX_3.4.17
3787:GLIBCXX_3.4.18
3788:GLIBCXX_3.4.19
8176:GLIBCXX_FORCE_NEW
8396:GLIBCXX_DEBUG_MESSAGE_LENGTH

もう一度試してみる

XvfbとSeleniumServerを立ち上げて、上の方で作ったphpスクリプトを再度動かしてみる。

$ Xvfb :3 -screen 0 1024x768x24 &
$ java -jar selenium-server-standalone-2.48.2.jar &
$ php webdriver.php
Qiita - プログラマの技術情報共有サービス

とれましたー。

参考:

[落書きメモ] よく使う(?)gitコマンド

(たまに|よく)使うけど忘れそうなコマンドの自分用メモ。

git config

gitconfig置き場は3種類あって、system, global, localの順に呼ばれて上書きされるっぽい

現在の設定を確認
git config (--system|--global|--local) -l

設定例
git config (--system|--global|--local) user.name "user_name"
git config (--system|--global|--local) user.email "user_email"

リポジトリ

リポジトリの確認
git remote -v

リモートの設定
git remote add origin [repo URL]

コミット

直前コミットの上書き
git commit --amend

直前コミットの上書き(コミットメッセージそのまま)
git commit --amend --no-edit

diff

差分ファイルの一覧
git diff [target] --name-only

GUIツール
git difftool -y [diff_target]

ブランチ

ローカルブランチを作る(-tオプションで追跡ブランチを指定できる)
git checkout -b [new_branch] -t origin/[track_branch]

branchコマンドでも可
git branch [branch_name] origin/[track_branch]

(developブランチを基点とした)フィーチャーブランチの作成
git checkout -b feature/[new_feature_branch] develop

既存のローカルブランチに追跡ブランチを設定する(設定したいローカルブランチにいる状態で)
git branch -u origin/[track_branch]

プッシュ時に設定することもできる
git push -u origin [track_branch]

ローカルブランチ、ローカルブランチに紐付いてる追跡ブランチ、リモート追跡ブランチを確認
git branch -a -vv

削除済みリモートブランチの追跡ブランチの削除(-nオプションつけると、削除は行わず確認だけできる)
git remote prune origin
git (fetch|pull) --pruneでもOK

ローカルブランチの削除
git branch -d [branch_name]

リモートブランチの削除
git push --delete origin [branch_name]

変更の一時退避

変更内容を一時退避(コメントを省略する場合はgit stashだけでOK)
git stash save "comment"

stashの一覧
git stash list

stashの復元(popするとstashリストから消える)
git stash pop 'stash'

変更取消

workingの変更取り消し
git checkout -- [file_name]
git checkout -- .

stageに上げた変更をworkingに戻す
git reset HEAD [file_name]
git reset HEAD .

元に戻す系のコマンドはあまり使ったこと無いので、git reset (--hard) HEAD^とかgit reflogとかの使い方はまだ詳しくは知らない。

svn export的なやつ

デフォルトではtarでアーカイブされるようなので、windowsではzip指定すると良い
git archive --format=zip branch_name -o export.zip

~/.gitconfig

コマンドじゃないけど。至って普通な感じだと思う。

[user]
    name = hoge
    email = fuga@piyo
[core]
    editor = subl --wait
    quotepath = off
[color]
    ui = auto
[push]
    default = simple
[diff]
    tool = WinMerge
    guitool = WinMerge
[difftool "WinMerge"]
    path = 'C:/Program Files/WinMerge/WinMergeU.exe'
    cmd = \"C:/Program Files/WinMerge/WinMergeU.exe\" -e -ub -dl \"Base\" -dr \"Mine\" \"$LOCAL\" \"$REMOTE\"
[merge]
    tool = P4Merge
[mergetool "P4Merge"]
    path = "C:/Program Files/Perforce/p4merge.exe"
    cmd = \"C:/Program Files/Perforce/p4merge.exe\" \"$BASE\" \"$LOCAL\" \"$REMOTE\" \"$MERGED\"
    keepTemporaries = false
[credential]
    helper = wincred
[alias]
    s = status
    b = branch
    l = log --graph --oneline --decorate
    ch = checkout
    cm = commit

今年の3月くらいから業務でgitを使うようになり、ようやく小慣れてきたかなーといった感じです。 はじめた当初はSourceTreeを使っていましたが、最近はGitBash on cmderでコマンドガチャガチャ叩いて格好つけたりしています。

PHPでRedis

Redisインストール

CentOSへのRedisインストールメモ
上記記事を参考にRedisをインストール。なお、記事ではredis-2.8.12.tar.gzをwgetしていますが、最新版を使いたかったのでredis-stable.tar.gzをwgetしました。

$ cd ~/
$ wget http://download.redis.io/releases/redis-stable.tar.gz
$ tar xzf redis-stable.tar.gz
$ cd redis-stable
$ make
$ sudo make install

それ以外は記事と同じ。

$ redis-server -v
Redis server v=3.0.4 ...

PhpRedisインストール

phpredis/phpredisを参考に。

$ cd ~/
$ git clone https://github.com/phpredis/phpredis.git
$ cd phpredis
$ phpize
$ ./configure
$ make
$ sudo make install
Installing shared extensions: /usr/local/phpenv/versions/5.6.11/lib/php/extensions/no-debug-non-zts-20131226/

extensionを有効にする。
phpenvを使っていて、php.iniの場所がよくわからなかったのでphp -iで調べて、conf.dの中にiniファイルを作る。

$ php -i | grep php.ini
9:Configuration File (php.ini) Path => /usr/local/phpenv/versions/5.6.11/etc
10:Loaded Configuration File => /usr/local/phpenv/versions/5.6.11/etc/php.ini

$ sudo vi /usr/local/phpenv/versions/5.6.11/etc/conf.d/phpredis.ini
extension=redis.so

$ sudo service httpd restart

動作確認

$ vi redistest.php
<?php
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);

$redis->set('name', 'tomozo');
echo $redis->get('name');

積極的に使っていきたい。

PHPカンファレンス2015参加してきた

f:id:tmysz:20151003122317j:plain

PHPカンファレンスに参加してきました。

年々参加者も増えており(参加費無料がでかい)、なんと今年は全館貸切だそうです。勢いを感じますね。
以下、聞いた発表について適当にまとめた感想入り混じりメモ。

PHPの今とこれから2015

みんなの使ってるバージョン

使用しているPHPバージョンごとに会場で挙手を求められる場面があった。自分も含め未だにPHP5.3以下を使っているユーザが多い。(弊社の新しいプロジェクトでは5.6使ってます)
世界的にみてもサポート切れバージョンの使用率が高いらしく、PHP界隈は闇が深い。

PHP7.0について

正式リリースは2015/11/12。(ついに来月!)
以下、主な注目点。

  • メインはやはり高速化
  • Null合体演算子
  • スカラー型宣言、戻り型宣言
  • 致命的エラーが例外補足可能に

eregやmysql等一部エクステンションの削除など上記以外にもいろいろ変わっている。
高速化については、前々からPHP7.0RCとHack/HHVMのベンチ比較が各方面でアツく語られていたのでかなり期待できるレベルなのではと感じていました。Hack/HHVMとの高速化競争でお互い影響を与え合っていて素晴らしいと思います。
Null合体演算子はたぶんみんなが待ち望んでいたものだと思います。PHP7を使える環境なら積極的に使っていこう。

今どきのSQLインジェクションの話総まとめ

徳丸さんによるありがたいお話。
日本のSQLインジェクション判例として紹介されたのが、「SQLインジェクションの対策漏れによる責任は開発会社にある」というものです。
CMSのECcubeをカスタマイズした箇所に脆弱性があったようですが、ECcubeのコア部分に脆弱性があって問題が起きた時の責任の所在はどうも曖昧なようです。 自分(会社)の身を守るためには、CMSフレームワークのパッチが出てきたらすぐに適用しなければなりません。

SQLインジェクション、どう対策すれば良いのか?という話ですが、PDOでプレースホルダを使えばほぼ大丈夫とのことです。 普段フレームワークのORMを使ってSQLを組み立てていれば、内部でプレースホルダを使っているはずです。
order byにも式を指定できるので、素のPHPで書く場合は注意しよう。

デモで、脆弱性のあったDrupal1.xの管理者権限を実際に奪取するなど、今以上にセキュリティを意識するきっかけになりました。

Electronからクロスプラットフォームアプリケーションの歴史を考える

Electronに至るまでのクロスプラットフォームアプリの歴史↓

OSがまだ無い時代
ハードが変わればソフトも全部書き直し

救世主Java
ハードやOSに依存しないバイトコードを作成。仮想マシン上で動作。
しかしJava…もっとライトに書きたい…

Web技術の採用
RIA流行り始める。Adobe AirとかMicrosoftSilverlight
ランタイムのインストールが必要だし、Flashジョブズが嫌ったし、Silverlightに至ってはMicrosoftすら使ってない…

ブラウザアプリ
Chromeアプリなど。ウェブアプリケーションがオフラインでも利用できる。
Chromeインストールしないといけない…

Electron
UIはHTML/CSSで、動きはJSで書ける。
クロスプラットフォームのWebブラウザをランタイムとして同梱 Node.jsの機能を利用できる。npmパッケージは19万以上!なので、たいていの機能は誰かが既に書いたものを流用して実現できる。
PHPのエキスパートはつまりJSのエキスパートなので(?)今すぐElectronでデスクトップアプリを開発できる!

と良いことだらけのElectronだが、欠点もある。
chromium同梱になるのでバイナリサイズが大きめだったり、動作が重めだったり。

大掛かりなものももちろん作れるが、俺々ツールやちょっとした社内ツールに最適なので試す価値は大いにあると感じた。

徳丸先生に怒られない、動的SQLの安全な組み立て方

文字列連結でSQL組み立て駄目 → SQLを文字列で指定できてしまうのが駄目という話。
「本質的には、ライブラリやAPIのインターフェースに欠陥があるのであり、間違いを誘発するものを使い続ける限り、SQLインジェクションはなくならない」という主張。
では具体的にどうするのかということについては、以下の2点をあげていた。

SQLテンプレートもSQL構文木も初めて知りました。

SQLテンプレートは、HTMLテンプレートのSQL版みたいなもののようです。SQLテンプレートを使うことによって、文字列連結不可&エスケープとプレースホルダ強制という恩恵に預かれます。
※発表者によるコンセプト実装 SQLTempl8

SQL構文木は、しっかりとは理解できませんでしたが、木構造に当てはめてからSQLを生成する(=文字列連結したSQLを直接パースしない)のでSQLインジェクションが防げる…ということかなと。 悪意ある文字列が与えられても、SQL木構造に影響はないため安全。

DMMのハイパー メディアオタサーの姫 arimoが語る Phalcon

C言語エクステンションで動いてるフルスタックフレームワークのPhalconをプロジェクトで採用した話。
エクステンションについては、バージョン1.xのときは生Clangで書かれていたが、2.xではPHPライクに書けるZephirで書いてClangにビルドしているので、PHPerにも優しい。
特筆すべきはやはりかなり速いということ。phalcon+enginxで運用している。 DIコンテナが便利。アプリ全体から使う機能をDIコンテナに入れておく。

Phalconの闇

  • 情報が少ない。何かあったときの調査に時間かかる。
  • ドキュメント英語ばっかり。公式も中途半端に日本語化
  • ORM。簡単なのはできるけど、サブクエリは生成できない。必要ならPDOで組み立てる。
  • メール。メール送信用のパッケージがない。結局mb_send_mailで送った。
  • configのマージ。環境ごとにconfig切り替える機能がない。ENVで手動で切り替えた。

なお、テンプレートエンジンにはVoltを使用。API開発のためViewは作らない予定だったが、メールのためだけにViewディレクトリ作らざるを得なかったとのこと。

脆弱性もバグ、だからテストしよう!

セキュリティテストツールの紹介・宣伝。

セキュリティテストの分類

CIにセキュリティテストを組み込む。
コーディング→単体テスト結合テスト→セキュリティテスト→リリース

セキュリティテストツールとしてはOWASP ZAP、VAddyがある。(VAddyは自社サービス宣伝)

VAddyデモ。 ブラウザに専用プロキシを刺して、検査対象のアプリをシナリオに沿って操作すると、情報を自動でクロールする。クロールした情報をもとにセキュリティテストを自動で行う。

VAddyはJenkinsプラグインがあるようなので、手軽に連携できそう。ちなみに無料(フリーミアム)

LT

ランダムデータをPHPで作る

開発時、DBにいれるダミーデータの生成。
generatedata.comが便利。ライブラリだとfakerが有名らしい。
fakerインスパイアのfabricate作ってるからみんなPR送ってという話。

PHPRubyのゲームを攻略する PHPWarrior

熟練のPHPerはRubyで作られたゲームをPHPで全部再実装してPHPで攻略する。
いつだったかの東京PHP勉強会と同じ内容かと思いきや、最終面が進化していた。

良心的にまじめに開発するための心構え

クラスに名前と役割以上のものをもたせない。太らせない、分割しよう。

PHPでDIをする

依存クラスについて中からアクセスするのではなく、コンストラクタで渡してやる(呼び出すときに引数で渡す)?

phpと夫婦生活

パーフェクトPHP改訂版2016年内発売予定 テスト、エクステンションの章追加!