読者です 読者をやめる 読者になる 読者になる

nanapi勉強会 vol2 に参加してきました

めも


そうたろう

  • cocoiti さん、目で dis られる
  • シェルをもっと効率的に使って作業しよう
  • 武器を増やそう
    • シェルの超基本
      • C-a とか C-e とか C-w とか使ってカーソル移動を効率的に
    • screen とか tmux とか当然使おう
      • それ上でコピペできるようになっておくとよいよ
    • .zshrc とか
      • いつも煩わしいと思ってた作業が簡単になるやつ!
        • 定着する
      • よさそうだから入れてみよう!
        • たいてい定着しない
    • インクリメンタルサーチ
      • C-r
      • 例えば git pull --rebase origin master と打ちたい場合、
        • pull あたりで C-r して過去のやつ引っ張ってくるとか
    • 同じことの繰り返しをさける!
  • 他人の作業に興味を持とう
    • まわりでシェルさばきの優れた人を見つけて色々聞いてみる

wadap

VOYAGE GROUP PR

  • 無料で セミナールーム社内バー AJITO を貸してます
  • 無料シェア会議室 PORT
  • 懇親会スポンサーもやってます
    • sponsoring ピザ / すし / ビール
  • その代わり PR させてね
  • エンジニア募集中!!!

ゆにこさん

  • 少々黒い画面を嗜むデザイナー
  • どうやって黒い画面とお近づきになれたか
  • きっかけは Git (*Hub ではない)
  • コマンド覚えてよかった
    • 誰に聞いても同じ
    • history に残る
    • エンジニアと会話できる
    • Win から Mac に移動しても問題なし
    • 黒い画面こわくない
  • まとめ
    • デザイナーでも黒い画面つかえると得するよ
    • エンジニアと同じ目線では話せるといいよ

id:rx7 さん

  • hef実践入門
  • History に残ってるコマンド実行数ランキング
    • history | awk '{print $2}' | sort | uniq -c | sort -nr
  • ignoreeof
    • シェルの入力終了を防ぐ
  • errexit
  • xtrace

こにしさん

_人人人人人人_
> ピザ到着 <
 ̄Y^Y^Y^Y^Y ̄

はらへった

@nashibao さん

  • fishシェル
  • suggest が最初からあるよ
  • sjl/z-fish
  • bpinto/oh-my-fish
  • いろいろいれると zsh と同じことができるよ
  • zsh よりいいことないの
    • ウェブの設定画面があるよ
    • 何するの
      • 色とか変えられたりするよ...
      • マージンも変えられるし...
        • CSS でやればいいだろ
_人人人人人人人人人人人_
> CSSでやればいいだろ <
 ̄Y^Y^Y^Y^Y^Y^Y^Y^Y^Y ̄

naoya さん

Composerを使った簡単Travis CI設定

これは PHP Advent Calendar 2013 - Qiita [キータ] の5日目の記事です。

みなさんこんにちは。fivestarことクロコスの小川です。

Composerを使うと簡単に依存ライブラリを管理することが可能です。Composer とはなんぞや、という方は下記の記事あたりに目を通してみてください。

Composerを活用したモダンな開発手法をPHPカンファレンス2013で発表してきた。 #phpcon2013 | Engine Yard Blog JP

Composerでは例えば次のようにcomposer.jsonファイルを書くことで依存ライブラリを指定できます。この例だとFacebookPHP SDKが使えるようになります。

{
    "require": {
        "facebook/php-sdk": "dev-master"
    }
}

Composerとオートロード

Composerを使うポイントの1つに、オートロードが自動設定される点があります。つまり、requireを書いたり、spl_autoload_register()を書いたりすることなくライブラリのクラスが呼び出せるようになる、ということです。Composerを使ってライブラリをインストールするとvendor/autoload.phpというファイルが自動的に作られるので、それを読み込むだけで外部ライブラリのオートロードが有効になります。シンプルですね。

なので、テストの際もphpunit.xmlにvendor/autoload.phpを読み込むように記述しておけば、オートロードが有効になった状態でテスト可能です。

<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="./vendor/autoload.php" colors="true">
  <testsuites>
    <testsuite name="hogeee">
      <directory suffix="Test.php">./Tests</directory>
    </testsuite>
  </testsuites>

  <filter>
    <whitelist>
      <directory>./</directory>
      <exclude>
        <directory>./vendor</directory>
      </exclude>
    </whitelist>
  </filter>
</phpunit>

