40分濃縮 php classの教室

75
40分濃縮PHP classのクラス / Yusuke Ando (@yando) PHP classの教室 40分間濃縮 40分濃縮PHP classのクラス / Yusuke Ando (@yando)

Upload: yandod

Post on 18-Dec-2014

23.706 views

Category:

Technology


1 download

DESCRIPTION

PHPカンファレンス関西2012で使用したスライドです。完全な内容は下北沢で開催した際のスライドと動画を御覧ください。

TRANSCRIPT

Page 1: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

PHP classの教室40分間濃縮

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

Page 2: 40分濃縮 PHP classの教室

PHPカンファレンス北海道2012 / Yusuke Ando (@yando)

Page 3: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

本日の対象者

PHPを使っている関数はなんとなくわかる

classを理解したい完全版はWebで

Page 4: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

本日のメニュー

関数を使ったPHPオブジェクト指向の基礎コードの拡張性を上げる

Page 5: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

関数を使ったPHPby jepoirrier

Page 6: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

関数とは

処理に名前を付ける引数(ひきすう)を受け取る

好きな処理をする返り値(かえりち)を返す

Page 7: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

function<?phpfunction hoge() { return date(‘Y-m-d’);}function fuga($w = null) { if (is_null($w)) { $w = date(‘w’); } $list = array(‘日’,’月’,’火’,’水’,’木’,’金’,’土’); return $list[$w];}echo hoge(); // ‘2012-03-21’ などと表示echo fuga(3); // ‘水’と表示

Page 8: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

functionの細かいとこ

名前の大文字小文字スコープ

引数の順番2重定義

Page 9: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

名前の大文字小文字<?phpfunction hoge() { return date('Y-m-d');}echo hoge(); // ‘2012-03-21’ などと表示echo Hoge();echo HOGE();echo hogE();$a = 'hoge';echo $a(); 全部同じ結果

Page 10: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

スコープ

hoge()内で有効なのは$inのみ

<?php$out = '1000';function hoge() { $in = 'ABCD'; echo $out; echo $etc;}function fuga() { $etc = 'XYZ';}hoge();hoge();echo $in;

$inが有効なのはhoge()内のみ

Page 11: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

引数の順番<?phpfunction hoge($a) {}function fuga($a, $b =0){}function moge($a=null,$b=null,$c) {}hoge(1); //OKfuga(1); //OKmoge(1,2,3); //OKhoge();fuga();moge(1,2);

必須の引数が指定されていないとエラー

Page 12: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

二重定義

<?phpfunction hoge() {}function hoge() {} FATALエラー

真っ白になります

Page 13: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

練習1関数を作ってください引数: 名前、性別

結果:男なら○○くん女なら○○ちゃん

Page 14: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

作例1<?phpfunction getLabel($name, $sex) { if ($sex == '1') { $suffix = 'くん'; } else { $suffix = 'ちゃん'; } return $name . $suffix;}

echo getLabel('つとむ', 1); //つとむくんecho getLabel('やよい', 2); //やよいちゃん

Page 15: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

練習2

練習1の機能は維持して年齢も引数で受け取り

12歳以上なら○○君/○○さん

Page 16: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

作例2<?phpfunction getLabel($name, $sex, $age=0) { if ($sex == '1') { $suffix = 'くん'; if ( $age >= 12) { $suffix = '君'; } } else { $suffix = 'ちゃん'; if ( $age >= 12) { $suffix = 'さん'; } } return $name . $suffix . "\n";}echo getLabel('つとむ', 1,10); //つとむくんecho getLabel('やよい', 2,20); //やよいさん

Page 17: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

練習3練習1,2の機能は維持して

男の子なら青女の子ならピンク

になるようにタグで囲む。(タグなしの機能も残す)

Page 18: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

作例3<?phpfunction getLabel($name, $sex, $age=0, $coloring=false) { if ($sex == '1') { $suffix = 'くん'; $color = 'blue'; if ( $age >= 12) { $suffix = '君'; } } else { $suffix = 'ちゃん'; $color = 'pink'; if ( $age >= 12) { $suffix = 'さん'; } } $str = "<span style='color:$color'>". $name . $suffix . "</span>\n"; if (!$coloring) { $str = $name . $suffix . "\n"; } return $str;}

echo getLabel('つとむ', 1); //つとむくんecho getLabel('やよい', 2); //やよいちゃんecho getLabel('つとむ', 1,10); //つとむくんecho getLabel('やよい', 2,8); //やよいちゃんecho getLabel('つとむ', 1,12); //つとむ君echo getLabel('やよい', 2,20); //やよいさんecho getLabel('つとむ', 1,0,true);//<span style='color:blue'>つとむくん</span>echo getLabel('やよい', 2,0,true);//<span style='color:pink'>やよいちゃん</span>

