Udemy で講座の販売を開始しました!
Udemy で「プログラミング学習の心得&HTTPの基礎」の動画講座を公開しました。
特別に 85% OFFのクーポンを発行します。
通常価格 10,800 円が 1,800 円で購入できます。
動画内でも説明していますが、初心者・初学者向けの内容です。
事前に自分の知りたい内容・興味のある内容か確認してからご購入ください。
はじめに
変数と関数の基礎はわかり、クラスも何となく聞いたことがある超初心者向けです。
長いですが、変数と関数しかわからなくても、読めばクラス、例外処理、PDOについて何となくわかるようになると思います。
それ以上の方は、読む必要はないと思います。
時間の無駄ですwww
PHPでデータベースを利用するには、PDOを理解する必要があります。
PDOを理解するには、クラスと例外処理の基礎知識が必要になります。
プログラミングの経験もなく、PHPを勉強し始めた超初心者にとっては非常にハードルが高いです。
なので、PDOを使ってデータベースに接続するために
- 序章
- 第1章 クラスの基礎
- 第2章 例外処理の基礎
- 第3章 PDOの基礎
という流れでまとめてみました。
序章
今までのデータベース接続
データベースへの接続方法の一つにmysql関数を使った方法があります。
下記のように関数を使い引数を指定するだけで簡単に接続できました。
$link = mysql_connect('ホスト名', 'ユーザー名', 'パスワード');
すげー簡単!やったー\(^o^)/ って感じですが、mysql関数を使った接続方法は、PHP 5.5.0 で非推奨になり、PHP 7.0.0 で削除されました。
特別な理由がない限りこの接続方法は使わないようにしましょう。
これからのデータベース接続
mysql関数以外でデータベースに接続するには、PDOまたはMySQLiを使用します。
今回は、PHP5.1.0から使えるPDOを使ってデータベースに接続したいと思います。
早速、PDOを調べてみると
データベース抽象化レイヤの一つで、プリペアドステートメントを ...
えっ ... 抽象化レイヤ? プリペアドステートメント? なにそれ ... (・ω・`;)
とりあえず難しい用語は忘れましょう。
PDOって何?という疑問もあるかと思いますが、今はPDOというものを使えば、データベースに接続できるとだけ覚えておきましょう。
今までのデータベース接続は、関数の知識があれば使えました。
PDOを使ってデータベースに接続するには、PDOクラスを利用します。
PDOを理解するには、クラスと例外処理の知識が必要になります。
まずは、クラスと例外処理の基礎をおさえましょう。
今回は、PDOを使ってデータベース(MySQL)に接続することが目的です。
クラスや例外処理、PDOについて必要最低限の基礎しか触れておりませんのでご了承ください。
前提条件
- PHPは5.3.6以上を使う前提で説明しております。PHP5.3.5以前での留意点も記述しております。
- データベースはMySQLを利用し、文字エンコードはUTF-8を使う前提で説明しております。
第1章 クラスの基礎
クラスとは
ざっくり言うと変数と関数の集まりです。
クラス = 変数 + 関数
クラスを定義する構文を見ると変数と関数の集まりなのがわかるかと思います。
クラスを定義する構文
ざっくりと書いた構文です。
class クラス名 {
$変数名
function 関数名(引数) {
}
}
変数と関数の集まりなので、簡単ですね。
それだけならクラスを使う意味がないのでは?と思いますよね。
次は変数と関数とクラスのそれぞれの違いを見ていきましょう。
変数と関数とクラスの違い
クラスは、変数と関数の集まりですので、データの保持と処理が可能です。
データの保持 | データの処理 | |
---|---|---|
変数 | ○ | × |
関数 | × | ○ |
クラス | ○ | ○ |
変数と関数とクラスの違いがわかりました。
実はクラス内に記述した変数と関数は別の名称になります。
次は、どのような名称になるのか見ていきましょう。
クラス内における変数と関数の名称
先ほど記述したクラスの構文で、クラス内にあっても変数と関数と書きましたが、実は名称が変わります。
クラス内に記述した変数はプロパティと呼び、クラス内に記述した関数をメソッドと呼びます。
以降の説明では、基本的にクラス内に記述された変数をプロパティ、関数をメソッドと呼びますのでしっかり覚えてください。
しつこいですが、クラス内に記述した変数と関数のことをプロパティとメソッドと呼びます。
後から新しい用語がでてきますので、プロパティとメソッドはここで完璧に覚えてください。
クラス内に記述したときの名称 | |
---|---|
変数 | プロパティ |
関数 | メソッド |
先ほど記述したクラスの構文を正しい名称にすると下記のようになります。
class クラス名 {
$プロパティ名
function メソッド名(引数) {
}
}
クラス内に記述した変数はプロパティで、関数はメソッドという名称に変わりました。
しつこいですが、クラス内に記述した変数と関数のみ名称が変わります。
実は名称を変えただけでは、クラスを定義する構文は、まだ完成しておりません。
もう一度クラスを定義する構文を見てみましょう。
クラスを定義する構文
先ほど記載した構文と少し変わっています。
class クラス名 {
アクセス修飾子 $プロパティ名;
アクセス修飾子 function メソッド名(引数)
{
//処理を記述
}
}
注目すべきはプロパティとメソッドの前にアクセス修飾子があることです。
先ほどは、わかりやすくするためにアクセス修飾子をあえて書きませんでした。
実際にはアクセス修飾子というのが必要ですので、覚えておいてください。
アクセス修飾子が何なのか詳しく見ていきましょう。
アクセス修飾子とは
アクセス修飾子とは、どこからアクセスできるのかを指定するものです。
例えば、クラスの中にあるプロパティは、クラスの外からも使用できるのかといったアクセス権限に関する指定のことです。
アクセス修飾子は、下記の3種類があります。
種類 | 説明 |
---|---|
public | どこからでもアクセス可能 |
private | クラス内のみからアクセス可能 |
protected | クラス内とそのクラスを継承した子クラスからアクセス可能 |
説明の中で「クラスを継承した子クラス」とありますが、後ほど説明しますので今はそんなのがあるということだけ覚えておいてください。
ちなみにアクセス修飾子を指定しないと、publicの扱いになります。
アクセス修飾子を省略することも可能ですが、省略せずに明示した方が見たときにわかりやすくなります。
また、publicにする必要がない場合には、privateやprotectedを適切に指定してください。
ちなみに、PHP4ではアクセス修飾子はありません。
PHP4の環境でアクセス修飾子を明示して実行すると構文エラーが表示されます。
次はクラスを使うメリットを見ていきましょう。
クラスのメリット
クラスのメリットを知るには、クラスの概念を理解する必要があります。
クラスの概念を実世界に例えて理解していきましょう。
クラスは、実世界で例えると設計書にあたります。
車の設計書があれば、車をいくつも作成することが可能です。
設計書から作成された車のことを、プログラムの世界ではインスタンスと呼びます。
設計書から車を作成することを、プログラムの世界ではインスタンス化と呼びます。
新しい用語がでてきましたが、図を見るとイメージできるかと思います。
車の設計書(クラス)があれば、いくつも車(インスタンス)を作成することが可能です。
言い換えれば、クラスがあれば、いくつもインスタンスを容易に作成できます。
これがクラスを使うメリットの一つです。
次はクラスからインスタンスを作成する構文を見ていきましょう。
クラスからインスタンスを作成する構文
先ほど、車の設計書(クラス)から車(インスタンス)を作成すると説明しました。
実際にインスタンスを作成する構文を見ていきましょう。
$変数名 = new クラス名(引数)
new演算子の後にクラス名を記述してインスタンスを作成しています。
作成したインスタンスを変数に代入しています。
インスタンスは、基本的に変数に代入して使うようになります。
現時点では、「代入して使う」ということがわからないと思いますが後ほど説明します。
実際にインスタンス化してみる
頭の中を整理するために、実際にクラスを作成してインスタンス化してみたいと思います。
// クラスを作成
class Car {
public function drive() {
echo '走ります';
}
}
// インスタンスを作成(インスタンス化)
$prius = new Car();
Carクラスを作成した後に変数($prius
)にインスタンスを作成して代入してます。
ここまでは、今までのおさらいなので記述してあるコードの意味はわかるかと思います。
ただ、実行結果がどのようになるのかわかりますか?
コードを見るとecho '走ります'
と書いてあるので走ります
と画面に表示されるかと思いますが、実際には何も表示されません。
上記の記述では、まだCarクラスのインスタンスを作成して$prius
に代入しただけです。
走ります
と表示させるには、代入したインスタンスのdriveメソッドにアクセスする必要があります。
先ほど「インスタンスは変数に代入して使う」と説明しました。
変数$prius
にインスタンスが代入されています。
変数に代入されているインスタンスのメソッドにアクセスするようになります。
代入されたインスタンスプロパティまたはインスタンスメソッドにアクセスするには、アロー演算子を使用します。
アロー演算子とは
インスタンスのプロパティやメソッドにアクセスするには、アロー演算子と呼ばれれる ->
を使います。
$インスタンスを代入した変数名->呼び出したいインスタンスのプロパティまたはメソッド名
先ほどのコードを使い、インスタンスのdriveメソッドへアクセスしてみます。
// Carクラスを作成
class Car {
public function drive() {
echo '走ります';
}
}
// インスタンスを作成(インスタンス化)
$prius = new Car();
// アロー演算子でインスタンスメソッドへアクセス
$prius->drive();
最後の一行を追記しました。
アロー演算子を使い、$prius
に代入したインスタンスにあるdriveメソッドを呼び出しています。
これを実行すると走ります
と表示されるようになります。
インスタンスのプロパティやメソッドを呼び出すには、アロー演算子を使うようになります。
先ほど、アクセス修飾子でアクセス権限を指定すると説明したのを覚えていますか。
アクセス修飾子のpublic
を指定すれば、クラスの外からでもアクセスできるはずですよね?
このアロー演算子は、インスタンスのプロパティとメソッドを呼び出すのに使います。
そうなると、インスタンス化しないとプロパティとメソッドにアクセスできなくなりますね。
単純にクラスのプロパティやメソッドにアクセスするには、スコープ定義演算子を使います。
スコープ定義演算子とは
クラスのプロパティやメソッドにアクセスするには、スコープ定義演算子と呼ばれる ::
を使います。
クラス名::呼び出したいクラスのプロパティまたはメソッド名
早速、スコープ定義演算子を使ってアクセスできるか確認したいところですが、その前にクラスのプロパティとメソッドとインスタンスのプロパティとメソッドの違いについて見ていきましょう。
##クラスのプロパティとメソッドについて
今まで普通にクラスのプロパティとメソッド、インスタンスのプロパティとメソッドと説明してきましたが、どれがクラスのプロパティで、どれがインスタンスのプロパティなのか区別できないですよね。
普通にクラス内に記述したプロパティやメソッドはインスタンスのプロパティやメソッドです。
では、クラスのプロパティとメソッドにするためにはどうすればよいのか。
クラスのプロパティまたはメソッドにするには、static
という修飾子を付与する必要があります。
プロパティであれば、プロパティ名の前にstatic
を記述します。
メソッドであれば、function
の前にstatic
を記述します。
staticのあり・なしでクラスなのか、インスタンスなのか区別できます。
下記のコードでどれがクラスのプロパティまたはメソッドかわかりますよね。
class クラス名 {
// No.1
アクセス修飾子 static $プロパティ名;
// No.2
アクセス修飾子 $プロパティ名;
// No.3
アクセス修飾子 static function メソッド名(引数) {
//処理を記述
}
// No.4
アクセス修飾子 function メソッド名(引数) {
//処理を記述
}
}
static
があるNo.1は、クラスのプロパティです。
No.3にもstatic
があります。これはクラスのメソッドです。
No.2とNo.4にはstatic
がないため、インスタンスのプロパティとメソッドになります。
No.1とNo.3は、クラスのプロパティとメソッドになるため、インスタンス化しなくてもアクセスできます。
No.2とNo.4はインスタンスのプロパティとメソッドになるため、インスタンス化しないとアクセスできないということになります。
ここで、staticについてPHPマニュアルの説明を見ていきましょう。
クラスプロパティもしくはメソッドを static として宣言することで、 クラスのインスタンス化の必要なしにアクセスすることができます。 static なプロパティは、インスタンス化されたクラスオブジェクトから アクセスすることはできません (static なメソッドにはアクセスできます)。
理解力のない私は最初この説明をみたときに、static を宣言することで public と同じような意味になるのかと勘違いしました。
static と public の違いを見ていきましょう。
staticの意味は?staticとpublicの違いは?
PHPマニュアルの説明をみて「publicを宣言すれば、インスタンス化しなくてもアクセスできるのにstaticを宣言する意味がないのでは?」と疑問に思った方もいるかと思います。
もしかしたら、私だけですかね(・ω・`;)
まず、「publicを宣言すれば、インスタンス化しなくてもアクセスできる」というのは誤りです。
publicだけ宣言しても、インスタンス化しなければアクセスできません。
staticを宣言することで、クラスに属したプロパティまたはメソッドになります。
クラスに属したプロパティまたはメソッドのためインスタンス化しなくてもアクセスできるようになります。
逆にstaticを宣言していないプロパティまたはメソッドはインスタンスに属します。
なので、publicだけ宣言しても、インスタンス化しなければアクセスできません。
staticを指定することで、クラスに属し、publicを指定することで、クラスの外からアクセスできるようになります。
publicはあくまでもアクセス修飾子であり、どこからアクセスできるかを指定するものです。
staticはクラスに属するかを指定するものであり、publicとは別物です。
staticがあるプロパティを静的プロパティと呼び、staticがあるメソッドを静的メソッドと呼びます。
今までクラスのプロパティ、クラスのメソッドと呼んでいましたが、静的プロパティと静的メソッドへ名称を統一します。
以降、下記の言葉で説明しますので覚えてください。
プロパティ | メソッド | |
---|---|---|
staticあり | 静的プロパティ※1 | 静的メソッド※2 |
staticなし | インスタンスプロパティ | インスタンスメソッド |
※1 今までクラスのプロパティと表記していましたが静的プロパティへ統一
※2 今までクラスのメソッドと表記していましたが静的メソッドへ統一
アロー演算子とスコープ定義演算子の使い分け
前にアロー演算子とスコープ定義演算子の使い方を説明したのを覚えているでしょうか。
いろいろな言葉がでてきたので、忘れている方もいるかと思います。
頭の中を整理するため、もう一度アロー演算子とスコープ定義演算子の使い分けを見ていきましょう。
種類 | アクセス方法 |
---|---|
静的プロパティ、静的メソッド | :: |
インスタンスプロパティ、インスタンスメソッド | -> |
クラスの静的プロパティまたは静的メソッドへアクセスするときは、スコープ定義演算子 (::
)を使用します。
インスタンスのプロパティまたはメソッドへアクセスするときは、**アロー演算子(->
)**を使用します。
クラスに属している場合はスコープ定義演算子を使い、インスタンスに属している場合はアロー演算子を使うだけの2パターンしかないので簡単ですね。
次は静的プロパティと静的メソッドへアクセスしてみましょう。
実際に静的プロパティ・静的メソッドへアクセスしてみる
静的かどうかは、staticのあり・なしで判断します。
staticがあれば静的プロパティもしくは静的メソッドで、staticがなければインスタンスプロパティもしくはインスタンスメソッドになります。
下記のコードを基に外部からTestクラスの静的プロパティ、静的メソッドへアクセスしてみましょう。
class Test {
// No.1 静的プロパティ
public static $a = 8;
// No.2 静的メソッド
public static function sum($b,$c) {
echo $b + $c;
}
// No.3 インスタンスプロパティ
public $d = 9;
// No.4 インスタンスメソッド
public function count() {
static $e = 0;
echo $e;
$e++;
}
// No.5 インスタンスメソッド
public function division($f,$g) {
echo $f / $g;
}
}
先ほど説明しましたが、静的プロパティと静的メソッドへアクセスするにはスコープ定義演算子(::
)を使います。
No.1の静的プロパティとNo.2の静的メソッドへアクセスしてみます。
class Test {
// No.1 静的プロパティ
public static $a = 8;
// No.2 静的メソッド
public static function sum($b,$c) {
echo $b + $c;
}
// No.3 インスタンスプロパティ
public $d = 9;
// No.4 インスタンスメソッド
public function count() {
static $e = 0;
echo $e;
$e++;
}
// No.5 インスタンスメソッド
public function division($f,$g) {
echo $f / $g;
}
}
// No.1 静的プロパティへアクセス
echo Test::$a;
// No.2 静的メソッドへアクセス
Test::sum(2,3);
echo Test::$a;
と Test::sum(2,3);
の命令を追加しています。
PHPのバージョン別の実行結果をご覧ください。
実行結果を見ていただくとわかりますが、PHP5では実行結果が表示されています。
PHP4には public
などのアクセス修飾子がありませんので、上記のコードは構文エラーになっています。
この記事を読んでいる方でPHP4の環境を使っている方は、いないと思いますのでスルーします。
スコープ定義演算子を使い、外部から静的プロパティと静的メソッドへアクセスできました。
インスタンスプロパティとインスタンスメソッドへアクセスするには、インスタンス化する必要があります。
あたりまえですが、インスタンス化せずにインスタンスメソッドへアクセスすることは通常できません。
しかし、下位互換性のためにスコープ定義演算子を使ってインスタンスメソッドへアクセスできるようになっています。
通常このようなアクセスはさけるべきですが、インスタンスメソッドへアクセスしてみます。
class Test {
// No.4 インスタンスメソッド
public function count() {
static $e = 0;
echo $e;
$e++;
}
// No.5 インスタンスメソッド
public function division($f,$g) {
echo $f / $g;
}
}
// No.4 インスタンスメソッドへアクセス
Test::count();
// No.5 インスタンスメソッドへアクセス
Test::division(4,2);
PHPのバージョン別の実行結果を見てください。
PHP5ではStrict Standards: Non-static method Test::count()
とStrict Standards: Non-static method Test::division()
が表示されますが、実行結果の0
と2
も表示されます。
Strict Standards: Non-static method
の意味は、「厳しく言えばstaticのないメソッド(インスタンスメソッド)へアクセスするべきではない」ということです。
アクセス修飾子を記述しているため、PHP4では構文エラーになっていますが、アクセス修飾子を外せば問題なく実行されます。
しつこいですが、スコープ定義演算子を使ってインスタンスメソッドへアクセスできますが、このようなアクセスはしないようにしましょう。
次は、インスタンス化するときに実行される特別なメソッドを見ていきましょう。
インスタンス化するときに実行される特別なメソッド
new演算子でインスタンス化するときに実行される特別なメソッドのことをコンストラクタと呼びます。
メソッド名に__construct()
と記述することで、定義することができます。
class クラス名 {
function __construct(引数) {
//処理
}
}
最初に説明しましたが、コンストラクタはインスタンス化するタイミングで実行されます。
インスタンス化するタイミングで実行されるため、コンストラクタはプロパティを初期化するときなどに使われます。
PDOでデータベースに接続するときにも、PDOクラスのコンストラクタの引数にデータベースの情報を記述してデータベースに接続しますのでコンストラクタについて覚えておいてください。
ちなみにPHP4ではクラス名と同じメソッド名にすることでコンストラクタとして機能します。
PHP5でも下位互換のために動作しますが、PHP5以上では__construct()
と記述しましょう。
インスタンス自身を指す特別な変数($this
)
インスタンス自身を指す$this
という特別な変数があります。
インスタンス自身を指しますので、インスタンスメソッドの中でしか使えません。
静的メソッドの中では$this
は使えませんので注意してください。
メソッドを作る上で、インスタンス自身を指したいときは多々あります。
例えば、下記のようなCarクラスを作成して、走行するdriveメソッドと走行した距離を返すgetKmメソッドを記述したとします。
$this
は使わずに記述してみます。
class Car {
private $km = 0;
public function drive($distance) {
$km += $distance;
}
public function getKm() {
return $km;
}
}
上記の記述で、インスタンス化してgetKmメソッドにアクセスすると、$km
という変数が定義されていないとエラーが表示されます。
下記のように$this
を使ってインスタンスのプロパティであることを記述しなければいけません。
class Car {
private $km = 0;
public function drive($distance) {
$this->km += $distance;
}
public function getKm() {
return $this->km;
}
}
ここで注意したいのが$this->km
の記述です。
プロパティ名は$km
なので$this->$km
かと思いますが、$
の記述はなく、$this->km
となりますので注意してください。
実際にクラスを作り、インスタンス化してみる
実際に車のクラスを作成して、走らせてみましょう。
// No1.車クラスを作成
class Car {
private $km = 0;
public function drive($distance) {
$this->km += $distance;
}
public function getKm() {
return $this->km;
}
}
// No2.インスタンス化して変数priusに代入
$prius = new Car();
// No3.インスタンスのdriveメソッドへアクセスして引数に80を指定
$prius->drive(80);
// No4.同じくインスタンスのdriveメソッドへアクセスして引数に20を指定
$prius->drive(20);
// No5.インスタンスのgetKmメソッドへアクセスして走行距離を出力
print $prius->getKm();
// No6.インスタンス化して変数corollaに代入
$corolla = new Car();
// No7.インスタンスのdriveメソッドへアクセスして引数に50を指定
$corolla->drive(50);
// No8.インスタンスのgetKmメソッドへアクセスして走行距離を出力
print $corolla->getKm();
No5のprint $prius->getKm();
では、何の数字が出力されるかわかりますか?
No3の処理で$km
の変数に20が足されています。
No4の処理で$km
の変数に80が足されています。
No5では合計である100が表示されます。
今までの説明があれば、それぞれ何をしているかわかるかわかったと思います。
上記ではCarというクラスを新たに作成しました。
実は、作成したクラスを基に新しいクラスを作成することができます。
次は、クラスの継承について見ていきましょう。
クラスの継承
Aというクラスを基にしてBという新しいクラスを作成することができます。
基となるクラスの変数や関数を引き継いで新しいクラスを定義することを継承と呼びます。
基になるクラスを親クラスと呼び、継承したクラスを子クラスと呼びます。
class クラス名 extends 親クラス {
}
親クラスと子クラスのことをスーパークラスとサブクラスと呼ぶこともあります。
スーパークラスやサブクラスという名称もよく使われるので覚えておきましょう。
この記事では、親クラス・子クラスという名称で記載します。
名称 | 別の名称 |
---|---|
親クラス | スーパークラス |
子クラス | サブクラス |
継承における親子関係
他のクラスを継承して新しいクラスを作れることがわかりました。
次に、親クラスと子クラスの関係を見ていきましょう。
まず、PHPでは親クラスを複数指定する継承(多重継承)は認められておりません。
親クラスは、ひとつだけ継承(単一継承)することができます。
そして親子の関係ですが、子クラスは親クラスの変数や関数を引き継いでいます。
逆に親クラスは子クラスの変数や関数を引き継ぐことはありません。
親クラス、子クラスという名前のとおり、無関係なクラスを親子関係にしない方が無難です。
is-a関係が成り立つときに継承するのが望ましいとされています。
is-a関係とは、子クラス is a 親クラスが成り立つ関係です。
日本語にすると、子クラスは親クラスですという意味になります。
例えば、「Windows is a OS」であれば、「WindowsはOSです」とis-a関係が成り立ちます。
継承は、このような関係が成り立つときに利用するのが望ましいとされています。
次で第1章のクラスは終わりです。
最後は「オブジェクト」について見ていきましょう。
最後に「オブジェクト」とは
クラスを理解するのに、オブジェクトという言葉は欠かせません。
クラスについてググったり、書籍を見るとオブジェクトという言葉が使われているかと思います。
しかし、今までオブジェクトという言葉をあえて使いませんでした。
なぜかと言うと、オブジェクトという言葉を使わなくても説明できるし、いろいろな言葉を使うと理解し難いと思ったからです。
ひと通り覚えてから、オブジェクトについて学べばいいかと思います。
正直、オブジェクトについて私もよくわかりません。
オブジェクトについてググってみましたが、オブジェクトの定義がよくわかりません。
人によっては、クラスやインスタンスなど含めた全体をオブジェクトと呼んだり、
クラスのことをオブジェクトと呼んだり、
インスタンスのことをオブジェクトと呼んだり、
何がオブジェクトかわかりません(・ω・`;)
ただ、オブジェクトの定義は、全体かクラスかインスタンスかのいずれかを指すことが多いです。
なのでオブジェクトと言われたときには、どこを指しているのか考え、一番適切な箇所に置き換えるようにしています。
個人的にオブジェクトというのはインスタンスを指すことが多いかなという印象です。
以降もオブジェクトという言葉は使いません。
オブジェクトについて知りたい方は、ググってください。
これで、クラスの基礎については、理解できたかと思います。
次は、例外処理を見ていきましょう。
続きは Zenn で閲覧できます。
今まで無料で公開しておりましたが、記事を有料化しました。
2021 年 9 月 7 日 300 円
※ 理解して記事にまとめるのに数百時間を費やしているので、300 円以上の価値はあると思います。