従来であれば、各ライブラリがオートロードの仕組みを独自で実装していたのですが、Composerがオートロードの仕組みも含めて管理してくれるため、利用者は1ファイル読み込めばよくなり、すごく楽になっています。

require-dev

Composerを使うと、開発時のみに読み込みたいライブラリの指定も可能です。それはcomposer.jsonにて次のように指定します。"require-dev" というのがそれです。

{
    "require": {
        "facebook/php-sdk": "dev-master"
    },
    "require-dev": {
        "phpunit/phpunit": "3.7.*",
        "phake/phake": "2.0.*@dev",
        "piece/stagehand-testrunner": "3.6.*"
    }
}

この例だとPHPUnit、Phake、Stagehand_TestRunnerを開発時のみインストールする、という指定です。このようなテスティングツール系は運用時には基本的に不要なので、require-devに含めておくのがよいです。

なお開発時のみ、という判定はインストール時に--devオプションを指定することで行います。

% php composer.phar install --dev

(追記) --dev がデフォルトでつくようになっていたらしい。今は逆に、require-devを含めたくない場合に--no-devつけろってことでした。 @hidenorigoto @brtriver ご指摘ありがとうございます!

Composer: Installing require-dev by default

Composer: Installing require-dev by default - Jordi Boggiano

参考までに、僕が作っているCrocosSecurityBundle というライブラリは次のようにrequire、require-devを設定しています。

{
    ...
    "require": {
        "php": ">=5.4.0",
        "symfony/framework-bundle": "2.3.*@dev",
        "symfony/http-foundation": "2.3.*@dev",
        "doctrine/common": "2.2.*"
    },
    "require-dev": {
        "symfony/config": "2.3.*@dev",
        "symfony/dependency-injection": "2.3.*@dev",
        "symfony/doctrine-bridge": "2.3.*@dev",
        "symfony/event-dispatcher": "2.3.*@dev",
        "symfony/http-kernel": "2.3.*@dev",
        "doctrine/orm": ">=2.2.3,<2.4-dev",
        "facebook/php-sdk": "dev-master",
        "phake/phake": "2.0.*@dev"
    },
    ...
}

そもそもこのライブラリはSymfonyのバンドルっていう、まあプラグインみたいなもので、基本的にSymfonyに組み込んで使うものなので、Symfonyがあればいいんです。とはいえ開発時にはテストをする必要があります。いちいちSymfonyに組み込んでテストするのも大掛かりで煩わしいので、Symfonyの中で使っているコンポーネントをrequire-devに入れておいて、Symfonyに組み込まなくても自力で依存しているSymfonyコンポーネントをインストールしてテストできるようにしています。

その他にも、Doctrine ORMやFacebook PHP SDKと連携する仕組みも提供していて、これは使いたい人だけ使えよっていう機能なの該当のライブラリはrequireに入れていないのですが、やはりテストは書いておきたいのでrequire-devに指定しています。

あ、ちなみにCrocosSecurityBundleはid:Yudoufuの協力もあってSymfony2.3にようやく対応しました。ゆどうふありがとう。

Travis CI

Travis CIはGitHubのリポジトリをCIするためのサービスで、ご存知の方も多いかと思います。

こういうやつです。
f:id:Fivestar:20131205124618p:plain

サービスフック設定をして、リポジトリに.travis.ymlを入れておくと、自動的にテストをしてくれるやつです。インストール方法はGetting startedをみればわかるっていうか画面をポチポチしてればほとんどやってくれちゃうのでまあやってみればよいです。

f:id:Fivestar:20131206125740p:plain

Travis CIではcomposerがプレインストールされているため、.travis.ymlに次のように書くだけで、自動的にライブラリをインストールしてPHPUnitを実行してくれるようになります。(オートロードはphpunit.xml.distで設定している前提です)

language: php

before_script:
    - composer install --dev

php:
  - 5.4
  - 5.5

Packagist

おまけ。Packagistっていうのは、Composerでインストールできるライブラリのリポジトリです。こいつもGitHubと連携していて、GitHubにあるリポジトリを簡単に登録することができます。せっかくなので、登録方法を簡単に紹介します。

Travis CIは設定を.travis.ymlに書きましたが、Composerはcomposer.jsonにライブラリの説明などを記述します。CrocosSecurityBundleだったら下記みたいに書いています。

{
    "name": "crocos/security-bundle",
    "description": "This bundle provides a way to configure security with annotations",
    "keywords": ["annotations","security","authentication","authorization"],
    "type": "symfony-bundle",
    "homepage": "https://github.com/crocos/CrocosSecurityBundle",
    "license": "MIT",
    "authors": [
        {
            "name": "OGAWA Katsuhiro",
            "email": "ogawa@crocos.co.jp"
        }
    ],
    ...
}