Page 19: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

練習4

練習1,2,3の機能は維持して学校種別を名前の後に表示することもできるように例: つとむくん(小)

Page 20: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

作例4<?phpfunction getLabel($name, $sex, $age=0, $coloring=false, $school=false ) { if ($sex == '1') { $suffix = 'くん'; $color = 'blue'; if ( $age >= 12) { $suffix = '君'; } } else { $suffix = 'ちゃん'; $color = 'pink'; if ( $age >= 12) { $suffix = 'さん'; } } if ( $age >= 6 && $age <= 11 ) { $suffix .= "(小)"; } else if ( $age >= 12 && $age <= 14 ) { $suffix .= "(中)"; } else if ( $age >= 15 && $age <= 17 ) { $suffix .= "(高)";

} else if ( $age >= 18 && $age <= 21 ) { $suffix .= "(大)"; } $str = "<span style='color:$color'>". $name . $suffix . "</span>\n"; if (!$coloring) { $str = $name . $suffix . "\n"; } return $str;}

echo getLabel('つとむ', 1); //つとむくんecho getLabel('やよい', 2); //やよいちゃんecho getLabel('つとむ', 1,10); //つとむくんecho getLabel('やよい', 2,8); //やよいちゃんecho getLabel('つとむ', 1,12); //つとむ君echo getLabel('やよい', 2,20); //やよいさんecho getLabel('つとむ', 1,10,false,true); //つとむくんecho getLabel('やよい', 2,8,false,true); //やよいちゃんecho getLabel('つとむ', 1,12,false,true); //つとむ君echo getLabel('やよい', 2,20,false,true); //やよいさん

Page 21: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

なんか

ヤバイ

Page 22: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

長さがヤバイ

エディタに収まらなくなりつつある

Page 23: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

マジックナンバー

この数字や文字を後で変更する時にミスりそう

Page 24: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

多すぎる引数

呪文と化した引数

Page 25: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

複数の関数に分割?

共通部分が多く引数も多い

簡単には分割できない

Page 26: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

分割するにも

扱っている変数が多い

Page 27: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

関数の弱点

引数と返り値は複雑なデータを扱うには貧弱(データが単純ならOK)

Page 28: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

ダークサイドの誘惑

Page 29: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

一見綺麗だが…このあたりの変数名が衝突した瞬間にアウト

Page 30: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

再利用性に乏しいデータをセットしなおさ

す必要がある

Page 31: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

つまりあのプラグインを入れた

ら真っ白に… ここでは動いているけど、あっちではダメ

似たような関数がたくさんコピペされている

手出しできない密林がコードにある

Page 32: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

オブジェクト指向の基礎by wocrig

Page 33: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

最初に覚える事

•クラス•プロパティ•定数•メソッド•インスタンス

Page 34: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

クラス

classでクラスを宣言プロパティ、定数、メソッドをクラス内に宣言できる

<?phpclass MyClass { const HOGE =100; public $some_string = ‘こんにちは’; public $num; public function sayHello() { echo ‘Hello’; }}

Page 35: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

インスタンス化

クラスとして宣言した処理を利用する為のオブジェクトを作成

アロー演算子(->)でメソッド等を指定

<?php$obj = new MyClass();$obj->sayHello();$obj->some_string = ‘AAAA’;

Page 36: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

$this

自分自身を指すオブジェクトメソッド内で使える

<?phpclass MyClass { const HOGE =100; public $some_string = ‘こんにちは’; public function sayHello() { echo $this->some_string; }}

Page 37: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

const

オブジェクトに属する定数を設定self:: か クラス名:: で参照できる

