SlideShare a Scribd company logo
2014/06/28 shin1x1
PHPカンファレンス関西2014
PHPコードではなく
PHPコードの「書き方」を知る
魚を与えれば、
その日をしのぐことはできる。
!
魚の釣り方を教えれば、
一生食べていくことができる。
PHPコードを知れば、
その場をしのぐことはできる。
!
PHPコードの書き方を知れば、
一生食べていくことができる。
PHPコードを知れば、
その場をしのぐことはできる。
!
PHPコードの書き方を知れば、
5年?食べていくことができる。
PHPコードの書き方を知ろう
PHPコードの書き方を知ろう
その前に!
$ php -v!
• 黒い画面で使うPHP
• PHP コマンド打つだけ( php ) で動く
• 余計なものが無いので、PHP言語を学ぶには良い
• 今後、検証にも使うので、実行できる環境を用意
(c) 2014 Masashi Shinbara @shin1x1
コマンドライン版PHP
(c) 2014 Masashi Shinbara @shin1x1
コマンドライン版PHP
!
$ php file.php!
• PHPファイル実行
!
$ php -r 'echo "Hellon";'!
• PHPスクリプト実行
• 最近の OSX には、PHP が標準添付
• OSX 10.9 = PHP 5.4.24
• ターミナルから実行
(c) 2014 Masashi Shinbara @shin1x1
Mac
!
$ /usr/bin/php -v
!
PHP 5.4.24 (cli) (built: Jan 19 2014 21:32:15)
Copyright (c) 1997-2013 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2013 Zend Technologies
• windows.php.net からダウンロード
• Zip ファイルを展開する
• コマンドプロンプトで実行
(c) 2014 Masashi Shinbara @shin1x1
Windows
(c) 2014 Masashi Shinbara @shin1x1
今日のコード
http://bit.ly/phpkansai2014_B4
Are you
readey?
FizzBuzzに見る
PHPコードの書き方
(c) 2014 Masashi Shinbara @shin1x1
FizzBuzz とは
1から20までの整数を出力します。!
!
ただし、3で割り切れる場合は「Fizz」、5で割り切
れる場合は「Buzz」、3でも5でも割り切れる場合は
「FizzBuzz」を出力します。!
!
各項目を出力する際は改行コードを入れて下さい。
<?php!
for ($i = 1; $i <= 20; $i++) {!
if ($i % 3 === 0 && $i % 5 === 0) {!
echo 'FizzBuzz' . PHP_EOL;!
} else if ($i % 3 === 0) {!
echo 'Fizz' . PHP_EOL;!
} else if ($i % 5 === 0) {!
echo 'Buzz' . PHP_EOL;!
} else {!
echo $i . PHP_EOL;!
}!
}
Sample1
$ php fizzbuzz.php!
1!
2!
Fizz!
4!
Buzz!
Fizz!
7!
8!
Fizz!
Buzz!
11!
Fizz!
13!
14!
FizzBuzz!
16!
17!
Fizz!
19!
Buzz!
(c) 2014 Masashi Shinbara @shin1x1
問題を分解してみる
1から20
(c) 2014 Masashi Shinbara @shin1x1
問題を分解してみる
1から20
FizzBuzz
処理
(c) 2014 Masashi Shinbara @shin1x1
問題を分解してみる
1から20
FizzBuzz
処理
1
2
Fizz
…
(c) 2014 Masashi Shinbara @shin1x1
問題を分解してみる
1から20
FizzBuzz
処理
1
2
Fizz
…
入力 出力処理
(c) 2014 Masashi Shinbara @shin1x1
入力・処理・出力が混在
<?php!
for ($i = 1; $i <= 20; $i++) {!
if ($i % 3 === 0 && $i % 5 === 0) {!
echo 'FizzBuzz' . PHP_EOL;!
} else if ($i % 3 === 0) {!
echo 'Fizz' . PHP_EOL;!
} else if ($i % 5 === 0) {!
echo 'Buzz' . PHP_EOL;!
} else {!
echo $i . PHP_EOL;!
}!
}
(c) 2014 Masashi Shinbara @shin1x1
関数にする
• 処理 = evaluate()

FizzBuzz を返す
• 出力 = render()