簡単に説明しておくと、下記のような内容を書いておきます。

  • name: パッケージの名称。ベンダー名/ライブラリ名 形式
  • description: 説明
  • keyword: タグを配列で指定
  • type: だいたい "library"
  • homepage: Webサイト。なかったらGitHubのURLでいいと思います


何かいていいかわからなかったら、Composerのリポジトリブラウザで適当に同じようなやつ探してまねればいいと思います。

で、とりあえず書き終わったら次のコマンドでチェック。is validとでれば大丈夫らしいです。

% php composer.phar validate
./composer.json is valid

そこまでできたらGitHubにpushして、あとはPackagistにGitHubのリポジトリを登録します。Packagist内でそこら中にある「Submit Package
Packagist」をおして登録画面にいき、リポジトリのURLを登録します。登録したときのこと忘れたんですが、HTTPSで登録した気がします。 (https://github.com/xxx/xxx.git)

あとはcomposer.jsonを勝手にみてうまいことやってくれます。

https://packagist.org/packages/crocos/security-bundle

で、Travis CIと同様、Packagistもサービスフックを設定することで、pushするたびにPackagistの情報も自動更新されるようになります。登録したGitHubリポジトリのSettingsからService Hooksを開き、Packagistを選んでAPI Tokenの登録をします。API TokenはPackagistのマイページ(右上のユーザ名のリンク)からYour API Tokenのところにあります。

f:id:Fivestar:20131205124707p:plain


さてさて、たいした内容ではありませんでしたが今回はここまで。Composer関連はその辺のPHPライブラリのcomposer.jsonみればいろいろヒントが書いてあるので、いっぱい探してみましょう。

次は @hidenorigoto さんのMVCの記事ですね。楽しみですね。

追記:

実装の問題としてクラスの関係がどうだとか、どことどこに関連があるのが正しい/間違いだとかいうレベルのことではないのです。ソフトウェアがどういう構成になっていればよいのかを抽象的に示したものなのです。

PHPメンターズ -> Beyond MVC

期待通り、すばらしい記事でした。

Twitter Bootstrap を使う際に a:link などに color を設定するとボタンの色まで上書きされちゃう問題の対策

1年ぶりくらいに更新しますが、引き続きクロコスにおりまして (てかこの前の記事が去年の7月なんでその後ヤフーに買収されるなどいろいろあったりしましたが) 、まあまあ元気にやっております。

      • -

さて本題。普段 CSS 書くときは大抵、 Twitter Bootstrap からいくつかの LESS をインポートしつつ、必要に応じてスタイルを上書きする形式をとっています。
そんな中、なんかどうしてもボタン(buttons.less でスタイルをあてているやつ)の文字色が反映されない状況に陥りまして、なんでだろうと調べて一応解決したので書いておきます。

問題の概要

今回のケースでは、デフォルトの文字色を次のように設定していました。

@import "bootstrap/buttons.less";

a, a:link {
  color: #666666;
}
a:visited {
  color: #999999;
}

Bootstrap では .btn クラスをつけるとボタンの形式になり、 .btn-primary のようなボタンに意味を付与するクラスをつけると意味に応じた色がつく、といった仕組みになっています。

/* bootstrap/buttons.less */
.btn {
  ...
}
.btn-primary {
  color: #ffffff;
}

で、例えばこの状態で次のようにHTMLがあるとします。

<p><a href="#">いえーい</a></p>

<p><a href="#" class="btn btn-primary">いえーい</a></p>

実際にこの状態で画面を見てみると次のようになります。

f:id:Fivestar:20131113204105p:plain

.btn-primary を設定しているのに文字色が #ffffff になっていません。

僕は最初、「CSS は要素よりもクラスの方が優先度が高いはずなので .btn-primary が適応されないのはおかしい」と思ってしまったのですが、よくよく調べたら擬似クラスもクラスと同じだけ重み付けされるんで、「要素 + 擬似クラス」と「クラス」の差で a:link などのスタイルが単なるクラスのみの指定である .btn-primary より優先されてしまった、ということでした。

対策

で、最初は .btn に疑似クラスや要素をつけて上書きする方法を考えたのですが、無駄な感じでやりたくないなーと思って別の方法を探した結果、否定疑似クラス (:not()) を使えばもっとも簡単に制御できるという結論にいたりました。

a:not(.btn), a:link:not(.btn) {
  color: #666666;
}
a:visited:not(.btn) {
  color: #999999;
}

このようにしておくと .btn の色に干渉することがなくなるので、デフォルトのボタン色がそのまま使われるようになります。

f:id:Fivestar:20131113205539p:plain

Bootstrap みたいな CSS フレームワークを用いる際、特定のスタイルに干渉してほしくない場合なんかは :not() 知っておくとよさそうです。

Symfony勉強会#6で効率本の紹介などをしてきました

6/30に行われた"日本Symfonyユーザー会"主催のSymfony勉強会に参加&発表してきました。

今回はメインセッションで「効率的なWebアプリケーションの作り方」について話してよいとのことだったので、本を書くに至った経緯などを小一時間お話ししました。それともう1本、Symfonyアーキテクチャについて、主にsymfony 1系のことを知ってる人を対象にお話ししました。以下スライドです。

それと、LTやるときにタイマーうんぬん言ってて、アプリを入れるのも面倒だし、と思ってその場で作りました。ブラウザから見られます。スマホでもたぶん大丈夫です。あと、一応ドラの音がでるんですけど、音源側の音量が少ないのでいいやつがあったらPull Requestください。

LT.Timer

雑感

今回も長丁場でしたが、参加者の皆さんお疲れ様でした。朝から晩まで、ずっと誰かしゃべってるというハードな会でしたけど、充実していて楽しかったです。ただ2回もしゃべるのはとても疲れたので、次は別の方(できればこれまでに発表したことない方!)が登壇してくれるといいなーと思います。

さいごに

スタッフのみなさま、お疲れ様でした。そして、会場提供していただいたVOYAGE GROUPさん、今回もありがとうございました。

「効率的なWebアプリケーションの作り方」を執筆した経緯など

僕は今年でエンジニアとして6年目になるのですが、昔は深く勉強したわけでもないのにMVCオブジェクト指向もわかってる気でいて、デザインパターンや設計原則の話を聞いても「難しいこといってて意味わからないし、Javaだけでやってれば?」なんて思っていた時期がありました。

4年目くらいのとき、当時在籍していたアシアルでPHPスクールでオブジェクト指向編の講師を務めることになったため渋々設計原則やデザインパターンを調べていたところ、目からうろこが落ちることばかりでした。

それまでは、複雑な処理を実装しようとした際にひたすら考えた挙げ句、うまく実装したつもりでメンテナンスが困難なコードになったりしたこともあったのですが、原則やパターンを学んだことで難しい場面でも悩むことも減ったし、コード自体もより素直で扱いやすいようになっていきました。

そういったことがあって、現場の苦労を減らせるよう、現場の開発者に向けて書いた本が「効率的なWebアプリケーションの作り方」です。主に「現場の初心者」の方々がよりスムーズにコードを書けるよう、前述のような原則などの知識から実際にアプリを開発する流れを1冊で解説しています。基礎知識を身につけたい、改めて学習したいという方はぜひ読んでみてください。

効率的なWebアプリケーションの作り方 ~PHPによるモダン開発入門

効率的なWebアプリケーションの作り方 ~PHPによるモダン開発入門

PHP勉強会@東京#58でPhakeの紹介をしました

第58回PHP勉強会@東京 - events.php.gr.jp

久々のPHP勉強会だったのでPhakeについて発表をしてきました。とても久々のPHP勉強会でしたが、懇親会で色々お話もできて楽しかったです。

訂正

Phake::mock()の第2引数以降がうんたら書いてますけど、第2引数以降がコンストラクタの引数になるのはパーシャルモックのときだけでした。


id:sotarokPHP 5.4の話のときにもいってたんですけど、「ゲッターセッター用意するの面倒だからAccessorってトレイトつくったよ!」「おれも!」みたいなことがあったりして、考えることはまったく同じですね。僕が作ってたときのソースさらしておきます。__call()をトレイトで実装しちゃうと、__call()が衝突しちゃうので一応メソッドわけてます。MagicCallMixerトレイトとか作ったけど消しちゃったらしい。

<?php
namespace Fivestar;

trait Accessor
{
    public function __call($method, $args)
    {
        return $this->callMagicAccessor($method, $args);
    }

    public function magicCallAccessor($method, $args)
    {   
        $processMethod = strtolower($method);
        if ('set' === ($verb = substr($processMethod, 0, 3)) 
            || 'get' === ($verb = substr($processMethod, 0, 3)) 
            || 'is' === ($verb = substr($processMethod, 0, 2)) 
        ) { 
            $camelName = lcfirst(substr($method, strlen($verb)));
            $underscoreName = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $camelName));

            $property = null;
            if (property_exists($this, $camelName)) {
                $property = $camelName;
            } elseif (property_exists($this, $underscoreName)) {
                $property = $underscoreName;
            }   

            if (null !== $property) {
                if ('set' === $verb) {
                    $this->{$property} = array_shift($args);

                    return;
                } elseif ('get' === $verb || 'is' === $verb) {
                    return $this->{$property};
                }   
            }   
        }   

        throw new \BadMethodCallException(sprintf('Call to undefined method %s::%s', get_class($this), $method));
    } 
}

