ぺちこん2015と餃子、からの大森

ちょっと遅くなりましたが、 PHPカンファレンス2015 - #phpcon2015 に行ってきたのでその記録でも。

道のり

PHPカンファレンスが行われる会場は京急蒲田が最寄り駅になっていて、

地元民でもない自分はPHPカンファレンスで使うくらいしか馴染みのない駅なのですが、

今回その京急蒲田駅が改装中で、会場まで非常にスムーズな動線ができていたので便利でした。

公式にもその動画があった↓ 分かりやすくでいいですね

会場までは京急蒲田駅からだとスムーズです。駅の改札前からPiOへの案内に従ってください。

Posted by phpcon.japan on 2015年10月2日

PHPの今とこれから2015

資料

PHPの今とこれから2015

感想
  • php7は基本的に期待しかないですね
  • 知ってる人にはおさらい的な感じ
  • 変数構文の統一に関しては知らなかったので、ちょっとマイグレーションでハマる場合があるやも

Performance Testing for Modern Apps

資料

Performance Testing Modern Apps // Speaker Deck

感想
  • 英語の壁ドーーーーーーーン
  • 資料見る分にはまだいいが、実際喋ってることはポカーン
  • とはいえ、知らないパフォーマンスツールを知ることができたのがよかった
  • とくに newsapps/beeswithmachineguns · GitHub とか名前のセンスがいいなー

その後早めのお昼休憩

  • 自分はちょっと早めに11:30からお昼休憩
  • 今回、会場内でもオムライスなどのお弁当を販売するなど気が利いていた
    • 昔来た時はどこでご飯食べようかと難儀した記憶もあるのでこの改善は素晴らしいなーと
  • とはいいつつ、せっかく蒲田まで来たので有名な羽付き餃子のお店に行くことにした
ニイハオにて

場所は 你好 別館 (ニイハオ) - 京急蒲田/餃子 [食べログ] ここ

会場からは歩道橋渡ってちょっと歩けばすぐって感じのところ。(目印は角のセブンイレブンかな)

11:30からオープンだったのでその時の店内はまだまだ余裕のある感じ。

休みの日だし、富士山という響きにもつられて、、

富士山ハイボール

f:id:kalibora:20151012130848p:plain

メインはチャーハン

f:id:kalibora:20151012130857p:plain

もちろん餃子(羽根つき)も

f:id:kalibora:20151012130907p:plain

大変満足でした。

基調講演

資料

Speeding up the Web with PHP 7

感想
  • php20周年だって!20年前とか恐ろしい!
  • file-based cache for OPCache これは知らなかった
    • 昨今CLIでも使うことが多いのでこういう改善すばらしい
  • 自虐することが多い言語だと思うけど、もう他の言語をうらやましがる必要のない言語になったよなぁという感想

いまどきのPHP開発現場 -2015年秋-

資料

いまどきのPHP開発現場 -2015年秋-

感想
  • PhpStorm はなんだかんだ試せてない
    • 使ったら素晴らしいだろうことはわかってるけど単に腰が重い
  • あんまり関係ないけど、 Scrutinizer つながりで Scrutinize っていう単語を覚えたよ

How to Build Efficient and Integrated Development Environment for The Team

資料

PHP Conference 2015 / How to Build Efficient and Integrated Development Environment for The Team // Speaker Deck

感想
  • 全体的には開発環境あるある話
  • QA環境のDBを開発環境にインポートするってのはpragmaticでよいなと思った
  • あと、資料になかったかもしれないけど、新人にはメンターをつけてるっていう話が印象に残った
  • 後半のエモい話は、若いころを思い出した
    • その頃はcvscsvじゃないよ)もほとんど使ってない現場で、みんなで使うようにしたりとか

ライトニングトーク

全体をふりかえって

  • 何かの時に、今回はPHPカンファレンス初めての方?っていう質問に大多数の人が手をあげていて、
  • 内輪感だけじゃなくて、新規の人がたくさん来てくれるイベントなんだなって
  • アラ、いいですね〜
  • 運営の方、スポンサーの方、発表者の方、参加された方々
  • とても素敵です
  • ありがとうございました
  • お疲れ様でした

その後、大森にて

f:id:kalibora:20151012134800p:plain

f:id:kalibora:20151012134811p:plain

f:id:kalibora:20151012134820p:plain

php5.3から使える例外チェーンのメモ