改行付きで出力
<?php!
function evaluate($i) {!
if ($i % 3 === 0 && $i % 5 === 0) {!
return 'FizzBuzz';!
} else if ($i % 3 === 0) {!
return 'Fizz';!
} else if ($i % 5 === 0) {!
return 'Buzz';!
} else {!
return $i;!
}!
}!
!
function render($output) {!
echo $output . PHP_EOL;!
}!
!
for ($i = 1; $i <= 20; $i++) {!
$fizzbuzz = evaluate($i);!
render($fizzbuzz);!
}!
Sample2
<?php!
function evaluate($i) {!
if ($i % 3 === 0 && $i % 5 === 0) {!
return 'FizzBuzz';!
} else if ($i % 3 === 0) {!
return 'Fizz';!
} else if ($i % 5 === 0) {!
return 'Buzz';!
} else {!
return $i;!
}!
}!
!
function render($output) {!
echo $output . PHP_EOL;!
}!
!
for ($i = 1; $i <= 20; $i++) {!
$fizzbuzz = evaluate($i);!
render($fizzbuzz);!
}!
(c) 2014 Masashi Shinbara @shin1x1
自動テストで検証
• 目で行うチェックは間違う
• プログラムでプログラムをチェック
• 正確無比(残酷なまでに)
• 何度でも実行できる
$ php fizzbuzz.php!
1!
2!
Fizz!
4!
Buzz!
Fizz!
7!
8!
Fizz!
Buzz!
11!
Fizz!
13!
14!
Fizz!
16!
17!
Fizz!
19!
Buzz!
$ php fizzbuzz.php!
1!
2!
Fizz!
4!
Buzz!
Fizz!
7!
8!
Fizz!
Buzz!
11!
Fizz!
13!
14!
Fizz!
16!
17!
Fizz!
19!
Buzz!
15 = FizzBuzz
(c) 2014 Masashi Shinbara @shin1x1
PHPUnit
(c) 2014 Masashi Shinbara @shin1x1
PHPUnit
• PHPコードでテストを書ける
• デファクトスタンダード
• Composer でインストール
(c) 2014 Masashi Shinbara @shin1x1
PHPUnit
http://phpunit.de/manual/current/ja/installation.html
<?php!
class SampleTest extends PHPUnit_Framework_TestCase!
{!
/**!
* @test!
*/!
public function render()!
{!
$this->assertEquals('1', something());!
}!
}!
テストコード
something()の
戻り値が 1 か?
$ phpunit test/!
!
!
!
!
!
!
!
OK の時は、緑
$ phpunit test/!
!
!
!
!
!
!
!
!
!
!
!
!
!
NG の時は、赤
(c) 2014 Masashi Shinbara @shin1x1
FizzBuzzのテストを書く
• test/FizzBuzzTest.php
•fizzbuzz.php の出力をテスト
• expectedOutput()
<?php!
class FizzBuzzTest extends PHPUnit_Framework_TestCase!
{!
/**!
* @test!
*/!
public function render()!
{!
$expected = <<<EOT!
1!
2!
Fizz!
…!
Buzz!
!
EOT;!
!
$this->expectOutputString($expected);!
include __DIR__ . '/../fizzbuzz.php';!
}!
}!
出力をテスト
$ phpunit test/!
!
!
!
!
!
!
!
(c) 2014 Masashi Shinbara @shin1x1
クラスにする
• FizzBuzz クラス
• 関数をFizzBuzzクラスへ
• クラスファイルは別ファイルにする
<?php!
class FizzBuzz!
{!
public function evaluate($i)!
{!
if ($i % 3 === 0 && $i % 5 === 0) {!
return 'FizzBuzz';!
} else if ($i % 3 === 0) {!
return 'Fizz';!
} else if ($i % 5 === 0) {!
return 'Buzz';!
} else {!
return $i;!
}!
}!
!
public function render($outout)!
{!
echo $outout . PHP_EOL;!
}!
}!
<?php!
class FizzBuzz!
{!
public function evaluate($i)!
{!
if ($i % 3 === 0 && $i % 5 === 0) {!
return 'FizzBuzz';!
} else if ($i % 3 === 0) {!
return 'Fizz';!
} else if ($i % 5 === 0) {!
return 'Buzz';!
} else {!
return $i;!
}!
}!
!
public function render($outout)!
{!
echo $outout . PHP_EOL;!
}!
}!
<?php!
require_once __DIR__ . '/class/FizzBuzz.php';!
!
$obj = new FizzBuzz();!
!
for ($i = 1; $i <= 20; $i++) {!
$fizzbuzz = $obj->evaluate($i);!
$obj->render($fizzbuzz);!
}
FizzBuzz
クラスは
別ファイルに
$ phpunit test/!
!
!
!
!
!
!
!
(c) 2014 Masashi Shinbara @shin1x1
さらにクラスにまとめる
• publish() = FizzBuzz を出力
• 入力値をコンストラクタで渡す
<?php!
class FizzBuzz!
{!
protected $start;!
protected $end;!
!
public function __construct($start, $end)!
{!
$this->start = $start;!
$this->end = $end;!
}!
!
public function publish() {!
for ($i = $this->start ; $i <= $this->end ; $i++) {!
$fizzbuzz = $this->evaluate($i);!
$this->render($fizzbuzz);!
}!
}
Sample3
<?php!
class FizzBuzz!
{!
protected $start;!
protected $end;!
!
public function __construct($start, $end)!
{!
$this->start = $start;!
$this->end = $end;!
}!
!
public function publish() {!
for ($i = $this->start ; $i <= $this->end ; $i++) {!
$fizzbuzz = $this->evaluate($i);!
$this->render($fizzbuzz);!
}!
}!
!
protected function evaluate($i)!
{!
if ($i % 3 === 0 && $i % 5 === 0) {!
return 'FizzBuzz';!
} else if ($i % 3 === 0) {!
return 'Fizz';!
} else if ($i % 5 === 0) {!
return 'Buzz';!
} else {!
return $i;!
}!
}!
!
protected function render($outout)!
{!
echo $outout . PHP_EOL;!
}!
}!
<?php!
require_once __DIR__ . '/class/FizzBuzz.php';!
!
$obj = new FizzBuzz(1, 20);!
$obj->publish();!
シンプルなコードに
$ phpunit test/!
!
!
!
!
!
!
!
おさらい
(c) 2014 Masashi Shinbara @shin1x1
FizzBuzz とは
1から20までの整数を出力します。!
!
ただし、3で割り切れる場合は「Fizz」、5で割り切
れる場合は「Buzz」、3でも5でも割り切れる場合は
「FizzBuzz」を出力します。!
!
各項目を出力する際は改行コードを入れて下さい。
(c) 2014 Masashi Shinbara @shin1x1
問題を分解
1から20
FizzBuzz
処理
1
2
Fizz
…
入力 出力処理
<?php!
for ($i = 1; $i <= 20; $i++) {!
if ($i % 3 === 0 && $i % 5 === 0) {!
echo 'FizzBuzz' . PHP_EOL;!
} else if ($i % 3 === 0) {!
echo 'Fizz' . PHP_EOL;!
} else if ($i % 5 === 0) {!
echo 'Buzz' . PHP_EOL;!
} else {!
echo $i . PHP_EOL;!
}!
}
混然一体となったコード
<?php!
class FizzBuzz!
{!
protected $start;!
protected $end;!
!
public function __construct($start, $end)!
{!
$this->start = $start;!
$this->end = $end;!
}!
!
public function execute() {!
for ($i = $this->start ; $i <= $this->end ; $i++) {!
$fizzbuzz = $this->evaluate($i);!
$this->render($fizzbuzz);!
}!
}!
!
protected function evaluate($i)!
{!
if ($i % 3 === 0 && $i % 5 === 0) {!
return 'FizzBuzz';!
} else if ($i % 3 === 0) {!
return 'Fizz';!
} else if ($i % 5 === 0) {!
return 'Buzz';!
} else {!
return $i;!
}!
}!
!
protected function render($outout)!
{!
echo $outout . PHP_EOL;!
}!
}!
処理を分離
<?php!
require_once __DIR__ . '/class/FizzBuzz.php';!
!
$obj = new FizzBuzz(1, 20);!
$obj->publish();!
1から20のFizzBuzzを出力
$ phpunit test/!
!
!
!
!
!
!
!
まとめ
(c) 2014 Masashi Shinbara @shin1x1
(c) 2014 Masashi Shinbara @shin1x1
まとめ
• 問題を分割して、小さく実装
• 関数やクラスでグループ化
• 自動テストは強い味方
(c) 2014 Masashi Shinbara @shin1x1
分割は容量と用法を守って
@shin1x1
(c) 2014 Masashi Shinbara @shin1x1

More Related Content

PHPコードではなく PHPコードの「書き方」を知る