最後に、会場を提供していただいたVOYAGE GROUPさん、ありがとうございました。

CrocosSecurityBundleの新リリースについて

crocos/CrocosSecurityBundle · GitHub

CrocosSecurityBundleは認証管理用のバンドルで、Symfony2標準のSecurityBundleが複雑で使いづらかったのでシンプルに管理できるように作成したものです。

最初のリリース後に何回かアップデートを重ねていまして、公開当初よりも機能が増えたりしています。本日バーション1.4をリリースしたので、これまでリリースとあわせて紹介します。

1.2

Comparing 1.0...1.2 · crocos/CrocosSecurityBundle · GitHub

1.1はhotfixで使ったので2回目のリリースは1.2になります。ここでの主な変更は、AuthException例外の追加とリファクタリングバグフィックスになります。AuthExceptionはどこかでスローされると、ログイン画面へ遷移(forward)するようになっています。

<?php

use Crocos\SecurityBundle\Exception\AuthException;

$security = $this->get('crocos_security.context');

if (!$security->isAuthenticated()) {
    throw new AuthException('Authentication required');
}

1.3

Comparing 1.2...1.3 · crocos/CrocosSecurityBundle · GitHub

1.3から、Twigのテンプレート内でSecurityContextオブジェクトが _security 変数として参照できるようになりました。

