40分濃縮 php classの教室
DESCRIPTION
PHPカンファレンス関西2012で使用したスライドです。完全な内容は下北沢で開催した際のスライドと動画を御覧ください。TRANSCRIPT
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
PHP classの教室40分間濃縮
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
PHPカンファレンス北海道2012 / Yusuke Ando (@yando)
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
本日の対象者
PHPを使っている関数はなんとなくわかる
classを理解したい完全版はWebで
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
本日のメニュー
関数を使ったPHPオブジェクト指向の基礎コードの拡張性を上げる
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
関数を使ったPHPby jepoirrier
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
関数とは
処理に名前を付ける引数(ひきすう)を受け取る
好きな処理をする返り値(かえりち)を返す
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); // ‘水’と表示
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
functionの細かいとこ
名前の大文字小文字スコープ
引数の順番2重定義
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(); 全部同じ結果
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()内のみ
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);
必須の引数が指定されていないとエラー
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
二重定義
<?phpfunction hoge() {}function hoge() {} FATALエラー
真っ白になります
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
練習1関数を作ってください引数: 名前、性別
結果:男なら○○くん女なら○○ちゃん
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); //やよいちゃん
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
練習2
練習1の機能は維持して年齢も引数で受け取り
12歳以上なら○○君/○○さん
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); //やよいさん
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
練習3練習1,2の機能は維持して
男の子なら青女の子ならピンク
になるようにタグで囲む。(タグなしの機能も残す)
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>
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
練習4
練習1,2,3の機能は維持して学校種別を名前の後に表示することもできるように例: つとむくん(小)
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); //やよいさん
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
なんか
ヤバイ
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
長さがヤバイ
エディタに収まらなくなりつつある
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
マジックナンバー
この数字や文字を後で変更する時にミスりそう
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
多すぎる引数
呪文と化した引数
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
複数の関数に分割?
共通部分が多く引数も多い
簡単には分割できない
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
分割するにも
扱っている変数が多い
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
関数の弱点
引数と返り値は複雑なデータを扱うには貧弱(データが単純ならOK)
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
ダークサイドの誘惑
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
一見綺麗だが…このあたりの変数名が衝突した瞬間にアウト
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
再利用性に乏しいデータをセットしなおさ
す必要がある
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
つまりあのプラグインを入れた
ら真っ白に… ここでは動いているけど、あっちではダメ
似たような関数がたくさんコピペされている
手出しできない密林がコードにある
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
オブジェクト指向の基礎by wocrig
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
最初に覚える事
•クラス•プロパティ•定数•メソッド•インスタンス
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
クラス
classでクラスを宣言プロパティ、定数、メソッドをクラス内に宣言できる
<?phpclass MyClass { const HOGE =100; public $some_string = ‘こんにちは’; public $num; public function sayHello() { echo ‘Hello’; }}
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
インスタンス化
クラスとして宣言した処理を利用する為のオブジェクトを作成
アロー演算子(->)でメソッド等を指定
<?php$obj = new MyClass();$obj->sayHello();$obj->some_string = ‘AAAA’;
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
$this
自分自身を指すオブジェクトメソッド内で使える
<?phpclass MyClass { const HOGE =100; public $some_string = ‘こんにちは’; public function sayHello() { echo $this->some_string; }}
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
const
オブジェクトに属する定数を設定self:: か クラス名:: で参照できる
<?phpclass MyClass { const HOGE =100; public function sayHello() { echo self::HOGE; // MyClass::HOGE でもOK }}
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 = ‘こんばんわ’; }}
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
オブジェクトには
関数には出来なかった引数・返り値以外の
データを扱う方法がある!
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
これを整理してみる
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
練習5クラスを作ってくださいプロパティ: 名前、性別メソッド:下記を返す
男なら○○くん女なら○○ちゃん
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
作例5.1
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
初期化をどうするか
名前と性別の初期化が必要引数
直接セット初期化用メソッド
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
引数
破滅の予感
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
直接セット
面倒くさい
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
初期化用メソッド
忘れそう
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
コンストラクタ
__construct というメソッドを作成クラスをnewしてインスタンス化時に
必ず実行される!
<?phpclass MyClass { public $name; public __construct($name) { $this->name = $name; }}
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
作例5.2
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
練習6
コンストラクタで年齢も受け取りプロパティへ
12歳以上なら○○君/○○さん
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
作例6
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
その他の機能
•アクセス修飾子•オートロード•namespace•static
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
アクセス修飾子
メソッドやプロパティへのクラス外からのアクセスを制限できる
public / private / protected
<?phpclass MyClass { const HOGE =100; private $some_string = ‘こんにちは’; public function sayHello() { echo ‘Hello’; }}
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
アクセス修飾子
外部アクセスが不要なプロパティメソッド
をprivateにする事が多い
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
オートロード
クラス名とファイル名を整理しておくとクラスを自動的に読み込める
(クラス定義のみ別ファイルが理想)
<?phpfunction __autoload($class_name) { include $class_name . '.php';}
$obj = new MyClass1();$obj2 = new MyClass2();
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;
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();
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();
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
staticはステートレス
staticはインスタンス毎のデータが扱えず、実質グローバル関数と同じ
補助的な処理などに利用されるが、多用するとグローバル関数と同じ問題を引き起こします
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
コードの拡張性を上げるby MarkyBon
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
クラスを拡張する機能
•継承•抽象クラス•インターフェース•トレイト•マジックメソッド
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
継承
既存のクラスを再利用してクラスを作る
<?phpclass MyClass { public function hoge() { echo ‘a’; }}class MySubClass extends MyClass {}
$obj = new MySubClass();$obj->hoge();
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
parent:: <?phpclass MyClass { public function hoge() { echo ‘a’; }}class MySubClass extends MyClass { public function Hello() { parent::hoge(); }}
メソッドを再利用して新しい処理を作成
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
継承元のクラスは親クラス、スーパークラスと呼ぶparent:: で参照できる
既存のメソッドを上書きも可privateは触れない
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
練習7
クラスを作ってくださいKidを継承したHtmlKid
出力時に男子は青、女子はピンク
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
練習7
Kid.php - 先程のコードHtmlKid.php - 新規test.phpから実行
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
作例7
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
抽象クラス
親クラスになる為だけのクラス
<?phpabstract class BaseClass { abstract protected function fuga(); public function hoge() { echo ‘a’; }
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
インターフェース
特定のメソッドの保持を強制する
<?phpinterface iihito { public function sayHello();}
class Person implements iihito { public function sayHello(){ }}
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
トレイト
特定のメソッドをクラスに注入する
<?phptrait iihito { public function sayHello() { }}
class Person{ use iihito;}
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
最初に思う疑問継承
抽象クラスインターフェース
トレイトなぜ似たような機能が?
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
継承は1つのみ
インタフェーストレイトは柔軟
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
マジックメソッド
クラスに作ると特定のタイミングで自動的に実行され
るすごいメソッド
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
マジックメソッド
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
まとめ
40分濃縮PHP classのクラス / Yusuke Ando (@yando)
classは
•複雑なコードを整理•コードの拡張性を確保•コードをメンテナンスする
クラス=難しい ではなく難しい問題を解決する為の機能です