<?php
class FooException extends Exception
{
}
class BarException extends Exception
{
}
class BazException extends Exception
{
}
function foo()
{
    throw new FooException('foo error');
}
function bar()
{
    try {
        foo();
    } catch (Exception $e) {
        throw new BarException('bar error', 0, $e);
    }
}
function baz()
{
    try {
        bar();
    } catch (Exception $e) {
        throw new BazException('baz error', 0, $e);
    }
}
// main
try {
    baz();
} catch (Exception $e) {
    echo 'CATCH!', PHP_EOL;
    echo $e;
}
$ php ./exception_test.php
CATCH!
exception 'FooException' with message 'foo error' in /Users/kalibora/src/php/exception_test.php:13
Stack trace:
#0 /Users/kalibora/src/php/exception_test.php(18): foo()
#1 /Users/kalibora/src/php/exception_test.php(26): bar()
#2 /Users/kalibora/src/php/exception_test.php(33): baz()
#3 {main}

Next exception 'BarException' with message 'bar error' in /Users/kalibora/src/php/exception_test.php:20
Stack trace:
#0 /Users/kalibora/src/php/exception_test.php(26): bar()
#1 /Users/kalibora/src/php/exception_test.php(33): baz()
#2 {main}

Next exception 'BazException' with message 'baz error' in /Users/kalibora/src/php/exception_test.php:28
Stack trace:
#0 /Users/kalibora/src/php/exception_test.php(33): baz()
#1 {main}

例外をラップすべきかどうかは考える余地があるとして、
ラップしたい場合には便利。

ajaxの時ってビューロジックをサーバ側に置く?クライアント側?

ざざっとメモ。
例えば Employee というモデルがあり、 salaly プロパティを持っているとする。
DBに保存されてるのかどっかのAPIから取得するのかなどは問わない。

<?php
// こんな感じで社員オブジェクトが取れるとする
$employee = Employee::find($employee_id);
// で給料はこれで取れるとする
echo $employee->salaly, PHP_EOL // 200000


で、まぁテンプレ側で給料を表示する場合は、カンマ区切りで表示したいとする。
テンプレート変数に上記の $employee がアサインされてるとすると、

<html>
<body>
<?php echo number_format($employee->salaly) ?>
</body>
</html>

こんな感じかな。
それでじゃあこの仕様には意味が無いけど、この給料を非同期でajaxを用いて表示したいとする。
ajaxAPIを作ってそれをテンプレートから呼ぶことになると思うけど、
そのajaxAPIの返却値である給料にはカンマを入れるべきだろうか?
めんどくさいのでRESTかつjsonで返すと仮定すると、

GET http://example.com/employee?employee_id=1

こんな風に呼び出たら、

{
    salaly: 200000
}

こう?それとも

{
    salaly: 200,000
}

こう?

前者ならjs側でnumber_format相当のものを実装しないといけないし、
後者ならビューに特化しすぎてるので、そのテンプレートだけに特化したものになりそう。
また前者の場合でかつajaxでないページもあった場合、
そちらはサーバ(php)側で処理するから
ビューロジックはサーバ側にもクライアント側にも置かなくてはいけないので
同じ言語で書いているならいいが、
そうでないならビューロジックの定義が重複してしまう。
といったところで悩んでいたりする今日この頃。

Eテレ感想メモ

Eテレ見てたら面白かったので忘れないようにメモ。

  • めざせ!会社の星「部下も必見!デキる課長の極意」
    • 定期的にコミュニケーションの場を設ける。
      • やっぱり話しかけづらいし、忙しい時は聞くのも大変なので。
      • やるなら朝がいいらしい。これって朝会っぽい。
    • 人に任せる。
      • 細かく砕いて定期的にレビューする。

fizzbuzzでもいろんな書き方がありますね。今の僕ならこう書く

なんとなくネットサーフィンしていたら上記の記事に出会い、
なるほど色んな書き方がある物だなと感じました。
でも個人的にはあまり好きではない書き方だったので
(応用2のFizzBuzzFozzの時にメソッドを呼び分けているのですが
このロジックは抽象化してメソッドにいれたほうが好みなので)
今の自分ならこう書くだろうというのを書いてみました。


※使い慣れないrubyなので慣用表現に誤りがあるかもしれませんが
そこはご了承ください。

#!/usr/bin/ruby                                                                                                                       
puts '【基本】「まず基本的な FizzBuzz 問題を実現するプログラムを書きなさい'                           
class Array                                                                                                                               
  def fizzbuzzify                                                                                                                       
    self.map do |i|                                                                                                                      
      case true                                                                                                                            
      when i % 15 === 0 then                                                                                                    
        'FizzBuzz'                                                                                                                         
      when i % 5 === 0 then                                                                                                      
        'Buzz'                                                                                                                               
      when i % 3 === 0 then                                                                                                      
        'Fizz'                                                                                                                                
      else                                                                                                                                    
        i                                                                                                                                       
      end                                                                                                                                    
    end                                                                                                                                      
  end                                                                                                                                        