{% if _security.isAuthenticated %}
  <p>Logged in as {{ _security.user }}</p>
{% endif %}

1.4

Comparing 1.3...1.4 · crocos/CrocosSecurityBundle · GitHub

本日リリースした1.4では、Basic認証のサポート、エンティティでログインしたい人向けのSessionEntityAuthの追加などを行いました。

Basic認証のサポート

SecureConfigアノテーションにbasic属性を指定するだけでBasic認証が行われるようになります。basic属性には"ユーザ名:パスワード"形式の文字列を渡すだけです。

/**
 * @SecureConfig(domain="admin", basic="admin:adminpass")
 */

現時点ではコンテナパラメータなどは使えないので設定は固定になります。"%basic_user%:%basic_pass%"のような指定ができてもよいかなと思いますが、とりあえず要望があるまでは保留です。

SessionEntityAuth

SessionEntityAuthはデフォルトの認証ロジックであるSessionAuthの拡張です。SessionAuthはログイン状態をセッションで管理する仕組みで、具体的にはセッションにログインフラグとユーザ情報を格納しておくだけなのですが、このうちユーザ情報はログイン時に渡された値をそのままセッションに格納しているため、エンティティを渡したときにあまりよろしくないことが起こっていました。そこで作成したのが今回のSessionEntityAuthです。

SessionAuthだと何が悪いかというと、1つはオブジェクトがそのままシリアライズされることと、2つめがデシリアライズした時にエンティティがDoctrineの管理対象にならない点です。これらを回避するため、SessionEntityAuthではIDとクラス名のみをセッションへ入れて、セッションから復元する際にクラス名を元にリポジトリを特定し、IDを元にデータを取得しています。これによりセッションには2つのスカラ値が格納されるだけで済み、常にDoctrineの管理対象になるため、更新などもスムーズに行えるようになります。

SessionEntityAuthを使う場合はauth属性に"session.entity"を指定します。

/**
 * @SecureConfig(auth="session.entity")
 */

またログインユーザを表すエンティティにはgetId()メソッドが実装されている必要があります。また、ID以外にも何らかの状態(削除フラグなど)をチェックしなければならない場合は、エンティティにisEnabled()メソッドを実装して、その中で状態を判別して、ログイン状態を復元させない場合はfalseを返すようにします。


現時点で僕が必要な機能はある程度そろっており、あとは要望があった時か、バグなどがあったときに拡張していこうかと思います。

あと、READMEを英語に翻訳してくれる方募集中です。