今回はPHPオブジェクト指向に関する内容を紹介します。
クラス
クラス定義
//プロパティ,
//メソッド,
//定数
}
// サンプル
class Student {
}
$st1=new Student();
$st2=new Student; // ()を省略できる。
オブジェクトの比較
$st2=new Student; // ()を省略できる。
var_dump($st1==$st2); // true 値が同じ
var_dump($st1===$st2); //false オブジェクトが同じ
プロパティ
class Student {
public $name; // プロパティ
public $age=29;
}
// インスタンス
$stu1 = new Student;
// プロパティに値を設定
$stu1->name=’test2′;
$stu1->age=30;
// プロパティの値を取得
echo $stu1->name;
// プロパティ追加
$stu1->address=’TOKYO’;
// プロパティ削除
unset($stu1->address);
メソッド
public $name;
public $age;
// メソッドの場合publicを省略できる。デフォルト値:public
public function Test() {
echo ‘test’;
}
}
$stu1=new Student;
$stu1->Test();
アクセス権限
public 外部からアクセスできる
private 外部からアクセスできない
protected 継承の対象でアクセスできる
private $name;
private $sex;
public setName($name) {
$this->name=$name;
}
}
__construct&__destruct
private $name;
private $age;
public function __construct($name, $age) {
$this->name=$name;
$this->age=$age;
}
public function __destruct() {
echo “{$this->name}終了”;
}
}
new Student()のとき、__constructが実行される。function名はクラス名と同じの場合、constructとして使う。
継承
}
子クラスから親クラスのメソッドを実行する(parent)
public function test() {
echo “Person”;
}
public function show() {
echo “Person”;
}
}
class Student extends Persion {
public function show() {
$this->test();
parent::show();
}
}
オーバーライドとオーバーロード
オーバーライド
public function test() {
echo “Person”;
}
}
class Student extends Persion {
public function test() {
echo “Student”;
}
}
オーバーロード(使えない)
PHPではオーバーロードが使えない。
public function test() {
echo “Person”;
}
public function test($arg) { //エラー
echo “Person”;
}
}
マジックメソッドでオーバーロード
public function __call($fn_name, $fn_args){
switch (count($fn_args)){
case 1:
echo “{$fn_name} para1”;
break;
case 2:
echo “{$fn_name} para2”;
break;
default:
echo “error”;
}
}
}
$stu=new Student;
$stu->show(1);
$stu->shwo(1,2);
static
public static $age=30;
public static function test() {
echo “Person”;
}
}
Person::$age
Person::show();
self
public static $num=30;
public function add($num) {
self::$num +=$num; // self ==Personクラス
}
}
static
public static $num=30;
public function add($num) {
echo static::$num; // staticはオブジェクト.子インスタンスになるかも
}
}
final
final 定義したクラスを継承できない。
final定義したメソッドをオーバーライドできない。
public final function test() {
echo “Person”;
}
}
class Student extends Persion {
public function test() { // オーバーライドできない
echo “Student”;
}
}
abstract
①メソッドを定義し、実行内容を定義しない。
②クラスをインスタンスできない。
public abstract function test() {}
}
class Student extends Persion {
public function test() { // 親クラスのabstractを定義しないとエラー
echo “Student”;
}
}
クラス定数(const)
//public const AGE=0; //7.1以降
const AGE=0; //7.1以前
}
echo Person::AGE;
interface
function test1() {}; //デフォルト値public
function test1() {}; //デフォルト値public
}
class Student implements IPerson {
public function test1() {
}
public function test2() {
}
}
interface Inter1{
function func1();
}
interface Inter2{
function func1();
}
class Student implements Inter1,Inter2 {
public function func1() {
}
}
無名クラス(7.0以降)
private $name;
private $age;
public function __construct($name, $age) {
$this->name=$name;
$this->age=$age;
}
無名関数(7.0以降)
echo “func”;
}
class Student{
}
$stu=new Student();
$fun->call($stu);
異常処理
//処理内容
// 異常
throw new Exception(‘msg’,’code’);
} catch(Exception $ex) {
// エラーのとき、実行する
} finally {
// 最後に実行する
}
class AException extends Exception{
}
クラスのオートローディング
手動で
<?
class Good{
}
ファイル:Book.class.php
<?
class Book extends Good {
}
ファイル:demo.php
<?
require “./Good.class.php”;
requre “./Book.class.php”;
$book=new Book();
(__autoload)_PHP7.2以前
<?
function __autoload($class){
require “./{$class}.class.php”;
}
$book=new Book();
spl_autoload_register()PHP5.1以降
方法1
<?
function loadClass($class){
require “./{$class}.class.php”;
}
spl_autoload_register(‘loadClass’);
$book=new Book();
方法2
<?
spl_autoload_register(function($class_name){
require “./{$class_name}.class.php”;
});
$book=new Book();
方法3
<?
function loadClass($class){
$arr=array(
‘Good’ => ‘./good/Good.class.php’,
‘Book’ => ‘./book/Book.class.php’,
);
if (isset($arr[$class]))
require $arr[$class];
else
require “./{$class}.class.php”;
}
spl_autoload_register(‘loadClass’);
$book=new Book();
clone
public final function test() {
echo “Person”;
}
// closeを実行するとき、__clone()を実行される
public function __clone() {
echo ‘__clone()’;
}
}
$stu=new Person();
$stu2=clone $stu;
デザインパターン
Singleton
private $instance;
private function __construct() {}
private function __clone() {}
public static function getInstance() {
if (!self::$instance instanceof self)
self::$instance=new self();
return self::$instance;
}
}
Factory
class B{}
class ProductsFactory {
public function createProduct($num) {
switch($num) {
case 1:
return new A();
case 2:
return new B();
default:
return null;
}
}
}
$factory=new ProductsFactory();
$obj1=factory.createProduct(1);
$obj2=factory.createProduct(2);
Strategy
public function getData() {
echo ‘A getData’;
}
}
class B {
public function getData() {
echo ‘B getData’;
}
}
class SampleStrategy {
public function getData($obj) {
$obj->getData();
}
}
$sap=new SampleStrategy();
$sap->getData(new B());
シリアライズとデシリアライズ
シリアライズ
$str=serialize($arr);
file_put_contents(‘./arr.txt’,$str);
デシリアライズ
$arr=unserialize($str);
print_r($arr)
マジックメソッド
__tostring()と__invoke()
public function __tostring(){
return ‘__tostring()’;
}
public function __invoke(){
return ‘__invoke()’;
}
}
$stu=new Student();
echo $stu; // __tostring()出力
$stu(); // __invoke()出力
__set($k,$v)と__get($k)、__isset($k)と__unset($k)
private $name;
private $age;
public function __set($k, $v){
$this->$k=$v;
}
public function __get($k){
return $this-$k;
}
public function __isset($k){
return isset($this->$k;
}
public function __unset($k){
return unset($this->$k;
}
}
$stu=new Student();
$stu->name=’test’; // __set($k,$v)を実行される
echo $stu->name; // __get($k)を実行される
echo isset($stu->age); // __isset($k)を実行される
unset($stu->age); // __unset($k)を実行される
__call()、__callstatic
public function __call($name, $args){
echo ‘存在しないメソッド’.$name;
}
public function __callstatic($name, $args){
echo ‘存在しないstaticメソッド’.$name;
}
}
$stu=new Student();
$stu->play(); // __call()が実行される
Student::play(); //__callstaticが実行される
__sleep()、__wakeup()
private $name;
private $age;
// シリアライズのとき、実行される
public function __sleep(){
return array(‘name’,’age’);
}
// デシリアライズのとき、実行される
public function __wakeup(){
$this->address=’test’;
}
}
オブジェクトループ
public $name=’test1′;
protected $age=29;
private $address=’TOKYO’;
public function show(){
foreach($this as $k=>$v) {
echo $k.”-“.$v;
}
}
}
$stu=new Student;
foreach($stu as $k=>$v) { //name-test1
echo $k.”-“.$v;
}
$stu->show(); //name-test1age-29address-TOKYO
名前空間
名前空間を定義するには、namespaceキーワードの後に任意の空間名を記述します。
\ で区切ってサブ名前空間を記述できます。
名前空間の記述
function play() {
echo ‘A play’.”\n”;
}
namespace app;
function play() {
echo ‘B play’.”\n”;
}
// 非修飾形式
play(); // B play
// 修飾形式
content\play(); //A play
// 完全修飾形式
\app\content\play(); //A play
useキーワード
use 名前空間の全て、または一部 as 別名;
function play() {
echo ‘A play’.”\n”;
}
namespace demo;
function play() {
echo ‘B play’.”\n”;
}
use app\content;
play(); // B play
content\paly(); //A play 「use app\content;」がない場合、エラー
クラスをインポート
関数をインポート
定数をインポート
トレイト(trait)
trait使用
public function play() {
echo ‘A play’;
}
}
use A;
}
$emp=new Emp;
$emp->play(); // A play
重複宣言による衝突
public function play() {
echo ‘A play’;
}
}
trait B {
public function play() {
echo ‘B play’;
}
}
use A,B {
//方法1(Bの代わりにAを使う)
A::play insteadof B;
// Bのメソッドを利用したい場合
B::play as playB;
}
}
$emp=new Emp;
$emp->play(); // A play
$emp->playB(); // B play
アクセス権限変更
private function play() {
echo ‘A play’;
}
}
use A {
play as public playNew; // メッソドのアクセス権限とメソッド名を変更する
}
}
$emp=new Emp;
$emp->playNew(); // A play
foreach可能なオブジェクトを作る
Iterator
Iteratorを利用するとき、以下の五つメソッドを実装しなければならない。
function current();
function key();
function next();
function rewind();
function valid();
}
private $score_list=array();
public function addScore($score) {
$this->score_list[]=$score;
}
public function rewind() {
reset($this->score_list);
}
public function valid(){
return key($this->score_list) !==null;
}
public function current() {
return current($this->score_list);
}
public function key() {
return key($this->score_list);
}
return next($this->score_list);
}
}
$stu->addScore(29);
$stu->addScore(10);
$stu->addScore(23);
$stu->addScore(33);
foreach($stu as $k=>$v) {
echo “{$k}-{$v}”;
}
IteratorAggregate
function getIterator();
}
private $score_list=array();
public function addScore($score) {
$this->score_list[]=$score;
}
// 方法1
return new ArrayIterator($this->score_list);
}
foreach ($this->score_list as $key => $val) {
yield $key => $val;
}
}
}
$stu->addScore(29);
$stu->addScore(10);
$stu->addScore(23);
$stu->addScore(33);
foreach($stu as $k=>$v) {
echo “{$k}-{$v}”;
}