PHPで学んだ基本についての備忘録を共有したい。配列、Foreach文、コロン文、関数、戻り値、クラス、インスタンス、コントラクタ、アクセス権、Static、継承、Override、抽象化、インターフェース、オブジェクト指向、データベースへの接続などについて記述した。
項目ごとにまとめてあるが、一つのページに載せていて長文になっているので、「command + F」でワードを検索して閲覧してほしい。理解するまでの流れをできる限り噛み砕いてそのまま表現しているので、上級者が書いたスッキリした文章で理解ができない人には良いかもしれない。
基本的な名称など
ビルトインサーバー
PHPに備わっている簡易的に使えるWebサーバーのこと。ローカル開発環境において、コマンド一発で簡単にWebサーバーに接続して、動作確認ができるというもの。
接続するには、接続しようとしているローカル開発環境のIPアドレスが必要なので、ターミナルで「ip a」とコマンドを打つとIPアドレスが出てくるので、確認する。ビルトインサーバーの立ち上げは
「php -S IPアドレス:8000」
と、小文字の「php」とハイフン、そのあとの「S」は大文字で、それに続けてIPアドレス、そしてポート番号をつける。それでビルトインサーバーが立ち上がる。停止するには「control+C」。「http」から始まるアドレスがsターミナル上に表示されるので、それをブラウザにコピーすれば動作確認ができる。
定数の付け方
定数は変数と違い、変更しない値を固定するために使用するもの。定義するとその後に新しい値をつけようとしてもエラーになって出来ない。
「define("NAME_NUMBER_ONE", "suzuki");」
といったように、左に定数名(大文字で書くのが通常)を書き、右に値を入力する。「define」は定義するという意味の英語だから覚えやすい。変数とは違って「$」マークはつかない。
代入演算子
①$a = $a + 1;
②$a += 1;
二つの式の意味は同じ。
「+=」となっている②の式も「$a + 1」を$aに代入するという意味になる。「+」だけでなく「-」「*」「/」にも使える。
特殊文字
「\n」は改行
「 \」はタブ
文字列
PHPで文字列を表示する時は
「""」
「''」
の2種類のクオーテーションを使う。
ダブルクオーテーションは変数と特殊文字を適用させる。シングルクオーテーションは「\n」などの特殊文字でもそのまま「\n」という文字で表示する。
変数は波カッコで囲える
文字列の中に変数が混じっていると紛らわしかったりするので、変数は波カッコで囲うことができる。
{$animal}
${animal}
といった具合に全てを囲むのも、ドルマークだけ囲うこともできる。
比較演算子
「==」は値が等しい
「===」は値とデータの型も等しい
「!=」は値が等しくない
「!==」は値も型も等しくない
論理演算子
「and」「&&」は「〜かつ」と使える。
「or」「||」は「〜か」で使える。
「!」は否定で使える。
trueとfalse
どのような場合に「true」と判定され、どのような場合に「false」と判定されるか見てみる。
「false」は文字列が「空」か「0」、数値が「0」、配列の要素がなかった場合、「null」の時などの場合に判定される。それ以外は「true」となる。
三項演算子
三項演算子は、条件式の「true」「false」の結果によって、異なる式の結果を返す演算子。
$test = ($a > $b) ? $a : $b;
という式で考えてみる。
条件式が「true」であれば、赤字の「true」が適用されて「$test」には「$a」が代入される。条件式が「false」であれば「false」が適用されて「$test」には「$b」が代入される。
つまり
$a=2, $b=4
ならば「false」と判定されて「$test」には「$b」が代入されるということ。
定数
「define」で定義する。定数は一度定義すると値を変えることができない。変えようとするとエラーを弾いてくれる。大文字で定義するのが基本。
以下のページが見やすい。
基本構文と関数
Switchによる条件分岐
「if」と同じように条件分岐だが、変数の取り得るパターンがすでに決まっている場合にコードを綺麗に書くときなどに使うと便利。「if〜else」ではネストが深くなるときなどに使う。各条件は「case」で開始して「break」で閉じる。条件に当てはまらないのは「default」として、やはりその時のアクションを定義してあげる。例えば以下のようになる。caseの後の""内の文字が$timeにリンクしている。初めのケースならもし$timeが"morning"なら"good morning!!"となる。breakに至った時点で終了。
switch ($time){
case "morning":
echo "good morning!!";
break;
case "daytime":
case "early evening":
echo "good afternoon!!";
break;
case "night":
echo "good evening!!";
break;
default:
echo "(sleeping...)";
break;
}
一つの条件で「case」は赤字のように複数定義できる。
ループ処理
While文
「〜である間」指定した処理を続けると覚えるといい。先に判定して「true」であれば処理が実行される。変数の初期化、処理が終わる条件、処理を書いていく。
Do While文
処理が先に来て、それからWhileによって判定される式。あと判定なので少なくとも一回は処理される。変数の初期化、処理、処理が終わる条件を書いていく。
For文
While文と同じような役割だが、繰り返す回数がわかっているときなど単純な反復処理のときなどに使われるよう。
Break文
ループを途中で中断して抜ける処理になる。「if」などを使い「〜の場合にはループを抜ける」といったように処理をコントロールできる。
Continue文
「continue」文の後の処理を実行しないで、次のループに移る時に使う。やはり「if」などで条件を指定して使うよう。
配列
変数には値を一つしか格納できないが、二つ以上の情報をまとめて管理したい時には配列を使う。変数の箱が連なっているようなイメージ。
$salary = array(
"suzuki" => 20,
"sato" => 30,
"tanaka" => 40,
);
もしくは「array」の代わりに[ ]を使って
$salary = [
"suzuki" => 20,
"sato" => 30,
"tanaka" => 40,
];
とすることもできる。値を取り出すときは、
echo $salary["suzuki"];
とすると「suzuki」さんの給料が「40」といったように表示される。
値を書き換えることもでき、
$salary["sato"] = 50;
とすれば「sato」さんの給料は50に変更される。
配列はデフォルトでゼロから番号が割り当てられるので、
$salary = [
20,
30,
40,
];
のようにすると、連番[0]の人が20、[1]の人が[30]、[2]の人が[40]といったようにデータが格納される。
echo $salary[0];
と[0]番が割り当てられた人の給料を知りたいとすると、「20」が表示される。
配列の要素
配列の要素とは、変数の箱が連なっている配列の一つ一つの変数のこと。配列の要素==変数ということ。変数が配列になっている時には、変数が配列の要素と呼ばれるということ。
配列の添字
配列は変数が連なっているものの集合なので、配列の要素(変数)にそれぞれ割り当てられた番号が配列の添字。配列の一つめは「0」になる。
連想配列
添字に好きな名前をつけられる配列を連想配列という。名前をつけることで変数の中身が連想できる、と覚えると覚えやすい。
https://wa3.i-3-i.info/word11931.html
このページが圧倒的にわかりやすい。
多次元配列
配列の中に配列が入っている配列。
結果はこうなる。
$array[ ][ ]となっているが、初めの[ ]で何番目かの配列かを指定して、次の[ ]でその指定した配列の何番目かを指定している。
Foreach文
配列の中身をループで取り出す処理。「$salary」の中身をなくなるまで引っ張り出してくれる。
$salary = [
"suzuki" => 20,
"sato" => 30,
"tanaka" => 40,
];
例えばこのように定義していたなら、
foreach ($salary as $name => $amount) {
echo"($name) $amount";
}
とすると、「"suzuki"」などの値を「$name」という変数に入れて、「20」などの値を「$amount」という変数に入れて、処理を実行(この場合はecho)してください、という事になる。
この場合は、
(suzuki)20(sato)30(tanaka)40
と表示される。
また、
$salary = [
20,
30,
40,
];
と定義していたら、
foreach ($salary as $amount) {
echo "$amount ";
}
と取り出す命令を書くことで、
20 30 40
と表示される。
コロン文
foreach文の波カッコを「:」で代用する式。波カッコが取れることで、すっきりとした構文にすることができる。
foreach ($salary as $amount) {
echo "$amount ";
}
のforeach文を、
foreach ($salary as $amount) :
echo "$amount ";
endforeach;
と違う書き方で同じ命令を出すことができる。最後に「endforeach」をつける。
関数
処理をひとまとめにして定義しておいたもの。グローバル関数(PHPが元から定義している)ものとローカル関数(自分で定義する)がある。よく使う処理なんかを登録しておいて、呼び出して使うことができる便利なもの。
functionでローカル関数を定義できる。
function kyuuryou_keisan( ) {
echo 1*30;
}
処理は波カッコの後だ。1に30をかけて30になるという単純な式。kyuuryou_keisanが関数名。
この関数を呼び出すには、
kyuuryou_keisan( );
と書く。当然「30」と表示される。
また、値に引数を渡す処理をした状態で関数を作り、引数を指定して関数を呼び出すと、
function kyuuryou_keisan($name ) {
echo $name . "さんの給料は" . 1*30 . "です";
}
kyuuryou_keisan("sato");
などと書ける。関数の定義の時に指定した変数「$name」は、関数の中で使用することができる。関数を呼び出す時に「"sato"」といった引数を渡してあげる。呼び出し結果は、
「satoさんの給料は30です」
となる。
また、引数に初期値を指定することもできる。
function kyuuryou_keisan($name = "suzuki" ) {
echo $name . "さんの給料は" . 1*30 . "です";
}
kyuuryou_keisan( );
となり、引数が空欄で呼び出されているので、「"suzuki"」が「$name」に代入される。
ハッシュ関数
まず、ハッシュの意味を。ハッシュは「ごちゃ混ぜ」などといった意味。ハッシュドビーフは細切れの牛肉を使うから名前がついた。ハッシュするというのはごちゃ混ぜにするということで、パスワードの暗号化などに使われる。ユーザーが入力した任意の長さのパスワードが、固定された長さの規則性のない値に置き換えることをハッシュするという。ハッシュ化されて暗号化された固定長の値から、元のパスワードを取り出すのは困難であるので、パスワードの暗号化に使われている。
ハッシュ関数は、入力した値から長さの決まった他の値を返してくれる関数のこと。Aを入力したらAが暗号化されて他の値を返して、Bが入力されればAとは違う他の値がそれぞれ返される。同じ値を入力すれば常に同じ値が得られる。ハッシュ関数はたくさん種類がある。
md5
ハッシュ関数の一つ。何かを入れると長さが128ビットの入れたものに応じた値を返してくれる。
password_hash
強力な一方向アルゴリズムを使ってハッシュする関数。PHPの公式の見解では、「md5」よりもこちらを推奨している。
return
returnを使用することで、返り値を取得することができる。また、制御を呼び出し元に戻すことができる。
関数一覧
isset
変数が入っているか確認する関数。例えば、
if(isset($a)==true)
{
print $a;
}
if(isset($a)==false)
{
print "値が入っていません";
}
といった感じ。
変数が空ならfalseで中身があればtrueを返す。「空ですよ」という意味の「" "」が変数に入っていれば、これはtrueとして扱われる。NULLでもfalse。
header
ファイルを取得したり、リダイレクトできる関数。リダイレクトでは、
header('Location: リダイレクト先');
のように命令をだす。
preg_match
指定した正しい表記に文字列がマッチしているか検査する関数。マッチしていれば「1」を返し、マッチしていなければ「0」を返す。エラー発生時には「False」を返す。
あまりいい例ではないが、とりあえず書いてみた。
2行目の'PHP'のところに正規表現パターンが来て、そのあとの$phpのところに検査対象が来る。検査対象が正規表現パターンと一致していれば「1」を返すので、条件は成り立ち「マッチしました」と実行結果がでる。正規表現はややこしいので、とりあえず飛ばす。
move_uploaded_file
アップロードされたファイルを新しい場所に移動させる関数。
move_uploaded_file(移動元, 移動先);
このように使う。
$_FILESで取得したファイルは一時的に他の場所に移される(アップロードされる)ので、そのファイルを指定して飛ばしたい先を指定する。一時保管されたアップロードされたファイルは名前も変わるので、「移動先」のフォルダにファイル名をくっつけてこの関数を使うと名前を元に戻せる。
input type="file"にすると、ユーザーに写真などをアップロードしてもらうことができる。そのアップロードされたファイルを$_FILESで受け取って、サーバーが一時保管して、move_uploaded_fileの命令で、指定したフォルダに格納して管理することができる。
unlink
指定したファイルを削除する。
これなら、このコードを書いているファイルと同じ階層のフォルダ内にある「image」フォルダの中の、「$image_name」という変数にいれられたファイル名のファイルを削除するということになる。
fgets
ファイルポインタから1行取り出す。ファイルポインタとは、ファイルの中でどこが対象になっているかを示すもの。テキストファイルなら、点滅して示される。
「STDIN」は標準入力。キーボードからの入力に該当する。
range
範囲を指定して配列を作成する関数。
カッコ内は(開始値、終了値、増減値)となる。
この場合は2から6の間で2ずつ増えて配列を作成する命令なので、
実行結果はこのようになる。
最後の増減値は指定しないと1単位ずつ増加する。
array_slice
配列の指定した位置から要素を取得する。
カッコ内は(配列、配列の位置、取得数)を表している。この場合は$strという配列のKeyが[2]の位置から2つの要素を取得することを命令している。
実行結果はこのようになる。
取得数を指定しないと最後まで取得する。
sprintf
フォーマットを作成し、そのフォーマットに引数を指定して返す関数。
「%s」には文字が入り、「%d」には数字が入る。
引数は「%s」と「%d」の数だけ、その順番通りに指定すればいい。
変数
グローバル変数
$_GET
PHPでフォームからデータを受け取る時に使用するグローバル変数。
$_GET[' ']
として、受け取りたい値の「name」属性を入力することで、受け取ることができる。
HTMLのフォームでmethod="get"にすると、フォームに入力したデータが飛び先のURLの後に「?」を開始として追加される。
このような感じ。データがURLで引き渡されるのが$_GETとなる。URLにデータが表示されてしまうので、データが報時されてもいいものだけ$_GETで取得する。
フォームでなくとも、URLの最後に「?」で始まるアドレスを追加しても、$_GETで送っていることになる。その場合も、飛び先で$_GET[' ']で受け取ることが可能。
$_POST
POSTメソッドで送られた値を取得する変数。HTMLの「form」タグで「method」を「POST」にすることで$_POSTに値を飛ばせる。「input type」で指定した「name」で値を指定できる。
$_POSTは連想配列として使用する。つまり、
$_POST['username']
という形でHTMLで飛ばされた「username」を$_POSTで取得できる。連想配列なので[ ]内に取得したい値を指定する必要がある。つまり、$_POSTという連想配列に、配列の添字である変数がたくさん連なっていて、どの変数を指定するのかを[ ]で示す必要があるということ。
$_SESSION
セッションとはコンピュータのサーバ側に一時的にデータを保存する仕組み。$_COOKIEとは異なり、クッキーはブラウザにデータを一時的に保存する仕組み。クッキーはブラウザ側に保存されるので、セッションの方がセキュリティ的に安全。普通の変数では、画面が遷移したら情報が消えるが、スーパーグローバル変数なので、どのページからもデータを取り出すことができる。
session_start();
という関数を使うことで、パソコン側のクッキーとサーバが同じセッションIDを記憶することができる。このセッションIDがユーザーとサーバーの間で交わされる合言葉になる。この行為がログインになる。そもそもログインは、サーバに登録してある名前とパスワードと入力内容が一致したときに「if」の「true」でsession_start( )へユーザーを送り、セッションIDを共有することでログインが可能となる。ここでは「staff_login_check.php」のコードがそうなっている。
セッションIDを保持している状態だと$_SESSIONに格納されたデータを扱うことができるようになる。つまりログインされたユーザーだけが閲覧できるページを設定することができる。ログインすることで、$_SESSIONに格納したデータをやりとりする権限が与えられる。このセッションIDを破棄する行為をログアウトという。
ログインが成立したときは
$_SESSION['login'] = 1;
と書いたりする。これは別に['login']でなくてもいいが、例えば1という値を「login」という名前に格納することでisset関数などで「true」「false」で判定したときにログインの証拠になる。
if(isset($_SESSION['login'])==false)
{
print'ログインされていない状態です。<br/>'
}
といったように、認証が必要な全てのページの頭につけることで判定して、ログインしていないユーザーをブロックできる。
phpの頭にsession_start( )と書くことで、サーバーが「セッションを開始しましょう、セッションIDを確認させてください」とユーザーに言っている。次の行で書かれているsession_regenerate_id(true)というのは、セキュリティのために毎回セッションIDを変更するためのコード。
$_COOKIE
setcookieという関数を使用してパソコンのブラウザに一時的に保存されたデータを受け取るためのスーパーグローバル変数。
setcookieで送信と削除する
setcookie('名前', '値', 有効期限, 'パス', 'ドメイン');
名前と値は必須。有効期限は書かないとブラウザを閉じるまでが有効期限になる。
パスはクッキー有効としたいパスを設定することができる。「'/'」と記述すると、クッキーはコードを記述しているそのドメイン配下の全てで有効になる。「'/staff/'」とディレクトリを指定することもでき、その場合はそのディレクトリと配下のサブディレクトリでクッキーが有効になる。
ドメインは対象となるドメインを指定する。
例:setcookie('staff_name', 'suzuki', time()+60*60*24*7, '/', 'www.example.com');
上記のクッキーを取り出すときには$_COOKIEを使う。
echo $_COOKIE['staff_name'];
といったように書くと、「suzuki」が受け取れる。
削除するときにはtime()-とマイナスにすれば削除ができる。
セッションの破棄
3行目では$_SESSIONを空にしている。
4〜6行目では、クッキー情報があればそれを破棄する命令を書いている。
8行目でセッションIDを破棄している。
$_FILES
アップロードしたファイルを受け取るグローバル変数。連想配列として使用する。$_POSTのファイル版と覚えればいい。
5種類のデータを格納する。
- ['name'] ファイル名
- ['type'] ファイルのMINEタイプ(転送するドキュメントの種類)
- ['tmp_name'] 仮にアップロードされている画像の一時保管場所
- ['error'] アップロード時のエラーコード
- ['size'] 画像サイズ(単位はバイト)
$_FILESでファイルを取得した時点で、飛び先に行く前に['tmp_name']に一時保管される。一時保管された時は、サーバーによって勝手にファイル名が変えられる。
戻り値
「return」という処理によって返される値のことを「戻り値」という。
「return」は関数内に存在すると、その「return」に到達した時点で、その関数の処理を停止させて、関数の値を返す処理を行うという命令のこと。
「function」は関数を作るための命令。
「kakezan」は今回私が作った関数の関数名。
「$num」は引数を受けるための変数。
「echo」の後の「3」が変数に渡す引数。
この実行結果は「9」になる。
今回の引数「3」をおにぎりの具で例えて梅干しとすると、出来上がる梅おにぎりが戻り値となる。その完成した梅おにぎり(戻り値)を関数に返す命令が「return」となる。
今度の実行結果は「36」になる。今回は引数を「3」の代わりに「6」にした。
赤字の1番の流れで「6」という引数(鮭)を関数(弁当屋で働く職人)に渡して、その「6」という引数(鮭)を使って2番の流れで実行式(ご飯)に混ぜて使うことで戻り値(鮭おにぎり)が完成して処理(調理)が終了し、3番の流れで関数(弁当屋)に戻ってくる、といったようなイメージ。
オブジェクト指向
概念
クラスはあらかじめ関数など処理が用意されている「金型」と覚える。その便利な「金型」に名前をつけて使ったりする。クラス内には「プロパティ」と呼ばれる「その金型の特徴」と、「メソッド」と呼ばれる「できること」、という考え方がある。プロパティはクラス内の「変数」であり、メソッドはクラス内の「関数」である。そのクラスという便利な金型には当然特徴があって、何ができるかもその金型によって違うということだ。その便利な金型をコピーして物を作っていくことを「インスタンスを生成する」というように表現する。インスタンスとは「実体」「実例」「事例」といった意味だ。クラスが「金型」や「設計図」であるならば、インスタンスはその「実体」とでも表現できる。一方、オブジェクトは「モノ」や「事柄」を指す言葉。だから「金型である」クラスも、その「実体」であるインスタンスもオブジェクトとなる。しかし、全てのインスタンスはクラスから作られるので、インスタンスされたものをオブジェクトと呼んでいる。クラスは金型でしかないので、それ自体を使うことはできないので、コピーして使う必要がある。まずは金型であるクラスを作ってから、それをベースにしてインスタンス化することで、オブジェクトを作っていく。
オブジェクト指向の理解を助ける用語
オブジェクト指向を理解する上で、知っておく必要がある用語をまとめたので備忘録として載せる。
オブジェクト指向プログラミング(OOP)
オブジェクト指向を利用するのは楽に開発を進めるため。ソフトウェアを再利用しやすくする技術。部品の独立性を考えることで、エラーの特定や、修正もしやすく、個々を組み合わせて全体を機能させるという考え方。
クラスライブラリ
ソフトウェアの再利用部品群
フレームワーク
ソフトウェアの再利用部品群
デザインパターン
再利用部品群を作る時に用いられるおきまりの設計パターン
UML(Unified Modeling Language)
統一モデリング言語。OOPの仕組みを使うソフトウェア構造を図で表したもの。
上流工程
業務分析、要求定義、設計といった初期の段階
モデリング
OOPを上流工程に応用すること
クラス
Object(モノ)の種類を指す。インスタンスを生成するのに必要な「金型」。変数と関数により独立性の高い部品を作る金型。部品を作るためのものだが、できるかぎり大きな部品を作り、簡単に製品(プログラム)を作ることを念頭に置かれている。大きな部品でシンプルに大量生産するための仕組み。バラバラの関数と変数を整理整頓するためのもの。「private」「public」などでアクセスの範囲を指定できる。
ポリモーフィズム
英語で多形、多型という意味。命令先が、どのクラスのインスタンスかを意識しないで命令を送れる仕組みのこと。同じ一つの命令で、異なる複数のインスタンスに動作させることができる。例えば、「進め」と命令した時に、「人間クラス」なら歩くし、「車クラス」ならエンジンで進む、といったように同じ命令で全く異なる性質のものに命令を送れる。「人間クラス」と「車クラス」は違うクラスだけど、同じ「進め」というメソッドで、それぞれ異なった動きをさせることができる。クラスはインスタンスを生成して、そのインスタンスに共通の機能を効率的に分散させるが、ポリモーフィズムは、複数のクラスから生成された複数のインスタンス同士共通の関数とも言える。コードの重複を避けることができる。コードの無駄を減らせる。
このページがとても参考になった。
継承
クラスの特徴を引き継ぐこと。クラス同士の共通点と、相違点を整理することができる。コードの重複を避けることができる。コードの無駄を減らせる。
スーパークラス
哺乳類や爬虫類が集まった動物という「全体集合」を指す言葉。
サブクラス
全体集合を指すスーパークラスから想定的にみて、哺乳類や爬虫類などの部分集合を指す言葉。
サブルーチン
関数のこと。関数を呼び出す主のメインルーチンと対比してサブルーチンと呼ばれる。
ローカル変数
使える範囲が決まっている変数。関数内で定義した関数内でしか使えない。関数呼び出し時に作られて、抜ける時には破棄される。
グローバル変数
ローカル変数とは異なり、どこからでも参照や書き換えが可能な変数。基本的には使わない方向でコードを書いていきたい。なぜなら、どこでも使えて便利な一方、知らないうちに書き換えて他の関数に影響を与えてしまったりするから。変更したら、サブルーチンに影響を与えてしまっている可能性が出てくるので、確認しなくてはならなくなる。数が多いと大変なことになる。アプリの初めから最後まで全てで存在可能。
インスタンス変数
インスタンスから呼び出される、クラス内で定義される変数。ローカル変数とグローバル変数の良い部分を取り入れて考えられた変数。グローバル変数のように他の変数に影響を与えないためにアクセス範囲を指定できる。グローバル変数は、アプリに1個だけ存在するある変数だが、インスタンスは作れば作るほど、その変数領域を広げることができる。
値渡し
関数に変数を引数として渡す時にコピーしたものを渡すこと。コピーした変数を渡すので、呼び出し元の関数内の呼び出された関数内で変数の値が変更されても、呼び出し元には影響は与えない。使うことで関数の独立性を高めることができる。
参照渡し
関数に変数を引数として渡す時に、コピーしないで渡すこと。コピーしない変数を渡すので、呼び出し元の関数内の呼び出された関数内で変数の値が変更されると、呼び出し元の変数に影響を与えてしまう。使用はできるかぎり避けた方がいい。
ビット演算
2進数の0か1のビット単位で計算する方法のこと。
入れ子構造
関数の中に関数があるような入れ子の構造になっている状態。
ポインタ
アドレス変数とも呼ばれる。変数のアドレスを記憶する変数。
コンパイラ
機械語に翻訳する作業
GOTOレスプログラミング
(厄介だと言われる)GOTO文(プログラム内の指定された場所に無条件でジャンプする命令)を少なくするというプログラミングの考え方。スパゲッティコードを生み出す原因。
基本三構造
構造化プログラミングで提唱されたコードをわかりやすくしようという基本的な3つの構造のこと。
- 順次進行
- 条件分岐
- 繰り返し
プロパティ型指定
このページでPHPに関して情報が載っている。
パッケージ
クラスをまとめる仕組み。ディレクトリのように管理できて、クラスの名前の重複を避けることができる。「Composer」というパッケージ管理ツールなどを使用したりする。
責務(Responsibility)
ソフトウェアとしてのクラスの役割を決めること。どんな役割分担を担うのかという責務。
重複の排除
プログラムを書く際に、重複の見落としによる修正もれが起きやすくなる。
凝集度
個々の部品のまとまり具合を評価する尺度。これが高ければ高いほど優れたプログラム。 独立性。クラスで秘密を作れば作るほど独立性は高まる。分かりすい名前をつける。機能を盛り込み過ぎない。
結合度
部品間の結びつきの度合いを評価する尺度。これが低ければ低いほど優れたプログラム。
クラスの依存の循環
クラスの依存の循環は避ける。クラスのどれかに手をつけた場合、全て確認しなければならなくなるため。
ウォーターフォール型
計画、設計、プログラム、テスト、と順番に行い、「滝」という意味通りに前の工程には戻らないことをいう。作業手順を定めることで計画通りに進めることが主眼に置かれていた。早い段階で要求を確定することで、仕様変更を最小限に収める。
アジャイル開発
ウォーターフォール型とは対照的に、小さくリリースして段階的に作り上げていく方法。 反復をすることでリスクを最小限に留め、顧客やチームの協力を重視して変化への柔軟性が主眼に置かれている。リリース、顧客からのフィードバックというのを繰り返す。
SOA(Service Oriented Architecture)
サービス指向アーキテクチャ。システムを部品の集まりとしてみなす手法。
イテレーション
要求定義、設計、プログラミング、テストまでの一連の作業を反復すること。
リファクタリング
プログラムの動作を変えることなく、ソースコードを整理すること。
XP
エクストリームプログラミング。「コミュニケーション」「単純さ」「フィードバック」「勇気」を大切な4項目に掲げるプログラミング手法。勇気とは設計変更をする勇気のこと。どのような環境に置かれれば、最高のパフォーマンスができるかを考えられたことによって生まれた。XPの登場によりアジャイル開発が進んでいった。
CI(Continuous Integration)
継続的インテグレーション。インテグレーションは統合を意味する。コードを出荷できる状態を保ちながら品質を維持すること。メンバーのモジュールを定期的に結合テストしないと不整合が発見できない。継続的に結合することで、早期発見できる。
TDD(Test Driven Development)
テスト駆動開発。詳細設計、プログラミング、単体テストを一つのまとまった作業として捉える手法。確実に動くプログラムを作れて、フィードバックが早いのが特徴。
ビルド
ソースのコンパイルやライブラリのリンクを行い、実行可能なファイルを作成すること。
モジュール
他のものと組み合わせて使うことが想定された部品。
ロギング
機械に履歴を記録すること。
クラス一覧
DatePeriod
日付の期間とその間隔を指定するとforeach文でループで表示させることができるクラス。引数は
DatePeriod(
開始日時,
間隔,
終了日時);
の3つ。
このように書く。
これが実行結果。
なお、今回の書き方は、クラスの中にクラスで引数を定義する形となっている。
DateTime
日付と日時を表すクラス。
現在時刻は引数を指定しない。
以下が実行結果
時刻を指定する場合。
こちらは秒まで表示させた。
DateInterval
日付の間隔を表す。
5行めに引数を入れているのが確認できる。
この場合は5日と12時間感覚で取得する命令。
上が実行結果。
クラスの実装
とりあえず実際にコードを書いてみた。
以下が実行結果
まず、クラスを定義する。クラス名の初めは大文字にする。今回は「Human」としてみた。人種をイメージしてほしい。
波カッコの後にプロパティを定義する。プロパティはクラスの特徴を表すものなので、どんな人種がいるか知りたいところだ。今回のプロパティは「$country」と「$language」にした。国籍と言語がわかる。
この「Human」というクラスが「できること」として、名前と年齢を表示するという機能をつけてみた。それが「selectData」というメソッドだ。この金型をコピーすればもれなく付いてくる機能で、メンバーを管理するのに便利そうだ。
7行目では、「$this」というのが出てきたが、これは擬似変数と呼ばれるもの。何かと言うと、クラスを定義しているこの時点では「まだ新規登録されるオブジェクト(ここでは$number_1のこと)」が分からないから、とりあえずこの擬似変数を書いておくということ。「selectData」というメソッド(関数)を呼び出した時に、どのオブジェクトからアロー演算子で引っ張ってきたかがわかるので、このケースであれば「$this」は「$number_1」となっている。
クラスを定義しただけでは(ただの金型なので)何の役にも立たない。波カッコで閉じてクラスの定義を終えた後に、今度はインスタンス化してオブジェクトを作っていく。まずは、金型であるクラスで作る実体の名前を指定する。10行目では、「Human」クラスの「new」メンバーとして「$number_1」を作成した。世界の人種の「ゼッケン番号1番が日本」というイメージ。インスタンスを生成する場合は「new」を使う。
11行目を説明する。「$number_1->country」というものが意味することだ。これは、『「$number_1」という新しいメンバーの「country」という情報にアクセスするという行為』に「"japan"」を代入している、ということだ。「->」はアロー演算子と呼ばれ、左辺から右辺を取り出す演算子。「$number->country」で一括りと見るとわかりやすい。続く12行目の「language」も同じ処理だ。
14行目の処理を説明する。「Human」クラスの金型で生成した「number_1」という新しいオブジェクトが「 Human」から得た能力であるメソッド(関数)を持っているが、それに「->」でアクセスして関数を実行していることを示している。
コンストラクタを作る
「construct」という命令をクラス内で書いておくことで、作業を簡略化することができる。特別なメソッド(関数)でマジックメソッドとも呼ばれる。「construct」とは日本語で「構成する」などを意味するが「事前に金型を複雑に組み立てて置いてコピー時に能力を増やす」というようにイメージすると覚えやすいかもしれない。インスタンスを生成してオブジェクトを作った時にだけ「発動」するという特徴を持っている。一回だけ呼ばれるメソッド。インスタンスの初期化処理を記述する。初期値の設定に使われる。今回の国と言語の初期値設定は国籍などが変わらない限り初期値として設定しても良さそうなので、試しにコードを書いてみた。変更しなそうな名前と言語はコントラクタで初期値として指定できるように組み込む。
6行目にコントラクタの命令が加わっているのがわかる。「__contruct」のようにアンダーバーを二つ繋げて書く。特別なマジックメソッドだが、これも関数なので「function」で作る。今回は国と言語の2つを初期値として一度だけの処理をしたいので、「$country, $language」と書いた。カッコ内にコンまで続けて書く。そのあと、波カッコで、「インスタンス生成時には$countryと$languageを初期値として登録する」という命令を書く。つまり、「後から入力されるのが想定」されているプロパティ($countryと$language)を、「$this」つまり「後から入力されるのが想定されているインスタンス生成されたオブジェクト(今回の場合は$number_1)」がアロー演算子でアクセスした「country」と「language」に代入するということだ。
14行目は、15行目・16行目を書き直したもの。クラス名の後にカッコの中にコントラクタで定義した「$country」と「language」に代入したい文字列を入力してあげる。
アクセス権
プロパティとメソッドへアクセスできる場所を制限することもできる。これまで使ってきた「public」というのもアクセスを意味していた。3種類ある。
- Private:クラス内のみからアクセスが可能
- Protected:クラス内と親子クラス内からアクセスが可能
- Public:どこからでもアクセスが可能
「Public」はインスタンスから直接アクセスできるが、「Private」と「Protected」はインスタンスから直接アクセスはできない。「Private」の場合、クラス内で定義したメソッドから同クラス内のプロパティにアクセスして使うようなイメージ。
プロパティ「$country」を普通に「public」に設定して、15行目で設定したメソッド(関数)を呼び出し、16行目で「echo」で「$counrty」にアクセスした結果を出力してみる。
今度は「$country」を「private」にしてアクセスを制限してみる。
「$counrty」に直接アクセスしようとした16行目だけ表示されていないのがわかる。15行目はクラス内の関数で「$country」にアクセスしているので表示に成功している。インスタンスはメソッド「selectData」にアクセスしただけだからである。
ターミナルにはこのようなエラーもでた。「cannnot access private property Human 」と書かれて、アクセスが制限されてきちんとエラーになっているのがわかる。
staticキーワード(メソッドに使用)
実はインスタンスを生成しなくてもクラスを使うようにできる方法がある。クラスを「staticキーワード」で定義することで可能となる。
13行目に「static」でメソッドを定義した。
このようにインスタンスを生成しないでメソッドを使うことに成功した。
直接クラスのメソッドを使用するので、引数は取らないのでカッコ内は空欄にしておく。「directMessage( )」。また、メソッドを呼び出すときはクラス名の後に「::」とセミコロンを2つくっつける。
staticキーワード(プロパティに使用)
今度は「static」キーワードをプロパティに適用していく。
6行目に「$count」というプロパティを追加した。これはクラスをコピーしてインスタンスを生成するたびに、その数のカウントを表示することを想定したプロパティだ。
7行目で作ったコントラクタ(インスタンス生成時に、初回だけたった一回動くメソッド)に「self::」というのが追加されているのがわかる。この「self::」は「$this->」と同じような働きをすると覚えればいい。その違いだが、「$this」は「static」ではない動的なものへアクセスするとき、「self」は「static」である静的なものへアクセスする時に使われる。さらに詳しくいうと、「$this ->」は、「$this」へ将来代入されるインスタンスがプロパティにアクセスすることを示しているのに対し、「self::」は文字通り「自分自身」のクラスへアクセスすることを示している。なぜ「self」になるのかといえば、「static」でインスタンスを生成する必要がないので、自分が自分でアクセスする、といったイメージだ。
10行目で「++」という加算子でインスタンスが生成されるたびに数字を1つずつ追加していくという命令をコントラクトメソッドに追加している。
23行目では「staticメソッド」の時と同様に。クラス名の後にセミコロンを二つくっつけて「staticプロパティ」にアクセスしている。
表示結果はこうなる。
クラスの継承
クラスを継承して「子クラス」を作ること。クラスの共通部分を「子クラス」としてまとめる仕組み。コードの重複を排除できる。
class Human
をコピーして子クラスを作りたいときは、
class SpaceAlien extends Human
とする。
19行目に「Bird」という子クラスを作った。「Bird」は動物だが、「Human」と人間を定義している「金型」のコピーを生成して同じ機能をもたせたいのでBird
にした。「number_1」とゼッケン番号1番が「japanese」なら、子クラスの「number_1」は「swan」と白鳥とかをイメージするといいかもしれない。子クラスははじめ「宇宙人」とか「白人」とか「動物」とかにしたのだが、クラスを継承して同じ機能を使うことを目的としているのなら、「鳥類」が「人類」を表す「Human」を継承するには同列で記憶しやすいかと思い「Bird」にした。
これが実行結果。
21行目から25行目までの命令もしっかり使えるようになっているのがわかる。
親クラスのメソッドの上書きと子クラスでのメソッド追加
子クラスが継承した親クラスのメソッドはそのまま使えるし、上書きして使うこともできる。これを「Override」という。
親クラスの「Human」を継承して子クラスの「Bird」を作ったものに機能を色々と追加した。18行目までは前回と同じコードとなっている。18行目までは「Human」クラスに関する定義だ。その18行目までの定義をまるまる継承したのが「Bird」で、19行目からそのコードが書かれいている。
まず20行目の「selectData」という親クラスから継承したメソッドを見てみたい。メソッド名をそのまま使えるし、さらに上書きをすることもできるので、鳥らしく文章を変えてみている。
23行目では、子クラスである「Bird」クラスのみが使える新しいメソッドを定義した。鳥類は「hello」とは言わないので「quack」と鳴くようにしてメソッド名も「fromBird」を付け加えた。このようにクラスは継承されるだけでなく、子クラスで新しい機能(メソッド)を追加することができるのだ。
28行目では、子クラスのインスタンス(オブジェクト)を作った。「Human」クラスの人類のゼッケン番号は「$number_1」にしたので、鳥類は「$no_1」としている。鳥類の登録一番目は白鳥(swan)ということ。「country」はちょっと無理があったが鳥類の名前として「swan」を代入して、「language」にはこれも強引だが「quack」と鳴き声を入れた。
30行目を見ると「$no_1」のインスタンスが親クラスのメソッドである「selectData」にアクセスしているのがわかるし、32行目では「static」で定義した静的なメソッドに「Bird」がアクセスしているのがわかる。
実行結果は以下のようになった。
33行目では、きちんと「Bird」クラスが親クラスで定義した「 $count」を継承して使えているのがわかる。
抽象クラス(abstract)
それ自体はインスタンスを生成できないが、子クラスに継承させることだけを想定して作成するクラスのこと。子クラスで実装漏れを防いだり、子クラスの実装をシンプルにできるという利点がある。金型を作るための金型みたいなもの。
3行目を見るとわかるが、抽象クラスを作る際には普段クラスを生成する時の「classクラス名」ではなく「abstract classクラス名」とする。「abstract」は吸収するという意味なので覚えやすい。
6行目の、継承クラス内の「abstract」で定義されたメソッドは、子クラス内で必ず実装しなければならないというルールがある。その際は、メソッドのあとを空欄にしておくというのもルールにある。子クラスで継承して、子クラスでそれぞれ定義してくださいということだ。このように後からメソッドを定義すれば、「Bird」を作る際の強引さも多少は軽減されそうである。
13行目で「BaceCategory」を継承している。
実行結果はこのようになる。
このページの「abstruct」とはがかなりわかりやくす説明しているので、このページを貼り付けておく。
インターフェース
やはり上でリンクを貼ったページの「interface」の箇所を見るとわかりやすい。抽象化(abstract)と似ているが、異なる性質をもつ。「abstract」がプロパティという性質とメソッドという共通した機能を持った、量産のための金型の金型を作る命令なのに対して、「interface」は共通のメソッド(機能)を持たせる複数のクラスを作ることを想定している。
インターフェースは、先に定義したメソッドを、そのあとに定義するクラスで使用しなればならないというルールを設けることができる。
インターフェースでは、アクセス権は「public」のみ。
3行目で、まず「interface」と書いているが、これでメソッドが定義できる。今回は共通の「機能」を子クラスに継承させるという意味を含めて「Action」とした。共通の行動を持った異なるクラスをイメージした。機能は「move」と「make_sound」だ。つまり動けるもので、音をさせるものの機能を持ったクラスが想定されている。
8行目から、クラスを定義して「implements」という命令で「interface」で定義したメソッドを継承する。継承するといっても中身のない金型なので、子クラスの中で定義していく。子クラスで必ず「interface」のメソッドを実装しなければならないというルールがある。
子クラスは「Human」と「Car」とした。「abstract」でHumanを作るもので「Car」は作りたくはないが、「interface」ならば多少はしっくりとくる。
子クラス内で、具体的な行動を定義した。
実行結果はこのようになる。
子クラスは複数のインターフェースを継承できる。
class Human implements Go, Back
といった感じでコンまで繋ぐことができる。
また、インターフェースは追加で実装はできない。
インターフェースと抽象化を同時に
上記の二つを一緒に継承できる。
実行結果は以下のようになる。
外部ファイルの読み込み
「require」はエラーが出た場合に「fatal error」を発生させてくれて、処理されずに終了する。
「include」はエラーが出たら「warning」を発生させてくれるが、処理はそのまま実行される。
「require_once」と「include_once」という命令もあるが、これは両方とも、すでにファイルが読み込まれているかチェックしてくれて読み込まれていればその処理をスキップしてくれるというもの。
「autoload」という方法もある。クラスにしか使えない。
「Test.autoload.php」というファイルを作り、そこに上記のように記述した。
「Test.autoload.php」と同じ階層のディレクトリの「index.php」に上記のようにコードを書いた。「spl_autoload_register」を使用してオートローダーを登録しておくことで自動で読み込んでくれる。
実行結果は「his face is white」となる。
Composer
「composer」はライブラリを管理できるツール。Composerを使用してライブラリをインストールすることで、 「vendor/autoload.php 」というファイルが生成される。そして、このファイルを require すると、 vendor 配下のライブラリをオートロードできるように設定してくれるという便利なもの。
このページに詳しい手順が載っている。
例外処理
PHPは例外処理をサポートしている。プログラムの実行中に何かのエラーが発生することを例外というが、例外が起きたことを明示して補足することで、それに対応する処理を行うことを例外処理という。例外を明示して、何かの処理を与えることができる。
割り算で0で割ったと時のエラーを例外処理にしたもの。
例外を発生させたい場所を「try」で囲む(4行目から7行目)。「if」で条件をつけて、例外だった場合に例外を投げるには「throw」という命令を使う。PHPには初めから「Exception」クラスが定義されている。「new」でそのクラスのインスタンスを生成している。もし例外が発生したら、「catch」によって捕捉される。つまり例外が投げられた後の処理を「catch」の後に書いていく。例外の「$e」による「getMessage」(もともとExceptionクラスで定義されている)が実行される。「$e」というのはお決まり?のよう。
これが実行結果。
名前空間
PHPでは、同じ名前の関数は定義できないので、名前空間を使用することで、同じ名前の関数でも定義できるようになる。
複数の人が関わるプロジェクトなどで、各々が作ったファイルを使い統合するようなときは、誰がどんな関数を定義するのか分からないので、同じ関数名が定義されてしまう可能性がある。しかし、名前空間を使用すれば、関数に苗字がつくので、区別できるし、使い分けもできる。
同ファイル内で、外部ファイルを2つ読み込んで、その2つの外部ファイルで定義した関数が同じ名前だと使用できない。しかし、2つの外部ファイルで、名前空間を使用することで、同フォルダ内でも使用が可能となる。
このようにnamespaceの後に自由に名前をつける。この「MyApp」が苗字になる。
呼び出すときは
MyApp\ 定義した関数
とする。
このページがとてもわかりやすく名前空間について書いている。
PHPからデータベースに接続
名称説明
PDO(PHP Data Objects)
PHPからデータベースにアクセスするための機能を提供するもの。
DSN(Data Source Name)
データベースシステムに応じて接続するための文字列。PDOに接続するときに必要。
結果セット
結果セットとはデータベースからデータを取得する際に経由する場所のことだ。たくさんあるデータベースの情報から一部が指定されるわけだが、その選択されたデータを取得前に一時的に経由する場所だ。
PDOを使う準備
「try」「catch」で作っていく。PDO関連でエラーが出た場合に例外処理をしていくため。
PDOに接続していくにはPDOクラスのインスタンスをつくる。第一引数に「PDO_DSN」、第二引数に「DB_USERNAME」、第三引数に「DB_PASSWORD」を渡す。次の行にも色々とあるが、決まり文句としてとりあえず放置。
14行目からコードを追加した。「exec」は外部コマンドを実行するメソッド。PHPから「exec」という命令でデータベースにUNIXコマンドを通じて実行している。ここでは接続した「test_db」というデータベースに、「testuser」が「test」というテーブルに「name」と「score」を追加した処理となっている。ちなみに名前は「suzuki」でスコアは「60」となってる。
「MySQL」から確認するときちんと追加されていた。
PHPのビルトインサーバで実行結果を確認すると上記のようになっている。
クエリ(データベースサーバ)の実行
execute
結果を返さない。安全なSQLを実行するのに使う。
query
結果を返す。安全なSQLを実行するのに使う。ユーザーからの情報を入力しないような、繰り返し入力しない情報に適している。
prepare
結果を返す。安全対策が必要なSQLを実行するのに適している。ユーザーからの入力があるような、複数回入力されるSQLに適している。悪意のあるユーザへの対策ができる。
クエリの実行
14行目からコードを変更している。「Values」は「?」にしておく。「prepare」を使用するときは「$stmt」オブジェクトをつける。「$stmt」は「execute」というメソッドを使えるが、これが安全な形で値を埋め込んでくれる。挿入されたIDを引っ張ってくるという命令も使える。
しっかりと挿入されている。
ブラウザによる実行結果は上記の通り。
prepare(名前つきパラメータ)
「?」の代わりに名前つきパラメータを使うこともできる。
bindValueメソッド
prepareでは「bindValue」メソッドという一部のレコードにだけ一気に情報を挿入したりするのに便利なものもある。
bindValueの後のかっこにはなんばんめの「?」に情報を挿入した以下の番号、次が値、三番めはデータの型を指定することができる。文字列なら「PARAM_STR」で数字なら「PARAM_INT」でオッケー。
今回は「ito」さんのスコアを複数挿入するというコードで、はじめに「ito」で名前を指定して、その後にスコアを入力して「execute」をスコアのたびに入力すればいい。
bindParamメソッド
bindValueと似ている。bindValueは値をバインドする。bindParamは変数が指し示しているもの(参照しているもの)をバインドする。bindValueはすぐに変数を評価する。bindParamはexecuteされた時点で変数を評価する。すっきりとコードをまとめたりすることができる。違いがよくわからないので、とりあえずこれくらいの情報にしておく。
セキュリティ
エスケープ
PHPからPHPの外に出て行く値を相手先の形に合わせること。一番多い出力先がHTML。
CSRF(クロスサイト・リクエスト・フォージェリ)脆弱性
以下で詳細
正規表現
https://wa3.i-3-i.info/word11309.html
こちらのサイトで解説。
参考文献
『オブジェクト指向でなぜつくるのか』平澤 章 著