end                                                                                                                                          
puts (1..100).to_a.fizzbuzzify                                                                                                   
                                                                                                                                              
puts '【応用1】「同じ処理を 100 まで、200 まで、1000 までの配列にそれぞれ適用しなさい」'    
puts (1..100).to_a.fizzbuzzify                                                                                                   
puts (1..200).to_a.fizzbuzzify                                                                                                   
puts (1..1000).to_a.fizzbuzzify                                                                                                 
                                                                                                                                                
puts '【応用2】「1000 までの場合だけ、30 の倍数の時に "FizzBuzzFozz" にしなさい」'              
class Array                                                                                                                               
  def fizzbuzzfozzify                                                                                                               
    if self.count != 1000 then                                                                                                    
      return self.fizzbuzzify                                                                                                        
    end                                                                                                                                      
    self.map do |i|                                                                                                                      
      case true                                                                                                                            
      when i % 30 === 0 then                                                                                                    
        'FizzBuzzFozz'                                                                                                                  
      when i % 15 === 0 then                                                                                                    
        'FizzBuzz'                                                                                                                         
      when i % 5 === 0 then                                                                                                      
        'Buzz'                                                                                                                               
      when i % 3 === 0 then                                                                                                      
        'Fizz'                                                                                                                                
      else                                                                                                                                    
        i                                                                                                                                       
      end                                                                                                                                    
    end                                                                                                                                      
  end                                                                                                                                        
end                                                                                                                                          
puts (1..100).to_a.fizzbuzzfozzify                                                                                            
puts (1..200).to_a.fizzbuzzfozzify                                                                                            
puts (1..1000).to_a.fizzbuzzfozzify         

puts '【応用3】「1000 までの場合だけ、標準出力でなく、hoge.txt に出力するようにしなさい」'  
class FizzbuzzFozzOutput                                                                                                        
  def initialize(array_or_maxnum)                                                                                             
    case array_or_maxnum                                                                                                         
    when Array then                                                                                                                   
      @array = array_or_maxnum                                                                                               
    when Integer then                                                                                                                
      @array = (1..array_or_maxnum).to_a                                                                                  
    else                                                                                                                                      
      @array = (1..(array_or_maxnum.to_i)).to_a                                                                         
    end                                                                                                                                      
  end                                                                                                                                        
  def execute                                                                                                                            
    if @array.count === 1000 then                                                                                           
      File::open('hoge.txt', 'w') {|f|                                                                                               
        f.puts @array.fizzbuzzfozzify                                                                                           
      }                                                                                                                                         
    else                                                                                                                                      
      puts @array.fizzbuzzfozzify                                                                                               
    end                                                                                                                                      
  end                                                                                                                                        
end                                                                                                                                          
FizzbuzzFozzOutput.new(100).execute                                                                                    
FizzbuzzFozzOutput.new(200).execute                                                                                    
FizzbuzzFozzOutput.new(1000).execute        


まず、基本のFizzBuzzのロジックをオープンクラスで標準のArrayクラスのインスタンスメソッドとして追加します。
(標準のArrayに置くべきか、別のFizzBuzzArray的なクラスを作った方がいいかはちょっとよくわかりません。)
配列をFizzBuzz化する、という意味で Array#fizzbuzzify という名前を付けています。
なんとなく動詞っぽい気がしますが英語が得意でないので実際のところどうかはよく知りません。


応用1ではそれぞれの配列作ってfizzbuzzifyするだけです。


応用2では新たなロジックが出てくるので、それをまたArrayクラスのインスタンスメソッドとして追加します。
今度は Array#fizzbuzzfozzify としました。
1000までの場合という意味を厳密に考えるとめんどくさいので、とりあえず
1000個の要素の配列だった場合にFizzBuzzFozzが出るようにしています。
それ以外の場合は Array#fizzbuzzify に委譲します。
これで呼び出し側ではメソッドを呼び分ける必要はなく、どんな配列でも
Array#fizzbuzzfozzify を呼べばいいようになりました。


続いて応用3ですが、今度は出力先が変わります。
出力するメソッドをどこに置くかですが、Arrayに置くのもどうかと思ったので
新規で FizzbuzzFozzOutput クラスを作り、excecute メソッドで出力先が変わるロジックを吸収することにしました。
あと色気を出して、コンストラクタに配列だけじゃなく数値でも受け取れるようにしています。
いやらしいですね。

ソフトウェア工学的な読み物まとめ

個人的に何度でも読み返したい記事

URLのshbang(#!)ajaxのやつのメモ