<?phpclass MyClass { const HOGE =100; public function sayHello() { echo self::HOGE; // MyClass::HOGE でもOK }}

Page 38: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

$this

プロパティはメソッドを跨って参照や更新ができる

<?phpclass MyClass { public $some_string = ‘こんにちは’; public function sayHello() { echo $this->some_string; } public function change() { $this->some_string = ‘こんばんわ’; }}

Page 39: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

オブジェクトには

関数には出来なかった引数・返り値以外の

データを扱う方法がある!

Page 40: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

これを整理してみる

Page 41: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

練習5クラスを作ってくださいプロパティ: 名前、性別メソッド:下記を返す

男なら○○くん女なら○○ちゃん

Page 42: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

作例5.1

Page 43: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

初期化をどうするか

名前と性別の初期化が必要引数

直接セット初期化用メソッド

Page 44: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

引数

破滅の予感

Page 45: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

直接セット

面倒くさい

Page 46: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

初期化用メソッド

忘れそう

Page 47: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

コンストラクタ

__construct というメソッドを作成クラスをnewしてインスタンス化時に

必ず実行される!

<?phpclass MyClass { public $name; public __construct($name) { $this->name = $name; }}

Page 48: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

作例5.2

Page 49: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

練習6

コンストラクタで年齢も受け取りプロパティへ

12歳以上なら○○君/○○さん

Page 50: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

作例6

Page 51: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

その他の機能

•アクセス修飾子•オートロード•namespace•static

Page 52: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

アクセス修飾子

メソッドやプロパティへのクラス外からのアクセスを制限できる

public / private / protected

<?phpclass MyClass { const HOGE =100; private $some_string = ‘こんにちは’; public function sayHello() { echo ‘Hello’; }}

Page 53: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

アクセス修飾子

外部アクセスが不要なプロパティメソッド

をprivateにする事が多い

Page 54: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

オートロード

クラス名とファイル名を整理しておくとクラスを自動的に読み込める

(クラス定義のみ別ファイルが理想)

<?phpfunction __autoload($class_name) {    include $class_name . '.php';}

$obj  = new MyClass1();$obj2 = new MyClass2();

Page 55: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

namespace

さらには namespace という文法を使ってフォルダ階層とクラスを対応させる方法がPHP5.3以降で使えるように

<?phpnamespace my\name;class MyClass {}function myfunction() {}const MYCONST = 1;

$c = new \my\name\MyClass;

Page 56: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

static

staticが指定されたメソッドはインスタンスを作らずに実行できる

<?phpclass MyClass { const HOGE =100; private $some_string = ‘こんにちは’; public static function sayHello() { echo ‘Hello’; }}echo MyClass::sayHello();

Page 57: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

staticの落とし穴

staticが指定されたメソッドは$thisを使えない!

<?phpclass MyClass { const HOGE =100; private $some_string = ‘こんにちは’; public static function sayHello() { echo $this->some_string; }}echo MyClass::sayHello();

Page 58: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

staticはステートレス

staticはインスタンス毎のデータが扱えず、実質グローバル関数と同じ

補助的な処理などに利用されるが、多用するとグローバル関数と同じ問題を引き起こします

Page 59: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

コードの拡張性を上げるby MarkyBon

Page 60: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

クラスを拡張する機能

•継承•抽象クラス•インターフェース•トレイト•マジックメソッド

Page 61: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

継承

既存のクラスを再利用してクラスを作る

<?phpclass MyClass { public function hoge() { echo ‘a’; }}class MySubClass extends MyClass {}

$obj = new MySubClass();$obj->hoge();

Page 62: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

parent:: <?phpclass MyClass { public function hoge() { echo ‘a’; }}class MySubClass extends MyClass { public function Hello() { parent::hoge(); }}

メソッドを再利用して新しい処理を作成

Page 63: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

継承元のクラスは親クラス、スーパークラスと呼ぶparent:: で参照できる

既存のメソッドを上書きも可privateは触れない

Page 64: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

練習7

クラスを作ってくださいKidを継承したHtmlKid

出力時に男子は青、女子はピンク

Page 65: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

練習7

Kid.php - 先程のコードHtmlKid.php - 新規test.phpから実行

Page 66: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

作例7

Page 67: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

抽象クラス

親クラスになる為だけのクラス

<?phpabstract class BaseClass { abstract protected function fuga(); public function hoge() { echo ‘a’; }

Page 68: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

インターフェース

特定のメソッドの保持を強制する

<?phpinterface iihito { public function sayHello();}

class Person implements iihito { public function sayHello(){ }}

Page 69: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

トレイト

特定のメソッドをクラスに注入する

<?phptrait iihito { public function sayHello() { }}

class Person{ use iihito;}

Page 70: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

最初に思う疑問継承

抽象クラスインターフェース

トレイトなぜ似たような機能が?

Page 71: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

継承は1つのみ

インタフェーストレイトは柔軟

Page 72: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

マジックメソッド

クラスに作ると特定のタイミングで自動的に実行され

るすごいメソッド

Page 73: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

マジックメソッド

Page 74: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

まとめ

Page 75: 40分濃縮 PHP classの教室

40分濃縮PHP classのクラス / Yusuke Ando (@yando)

classは

•複雑なコードを整理•コードの拡張性を確保•コードをメンテナンスする

クラス=難しい ではなく難しい問題を解決する為の機能です