オブジェクト指向 - PHP入門
目次
- PHP入門
- PHPの概要
- PHP環境のインストール(XAMPP)・PHPの設定
- PHPの基本・簡単なプログラム
- 文法1
- 文法2
- 様々な関数を使う
- フォームの基本
- システム作成
- オブジェクト指向
- データベースとSQL
- PHPでMySQLを使う
- ブログを作る
- ECサイト(ショッピングサイト)を作る
このページの内容
はじめに
大規模なシステムを作る際に役に立つ考え方が「オブジェクト指向」です。PHPでもオブジェクト指向をサポートする構文が用意されています。また、既に用意されているクラスライブラリがたくさんあり、用途に応じて使い分けることもできます。オブジェクト指向とは
オブジェクト指向の真の意味は理解が面倒なのでとりあえず置いておき、その考え方によって便利になる例を示します。プログラムが大規模になって変数が増えてくると管理が大変になります。そのような場合、変数をいくつかのグループに分けると管理が楽になります(たとえばフォームを扱う変数群、ファイルを扱う変数群など)。そこで、同じ仕事をする変数を同じグループに分けて、さらにその仕事に関する関数も同じグループに入れて整理します。このような場合、「オブジェクト指向」という考え方が有用です。
PHPのオブジェクト指向プログラミングでは、まず最初に「クラス」というものを作ります。これは指示書・設計図になります。そしてその設計図(クラス)から「インスタンス(オブジェクト)」を作ります。インスタンスとオブジェクトは、ほぼ同じ意味で、「実体」ということです。
クラスの構文は以下のようになります。
class クラス名 {
アクセス修飾子 プロパティ名;
アクセス修飾子 function メソッド名() {
メソッド定義
}
}
詳しくは後述します。クラスとオブジェクトを使ったサンプル
object1.php
<?php
// Humanクラス定義
class Human {
public $name;
public $height;
public $weight;
function show() {
echo "{$this->name}さんの身長は{$this->height}cm、体重は{$this->weight}kgです。<br>";
}
}
// $taroインスタンス
$taro = new Human();
$taro->name = '太郎';
$taro->height = 174;
$taro->weight = 70;
$taro->show();
// $hanakoインスタンス
$hanako = new Human();
$hanako->name = '花子';
$hanako->height = 158;
$hanako->weight = 50;
$hanako->show();
?>
クラスとオブジェクトを使ったサンプルの解説
class Human {
・・・
}
この部分でHumanクラスを定義しています。クラスの内容は中括弧の中に書きます。
public $name;
public $height;
public $weight;
変数$name(名前)、$height(身長)、$weight(体重)をまとめて定義しています。クラスの中に定義した変数のことを「プロパティ」と言います。
function show() {
echo "{$this->name}さんの身長は{$this->height}cm、体重は{$this->weight}kgです。<br>";
}
名前と身長と体重を表示する関数showを定義しています。クラスの中に定義した関数のことを「メソッド」と言います。
$taro = new Human();
$taro->name = '太郎';
$taro->height = 174;
$taro->weight = 70;
$taro->show();
Humanクラスという設計図を元に$taroという実体を作成し、名前・身長・体重をプロパティに代入し、showメソッドを呼んで表示しています。
$hanako = new Human();
$hanako->name = '花子';
$hanako->height = 158;
$hanako->weight = 50;
$hanako->show();
同じくHumanクラスという設計図を元に$hanakoという実体を作成し、名前・身長・体重をプロパティに代入し、showメソッドを呼んで表示しています。インスタンス(オブジェクト)の生成
インスタンスを生成する際の構文は以下のようになります。
インスタンス名 = new クラス名()
これで指定したクラスから新しいオブジェクトが生成されます。プロパティの読み書き
インスタンスのプロパティを読み書きするには、以下のように書きます。
インスタンス名->プロパティ名
上記サンプルプログラムでは
$taro->name = '太郎';
$taro->height = 174;
$taro->weight = 70;
この部分でプロパティに値を代入しています。メソッドの呼び出し
インスタンスのメソッド呼び出しは、以下のように書きます。
インスタンス名->メソッド名()
上記サンプルプログラムでは
$taro->show();
この部分でメソッドを呼び出しています。メソッド内から自身のプロパティを参照するときは「$this->プロパティ名」と書きます。上記サンプルプログラムの
echo "{$this->name}さんの身長は{$this->height}cm、体重は{$this->weight}kgです。<br>";
「$this->name」は自分自身のプロパティである$name、「$this->weight」は自分自身のプロパティである$weightを参照しています。アクセス修飾子とは
アクセス修飾子には「public」「protected」「private」のいずれかが入ります。publicを指定したプロパティは、クラスの外からでも参照できます。privateを指定したプロパティは、クラスの内部でのみ参照できます。protectedを指定したプロパティは、クラスの内部と継承したクラスの内部で参照できます。メソッドにもfunctionの前にアクセス修飾子を付けることができますが、省略した場合はpublicと同じ意味になります。アクセス修飾子は、オブジェクトの中身を外から自由に触らせないようにするためにあります。これを「カプセル化」と言います。たとえば、object1.phpで「public $name;」を「private $name;」に変更すると以下のようなエラーが表示されます。
Fatal error: Cannot access private property Human::$name in C:\xampp\htdocs\php\object1.php on line 14
クラスの外側(クラス定義の中括弧の外)からプロパティ$nameを参照している部分が2行ありますが、
$taro->name = '太郎';
$hanako->name = '花子';
privateを指定したプロパティはクラスの外から参照するとエラーになるのです。ウェブアプリとの組み合わせ
オブジェクト指向の考え方を、ウェブアプリに用いるとどうなるでしょうか?ここでは一例として、フォームとセッションをクラスと組み合わせた例を示します。以下のソースは、フォームから名前・身長・体重を入力するとセッションに保存され、保存されたデータをテーブルで一覧表示するものです。
object2.html
<form action="object2.php" method="post">
名前:<input type="text" name="name"><br>
身長:<input type="text" name="height"><br>
体重:<input type="text" name="weight"><br>
<input type="submit">
</form>
object2.php
<?php
class Human {
public $name;
public $height;
public $weight;
function show() {
echo "<tr><td>$this->name</td><td>$this->height</td><td>$this->weight</td></tr>";
}
}
session_start();
$man = new Human();
$man->name = htmlspecialchars($_POST['name']);
$man->height = htmlspecialchars($_POST['height']);
$man->weight = htmlspecialchars($_POST['weight']);
$_SESSION[$man->name] = $man;
?>
<table border="1">
<tr><th>名前</th><th>身長</th><th>体重</th></tr>
<?php
foreach ($_SESSION as $s) {
$s->show();
}
?>
</table>
<a href="object2.html">戻る</a>
Humanクラスは前節とほぼ同じですが、showメソッドはテーブルの一行を出力するように変更しています。
$man = new Human();
$man->name = htmlspecialchars($_POST['name']);
$man->height = htmlspecialchars($_POST['height']);
$man->weight = htmlspecialchars($_POST['weight']);
Humanクラスからインスタンス$manを生成し、フォームから入力された名前・身長・体重をそれぞれ該当するプロパティに代入しています。
$_SESSION[$man->name] = $man;
セッション変数にインスタンス$manを保存しています。セッション配列の添え字は、入力された名前にしています。
foreach ($_SESSION as $s) {
$s->show();
}
セッション変数から順番にインスタンスを取り出し、showメソッドを呼び出して、テーブルの各行を出力しています。クラスを使わずに同じ機能を実現しようとすると、各人の名前・身長・体重をそれぞれセッション変数に登録する必要があり、処理が煩雑になります。
既存のクラスを使う(RSSリーダー)
ここまでクラスの作成方法を解説しましたが、実際には自分でクラスを作るよりも、既存のクラスを利用することのほうが多いと思います。ここではひとつの例として、XMLを扱うクラスを使いRSSリーダーを作成してみましょう。RSSとは、ニュースなどの最新記事と概要をXML形式で配信するための仕組みです。XMLの内容を解析するのは面倒なのですが、PHPの「simpleXML」機能を使うと簡単に内容を取り出すことができます。以下にGoogleニュースのRSSフィードを取得して表示するプログラムを示します。
rss.php
<?php
$rss = simplexml_load_file("http://news.google.com/news?hl=ja&ned=us&ie=UTF-8&oe=UTF-8&output=rss");
foreach ($rss->channel->item as $item) {
echo "<p><a href='$item->link'>$item->title</a></p>";
}
?>
まずsimplexml_load_file関数でRSSフィードを指定してXMLを取得します。この関数の戻り値は「SimpleXMLElement」クラスのオブジェクトで、このクラスはXMLの操作を簡単にしてくれるものです。SimpleXMLElementクラスのインスタンスが$rssに入るので、RSSの形式に従って記事をループで取り出して表示しています。$rssは、プロパティとしてchannnel(SimpleXMLElementオブジェクト)、さらにchannelのプロパティとして各記事を表す配列itemを持ちます。itemのプロパティ「title」が記事のタイトル、「link」が元記事へのリンクです。
上記プログラムではGoogleニュースのRSSフィードを指定しましたが、simplexml_load_file関数の引数を変更すると、あらゆるニュースサイトやブログのRSSを指定して表示することができます。
既存のクラスを使う(zipファイルの圧縮)
次に、zipファイルの圧縮・解凍ができる「ZipArchive」クラスを利用してファイルを圧縮してみましょう。以下のプログラムを実行すると、「zip.php」が「test.zip」ファイルに圧縮されます。zip.php
<?php
$zip = new ZipArchive();
$zip->open('test.zip', ZipArchive::CREATE);
$zip->addFile('zip.php');
$zip->close();
?>
圧縮完了しました。
ZipArchiveクラスのopenメソッドにより作成するzipファイルをオープンし、addFileメソッドで圧縮するファイルを指定し、closeメソッドでクローズします。圧縮するファイルは複数指定できます。継承
オブジェクト指向では「継承」という概念があります。継承は、既存のクラスに機能を追加して新しいクラスを作ることです。継承したクラスの記述法
class クラス名 extends 親クラス名 {
クラス定義
}
継承のサンプルとして、上で解説したZipArchiveクラスを継承した「ZipArchive2」クラスを作成してみましょう。zip2.php
<?php
class ZipArchive2 extends ZipArchive {
public function addArray($array) {
foreach ($array as $file) $this->addFile($file);
}
}
$zip = new ZipArchive2();
$zip->open('test2.zip', ZipArchive::CREATE);
$zip->addArray(array('zip.php', 'zip2.php'));
$zip->close();
?>
圧縮完了しました。
このプログラムで、ZipArchiveクラスを継承し、ZipArchive2クラスを定義しています。継承元クラスのことを「親クラス」「スーパークラス」などと呼びます。継承したZipArchive2クラスでは、継承元のZipArchiveクラスの全ての機能が使用できる上に、独自のプロパティやメソッドを持つことができます。
ZipArchive2クラスでは、addArrayメソッドを追加しています。このメソッドは、ファイル名を格納した配列を引数で渡すと、全てのファイルを圧縮ファイルに追加してくれます。
継承を使うことによって、PHPの豊富なクラスライブラリを用途に応じてカスタマイズすることができます。