2014-10-27 GMOリサーチ寺田渉 
Facebook: 寺田渉Twitter: @wa_terada
ボードゲーム翻訳 
CakePHP Cookbook翻訳 
TED 字幕翻訳 
開発(PHP/JavaScript/Java/Perl)
公式ホームページがある。 
判らなかったら、まずはここを調べよう。 
http://jp1.php.net/manual/ja/
今日は、PHPの仕様で 
初心者がハマりやすいポイントや 
知ってると便利な関数を紹介します。
文法編
==
<?php 
$input = "1abc"; 
if ($input == 1) { echo "NG!!!!"; } 
これはNG!!!! が出力される。 
なぜ?
<?php 
$input = "1abc"; 
if ($input == 1) { echo "NG!!!!"; } 
キャストされるから。 
さけるには=== を使う。 
左右のどちらかが文字列でない場合、 
== は危険。
empty()
empty(変数) 
変数が 
null , false , 0 , 0.0 , '' , [] , 未定義 
ならtrue になる。 
他にもあるが何?
$var = '0'; 
empty($var); //←これはtrue 
文字列の'0' が空だと 
判定されることを忘れないこと。
配列の+
配列の+ とarray_merge は何が違う? 
<?php 
$a1 = [ 'a' => 1, 'b' => 2, 3 ]; 
$a2 = [ 'b' => 4, 'c' => 5, 6 ]; 
var_export($a1 + $a2); 
var_export(array_merge($a1, $a2)); 
この結果は違う?
【+の場合】 
array ( 
'a' => 1, 
'b' => 2, //先勝ち 
0 => 3, 
'c' => 5, 
//先勝ちで6無し 
) 
→ key/index どちら 
でも常に先勝ち 
【array_merge の場合】 
array ( 
'a' => 1, 
'b' => 4, //後勝ち 
0 => 3, 
'c' => 5, 
1 => 6, //勝手に連番 
) 
→ key なら後勝ち 
index なら連番 
$a1 = [ 'a' => 1, 'b' => 2, 3 ]; 
$a2 = [ 'b' => 4, 'c' => 5, 6 ];
では、これはどうなるでしょう? 
<?php 
$a1 = [1,2,3]; 
$a2 = [4,5,6]; 
var_export($a1 + $a2); 
var_export(array_merge($a1, $a2));
【+の場合】 
array ( 
0 => 1, 
1 => 2, 
2 => 3, 
) 
【array_merge の場合】 
array( 
0 => 1, 
1 => 2, 
2 => 3, 
3 => 4, 
4 => 5, 
5 => 6, 
$a1 = [1,2,3]; 
$a2 = [4,5,6]; 
※おそらく混乱するので 
) 
配列の+ は使わない方が良い。
関数編
文字列分割 
いろいろ
<?php 
$str = "aaa<br/>bbb<br/>ccc"; 
$res = 【なんでしょう】;
<?php 
$str = "aaa<br/>bbb<br/>ccc"; 
$res = explode("<br/>", $str); 
var_export($res); 
array ( 
0 => 'aaa', 
1 => 'bbb', 
2 => 'ccc', 
)
<?php 
$str = "aaa<br/>bbb<br>ccc"; 
$res = 【なんでしょう】;
<?php 
$str = "aaa<br/>bbb<br>ccc"; 
$res = preg_split('/<br¥/?>/', $str); 
var_export($res); 
array ( 
0 => 'aaa', 
1 => 'bbb', 
2 => 'ccc', 
)
<?php 
$str = "aaa<br/>bbb<br>ccc"; 
$res = 【なんでしょう】;
<?php 
$str = "aaa<br/>bbb<br>ccc"; 
$res = preg_split('/(<br¥/?>)/', $str, 
null, PREG_SPLIT_DELIM_CAPTURE); 
var_export($res); 
array ( 
0 => 'aaa', 
1 => '<br/>', 
2 => 'bbb', 
3 => '<br>', 
4 => 'ccc', 
)
<?php 
$str = "aaa<br/>bbb<br>ccc"; 
$res = 【なんでしょう】;
<?php 
$str = "aaa<br/>bbb<br>ccc"; 
$res = str_split($str, 5); 
var_export($res); 
array ( 
0 => 'aaa<b', 
1 => 'r/>bb', 
2 => 'b<br>', 
3 => 'ccc', 
)
<?php 
$str = 'aaa,"b,b,b","c""c""c"'; 
$res = 【なんでしょう】;
<?php 
$str = 'aaa,"b,b,b","c""c""c"'; 
$res = str_getcsv($str, ',', '"'); 
var_export($res); 
array ( 
0 => 'aaa', 
1 => 'b,b,b', 
2 => 'c"c"c', 
)
文字列キャプチャ 
いろいろ
2014-10-27 19:00,ERROR:あいうえお 
ここから、 
年月日、 
時分、 
ERRORの文字列、 
メッセージ 
を抜き出したい!
<?php 
$str = "2014-10-27 19:00,ERROR:あいうえお"; 
$res = sscanf($str, '%10s %5s,%5s:%s'); 
var_export($res); 
だが、"ERROR" 部分が可変長だと発覚!! 
どうする? 
array ( 
0 => '2014-10-27', 
1 => '19:00', 
2 => 'ERROR', 
3 => 'あいうえお', 
)
<?php 
$str = "2014-10-27 19:00,ERROR:あいうえお"; 
preg_match('/^(.+?) (.+?),(w+):(.*)$/', 
$str, $res); 
var_export($res); 
array ( 
0 => '2014-10-27', 
1 => '19:00', 
2 => 'ERROR', 
3 => 'あいうえお', 
) 
これ、結果を連想配列で取れる?
<?php 
$str = "2014-10-27 19:00,ERROR:あいうえお"; 
preg_match('/^(?<ymd>.+?) (?<hm>.+?),' 
. '(?<type>w+):(?<msg>.*)$/', $str, $res); 
var_export($res); 
array ( 
0 => '2014-10-27 19:00,ERROR:あいうえお', 
'ymd' => '2014-10-27', 
1 => '2014-10-27', 
'hm' => '19:00', 
2 => '19:00', 
'type' => 'ERROR', 
3 => 'ERROR', 
'msg' => 'あいうえお', 
4 => 'あいうえお', 
)
配列関数 
いろいろ
<?php 
$ary = [1,2,3,4,5]; 
$res = 【なんでしょう】;
<?php 
$ary = [1,2,3,4,5]; 
$res = array_chunk($ary, 2); 
//$res: [[1,2],[3,4],[5]]
array_map 
指定した配列の要素に 
コールバック関数を適用する 
http://jp1.php.net/manual/ja/function.array-map.php 
array_walk 
配列の全ての要素に 
ユーザー定義の関数を適用する 
http://jp1.php.net/manual/ja/function.array-walk.php 
答えはドキュメントの中! 
ヒント:引数と戻り値
array_map 
array array_map ( callable $callback , array $array1 [, array $... bool array_walk ( array &$array , callable $callback [, mixed $userdata 
array_walk 
そう! 
array_map は変更後の配列を作るためのもの 
array_walk は自身を書き換えるためのもの
よく使う 
便利な配列関数 
を2つ紹介
0,5,10,...という具合に 
10000まで5つ刻みの数列がほしい!
0,5,10,...という具合に 
10000まで5つ刻みの数列がほしい! 
range(0, 10000, 5)
$id = $array[0]; 
$name = $array[1]; 
これを下記のように書ける? 
($id, $name) = $array;
$id = $array[0]; 
$name = $array[1]; 
これを下記のように書けます! 
list($id, $name) = $ary;
SPL編 
Standard PHP Library (SPL) 
(標準で入っているライブラリ) 
http://jp1.php.net/manual/ja/book.spl.php
LogicException 
throwされたらバグだという場合の例外。 
つまり、これをキャッチするプログラムは不要だし、 
運用中には絶対throwされないようにすべき。 
バグを発見しやすくするために仕込む例外はコレ。 
if ($data == null) { 
throw new LogicException( 
"dataがnullの場合はこの関数使えません"); 
}
イテレータ 
普通なら、ループの中に色々な制御を 
入れていくことになるが、 
イテレータではループの外で 
条件などを定義可能。
SplFileObject 
ファイルの1行ずつをイテレータとして扱える。 
(メモリから消えると勝手にfclose するのも地味に便利) 
<?php 
$file = new SplFileObject($path); 
$file->setFlags(SplFileObject::READ_CSV); 
foreach ($file as $line) { 
echo $line[0]; 
}
AppendIterator 
イテレータ複数を1つのイテレータとして扱える。 
サイズが大きくてarray_merge では心配なとき良い。 
$ite = new AppendIterator(); 
$ite->append(new ArrayIterator([1,2,3])); 
$ite->append(new ArrayIterator([5,6,7])); 
foreach ($ite as $a) { 
echo $a; 
} 
//result: 123567
LimitIterator 
イテレータのループ範囲を限定する。上位100件とか。 
$ite = new ArrayIterator([1,2,3,4,5,6,7]); 
$ite = new LimitIterator($ite, 2, 4); 
foreach ($ite as $a) { 
echo $a; 
} 
//3456
CallbackFilterIterator 
イテレータにフィルタを適用する。 
$ite = new ArrayIterator([1,2,3,4,5,6,7]); 
$ite = new CallbackFilterIterator($ite, 
function($current, $key, $iterator) { 
return $current % 2 == 0; 
} 
); 
foreach ($ite as $a) { 
echo $a; 
} 
//246
PHPの公式ホームページは 
かなり充実しています。宝の山です。 
特に文法、配列、文字列、SPL まわり 
は一度ざっと読んでおくと良いでしょう。 
判らなかったら公式ホームページ 
を見てみましょう!
GMOリサーチ 
(10月21日上場しました!) 
現在、一緒に働ける仲間(社員)を 
募集しています!!
- GitHub / Git (git-flow) 
- PHPStorm 
- CakePHP 
- ユニットテスト/ Behat 
- 継続的インテグレーション 
- 将来は英語話せるようにサポート
- 無料のカフェ 
- お昼寝スペース(利用推奨) 
- 託児所 
- マッサージルーム
ぜひFacebook 等で 
寺田渉まで 
ご連絡ください!!
ご清聴ありがとうございました!

知ってるようで意外と知らないPHPの便利関数