注意
XAMPPをブラウザで開くときは、http://localhost/~
◆データベースの3つの型(教科書P288~9)
| 型 | 内 容 | 
|---|---|
| 関係型(リレーショナル型) | データを表で管理。表計算と同様の形! | 
| ツリー型(階層型) | データを階層で管理 | 
| ネットワーク型 | データを網状に管理。必要なデータ間のみ連携されている。 | 
この3つのうち、通常使用されているのは関係型のみ
後の2つは考え方としてはあるが、実用例はほぼない
◆リレーショナルデータベース(教科書P290~1)
データベースは行単位で扱っていく。
行にはプライマリーキー(主キー)が必須。このキーでデータを選択する
プライマリーキーは、「ユニークかつ、not Null」であることが条件。
tblの列はカラム名。tblの集合体がサーバ
■ビュー表
| 表操作 | 内 容 | 
|---|---|
| 選択 | 必要な行単位で取り出す | 
| 射影 | 必要な列(カラム)単位で取り出す | 
| 結合 | 複数のテーブルをキーで合体 | 
外部キー
tbl同士をつなぐキー。(共通のidなど)
■正規化
表を分けて不整合や漏れを防ぐ。
(非正規形→第一正規形→第二→第三)
- 第一正規形
- 繰り返しを除く(繰り返し部分を切り離し、新たなレコードとして挿入する)
 
- 第二正規形
- 関係する部分ごとにtblを分ける
 
|商品コード|商品名|単価|数量|
       ↓
|コード|数量|   |コード|品名|単価|
2つに分ける
- 第三正規形
- 主キー以外に依存している列を取り出し、tblを分ける
 
◆SQLでDBを操作(教科書P310~1)
■DBとPHPのデータやり取り命令(代表的なもの)
| 内容 | 命令 | 
|---|---|
| 選択(取出) | SELECT | 
| 書込 | INSERT INTO | 
| 更新 | UPDATE | 
| 削除 | DELETE | 
| tblやDB作成 | CREATE | 
※CREATEはあんま使わない。
SELECTの条件
| 1 | 2 | 
|---|---|
| 射影 | WHERE | 
| 結合 | JOIN | 
例)
SELECT * FROM ~
- ロールバック:障害が起きる前段階に戻す
- ロールフォワード:以降を手動で処理
◆PHP
PHPはサーバーサイド言語といい、サーバーにPHPファイルの要求があった時は、
サーバー側マシンでPHP部分の処理を行い、その結果を要求したものに渡す形。
- ファイル拡張子 :「.php」
- プログラムエリア:「<?php」で始まり、「?>」で終了
<!DOCTYPE html>
︙
<?php ここにPHPの処理を記述 ?>
※ファイル内に何か所PHPエリアがあっても問題なし(全て処理)
<?php
  if(n%2==0);
?>
  <p>偶数</p> ←echoより処理早い
<?php
  else;
?>
  <p>奇数</p>
<?php
  endif;
?>
PHPはCをベースに開発されており、JavaScriptと基本命令(ifやfor)はほぼ同様。
またPHPは様々なDBにアクセス可能で、現在PHPからアクセスする可能性が高いのはMySQLというDB
- XAMPP(win用)
- MAMP(mac用)
- Apache(大きいくくり。サーバ)
DBが使えるレンタルサーバー
- 
xfree(無料サーバ) - phpMyAdminの構成が古いので注意……
 
- 
ロリポップ 
- 
さくら(有料で安いサーバ) 
 XAMPPと同じ構成
ソース公開はGitHubで
◆XAMPP初期設定
■設定ファイルの変更
1)設定ファイル(.ini)のバックアップを取る
- C:\xampp\php の「php.ini」をデスクトップにコピペ
- 「php.ini.bak」に名前変更し、フォルダに戻す
2)php.iniファイルを修正
- 「mbstring.language = Japanese」の頭にある「;」(コメントアウト)を消す
- date.timezone=~を「date.timezone="Asia/Tokyo"」に修正
3)XAMPPを再起動し、Apache&MySQLの[start]ボタンを押す
- Moduleが薄緑になり、下に赤文字エラー出ないことを確認したらOK!
閉じるときは、「stop」押さないとバックグラウンドで動いちゃうよ
■ファイル構成をデフォルトで開く
1)htdocsにある「index.php」を削除
2)http://localhost/を開く(そのままブクマ)
◆htdocs(C:\xampp\htdocs)
■ローカルでXAMPPによる作業をする
「xamppフォルダ」内の「htdocs」の中に保存。ここ以外に置いてもPHPは処理されない
(レンタルサーバでいう、レンタルしてファイルやフォルダを置く場所!)
■アクセス時には、「http://localhost/」!!
PHPファイルをXAMPPで処理してブラウザで表示するには、
「http://localhost/~」と入れ、その後フォルダ名やファイルを入力してアクセス。
※htdocsフォルダまでが「http://localhost」アドレスなので注意
◆XAMPPのボタンについて
| ボタン | 動作 | 
|---|---|
| [Shell]ボタン | win shellひらく | 
| [Admin]ボタン | Apache=フォルダ構成、MySQL=phpMyAdminが開く | 
| [Explorer]ボタン | XAMPPのフォルダ開く | 
| [Service]ボタン | 今動いてるプログラム?が見れる(変なの邪魔してないかとか見る | 
phpMyAdmin以下テーブルはXAMPPを構成してるので絶対触らない!
 -information_schema
 -mysql
 -performance_schema
 -phpmyadmin
shellにはクエリをうつ。が、phpMyAdminの「SQL」タブの方が楽…(ショートカットが古い
文字コードはutf8_binが日本語
◆echo文(出力)
echo "ここに表示する内容";
その場所に指定した内容(文など)を出力する。
<p><?php echo "Hello,I'm a PHP!"; ?></p>
//   ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄↑ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
//ここがPHPとして処理され、指定した文字列が書き出される
//(「<p>Hello~PHP!</p>」となり、ブラウザで出力)
- echoの""中にpタグ含めて書くより、pタグでechoを包む形が多い!!
- PHPで処理する量を減らすため、タグが確定してる時は中にPHP
- PHPエリア内はスペース効かないので、ソース汚くなる……
 
■echo中の「,」
文字列の連結。文字列と変数を繋げることも可能
echo "<p>「",$number,"」は、奇数です。</p>",PHP_EOL;
       ̄    ̄            ̄
printを使うメリットは特にないのでechoでいい
◆ソースの改行
■「PHP_EOL」…出力されるソースコードの改行
echo "<p>「",$number,"」は、奇数です。</p>",PHP_EOL;
//                                ̄ ̄ ̄ ̄
◆コメントアウト
■/*~*/
複数行(ブロックコメント)
■//
一行
■#
一行
PHPのコメントは、ソースを開いても見れない(PHP処理内なので)
◆「"」「'」の違い
JSは「"」「'」同じ意味だったが、PHPは違う!!!!
echo文文において
- 「"~"」
- 内部の変数を評価し、値に変換して出力
 
- 「'~'」
- 内部の変数は評価せず、変数名そのまま出力
 
◆$~(変数の命名)
■「$~」
変数名を付ける
JSと違い、変数に「宣言」は不要!
◆mt_rand(乱数取得)
■「mt_rand(min,max)」
乱数取得
mt_rand()は、rand()のエイリアス(別名)として同様の動き。
共に()内は「min~max」間の数値をランダムで1つ取得する。
()を省略すると、以下が入力されたものとして乱数を取得。
- min:「0」
- max:そのシステムで扱える最大の整数
rand()のが古い。PHPverが古い場合は「mt_」の方がより高速。
◆var_dump()関数
()内に変数を書くと、その変数の型や中身が出力される。
効果はJavaScriptのconsole.logに近い。
出力されるのはブラウザ上になるため、開発終了時に残ってはいけない!!
$a = 1;
var_dump($a); //int(1) と出力
◆エラー
- パースエラー/シンタックスエラー
- 致命的!画面に何も出ない
 
- FatalErrorなど
- そこまで処理し、エラーで停止
 
- 警告
- エラー出るだけで処理する
 
※最終的に警告含め全部消す!
◆可変変数
変数名に変数を使う、変数名を可変にする。
$var=1;
$var_name='var';
echo $$var_name;
//    ̄ ̄↑ ̄ ̄
//  まず、「$var_name」が評価されて「$var_name」の中身が「$var」
//  となり、その後に「$var」が評価され「1」がechoされる
◆スーパーグローバル変数
$_ほにゃほにゃのことを、スーパーグローバル変数という。
| 変数 | 内容 | 
|---|---|
| $_GET | formのmethod="get"で受け取った変数 | 
| $_POST | formのmethod="post"で受け取った変数 | 
| $_COOKIE | cookieから受け取った変数 | 
| $_SESSION | セッション変数 | 
cookieとセッションはセットで使う
◆変数のスコープ
■グローバルスコープ
PHPにブロックスコープはない!
JSと違い、ブロックで定義しても以降ずっと使えてしまうので注意
■ローカルスコープ
関数(function)内はローカル!!
◆定数
■define()関数
| 引数 | 内容 | 
|---|---|
| 第1引数 | 定数名(名なので文字列) | 
| 第2引数 | 値 | 
<?php
define('book','Perfect PHP');
■constキーワード
JavaScriptと同様の形で設定。(PHP5.3以降可能)
<?php
const BOOK = 'Perfect PHP';
◆printfによる小数点以下の強制出力
printf()
| 引数 | 内容 | 
|---|---|
| 第1引数 | 第何位までかを指定('%.〇f'の形で、〇部に指定) | 
| 第2引数 | 値 | 
echoの場合
小数点以下&以降0しかない時、省略(整数に)される。
◆型判定
| 型判定 | 内容 | 
|---|---|
| is_string() | 文字列 | 
| is_int() | 整数 | 
| is_float() | 浮動小数点 | 
| is_numeric() | 数値として扱えるか判定 | 
()の値を判定し、「true」or「false」が返る。
文字列の"1"は自動キャストで整数型になる=true判定
◆型チェック
gettype()関数
()内のものの型を返す。
◆文字列の連結演算子
「.」で行う
echo文内は「,」でも文字列の連結が可能。
◆変数の計算の順番(メモ)
$a=1;
$b=$a ++;
//  ̄ ̄ ̄~aまで先に処理
【結果】
$a…2
$b…1
$a=;
$b=++$a;
//   ̄ ̄++~が先に処理
【結果】
$a…2
$b…2
◆配列
$配列名=array(中身1,~,);
添字配列も連想配列も、共に同じ命令で作成。
(同じ関数で作成することから、添字配列と連想配列は同じものと考える!)
PHPにおいて、キーを指定しなかった場合、自動的に添字をキーとして配列を作成する。
以下の2つは、同じ配列を作成している!!
$arr=array(
  'a',
  'b',
  'c',
);
$arr=array(
  0=>'a',
  1=>'b',
  2=>'c',
);
配列は、
- 値の変更 :可能
- キーの変更:不可!
<?php
$one = array(
  1,
  1.0,
  '1',  //複数の型も入れられる
);
$fruits = array(
  'peach',
  'apple' => 'red', //連想配列(appleがキー
);
echo $fruits[1],PHP_EOL;      //「peach」と表示
echo $fruits['apple'],PHP_EOL;//「red」と表示
$arr=array();  //空の配列
◆配列の挿入削除
array_splice(配列,〇番目から,△個削除し,そこに挿入する)
| 引数 | 内容 | 
|---|---|
| 第1引数 | 配列 | 
| 第2引数 | 〇番目から | 
| 第3引数 | △個削除し | 
| 第4引数 | そこに挿入する | 
挿入するデータのキーは指定不可(添字が自動付与)
◆if文
JavaScript同様の形で使用可能。
■JSとの相違点①
- 
elseif命令- else ifも問題なく使用でき、かつelseifという形も使用できる。
 
if(~){
// ︙
}
else if(~){
// ︙
if(~){
// ︙
}
elseif(~){
// ︙
JSのelse{if(~は省略形。
「elseif」という命令自体がある
■JSとの相違点②
- ブロックの代わりに「:」「endif」を使用できる
if(~):
// ここに処理
else:
// ここに処理
endif;
◆PHPにおけるswitch
PHPのswitchは、caseと**「==」判定**を行う。
(教科書に===とあるが、正しくは==)
switch文は判定が言語により異なるので、新しい言語を学ぶときは必ず確認が必要!
◆foreach
forで配列のレングスを回すのと同じ!
foreach(配列名 as ここで使う変数)
//       ↑      ̄ ̄ ̄ ̄ ̄ ̄ ̄$value等が定番
//添字なくても処理してくれる
配列の値を、先頭から順に、指定した変数に代入してループ処理。
(配列の最終データの次に)もうデータがないことを示すalseが返ってきたら、ループ処理を終了する
■値に加え、キーも取得
foreach(配列名 as キーを受ける変数 => 値を受ける変数)
//              ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄$key等が定番
◆foreach‐&による参照
foreach($fruts_color as &$color)
               ̄
取得時に&参照を使用することで、
foreach内において$colorと取得した配列の中身が同期を取り、
$colorに代入すると、その時取得している値にも代入される。

この参照をしたとき、foreach終了後は
$colorは配列の最後のデータを参照したままになっている。
そのため、foreach終了後に$colorに値を代入すると、
配列の最後のデータに書いてしまう。
それを避けるため、参照を行った際は、
参照が終わり次第すぐに、その変数の参照を解除する必要がある!!
unset(変数名)
指定した変数をリセットする関数。
◆date
date(フォーマット);
■フォーマット一覧
| フォーマット | 意味 | 
|---|---|
| Y | 年4桁 | 
| y | 年2桁 | 
| m | 月(二桁の数字) | 
| n | 月 | 
| d | 日(二桁の数字) | 
| j | 日 | 
| D | 曜日3文字 | 
| l | 曜日フルスペル | 
| w | 曜日(数字) | 
| G | 時間24時 | 
| g | 時間12時 | 
| H | 時間24時2桁 | 
| h | 時間12時2桁 | 
| i | 分2桁 | 
| s | 秒2桁 | 
echo date("Ymd");// 20010310
$today = date("H:i:s");// 17:16:18
$today = date("Y-m-d H:i:s");
// 2001-03-10 17:16:18 (MySQL の DATETIME フォーマット)
◆exit()、die()
共にPHPの強制終了命令。
この関数実行後は、そのPHPファイルのそれ以降の処理はしない。
()内に文章を設定すると、終了時にそれを出力する。
<?php
die ('ここで終了~!'); //画面上に文字表示
echo 'ここは処理されないよ';
?>
◆array_map()関数
array_map(関数,配列)
| 引数 | 内容 | 
|---|---|
| 第1引数 | 関数 | 
| 第2引数 | 配列 | 
第2引数で指定した配列のすべての要素に、第1引数の関数を実行
                      ̄ ̄ ̄ ̄ ̄↑ ̄ ̄ ̄ ̄
(第1引数の関数に 配列の要素の値を順に引数として渡し、戻り値をその要素に代入する)
◆クロージャ(教科書P114)
ローカルスコープだけでなく、定義された場所のスコープも含める関数。
function() use($関数内で利用したい外の変数名){ ここに処理 }
//                      ↓2が親
$my_pow = function($times = 2){
//                  ↓親の引数を使う宣言
    return function ($v) use(&$times){
//   ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄returnで指定した関数の戻り値をreturnする
        return pow($v,$times);
    }
}
//引数を渡されなければ「2」(親を使う)、渡されたらその値を使う
$cube = $my_pow(3);//returnで関数が入る
echo $cube(2);//2の3べき乗(2*2*2)、結果は8
echo $cube(4);//4の3べき乗(4*4*4)、結果は64
関数に「;」は不要だが、
無名関数は変数に関数を代入しているので最後に「;」($suu=関数;)
◆べき乗
pow(元の数,べき乗の数);
◆htmlspecialchars()関数
htmlspecialchars(値,ENT_QUOTES,文字コード)
| 引数 | 内容 | 
|---|---|
| 第1引数 | 値 | 
| 第2引数 | ENT_QUOTESで「'」「"」両方対象 | 
| 第3引数 | 文字コード | 
- 第1引数の値の中で、htmlではそのままでは出力されない文字をエスケープ処理する
- 「>」→「&gr;」、「<」→「<」など
 
- 「
ユーザの入力がhtml上意味のある記号等含む場合、要処理(<>がタグ扱い等)
&/>など
- 第2引数
- 
ENT_COMPATダブルクオートは変換しますがシングルクオートは変換しません。
- 
ENT_QUOTESシングルクオートとダブルクオートを共に変換します。
- 
ENT_NOQUOTES
 ︙
 
- 
ユーザーの入力したものはエスケープ処理必須!!1!
◆formデータ受取(教科書174P)
html側で、以下の形でデータを受け取る。
- 
get→「$_GET['name属性値']」
- 
post→「$_POST['name属性値']」
<body>
 <?php if(isset($_GET['name']) && strlen($_GET['name']) > 0): ?>
 <p><?php echo htmlspecialchars($_GET['name'],ENT_QUOTES,'UTF-8'); ?>さん、こん
にちは</p>
 <?php endif; ?>
 <form action="form.php" method="get">
  <p>名前:<input type="text" name="name">
  <input type="submit" value="送信">
 </form>
</body>
◆count()
count(配列)
配列の要素数を取得
◆フォーム確認画面→受け取り
1)
htmlを書くとき、inputのtypeを「hidden」にすると、ブラウザ上に表示されない。
(ソースには表示される)
<input type="hidden" name="~" value="<?php echo ~;?">
の形で、ユーザの入力したものをvalueに設定していく。
■確認画面から戻るボタン
<input type="button" value="戻る" onclick="history.go(-1)">
//                                  ̄ ̄ ̄ ̄↑ ̄ ̄ ̄
//                     JavaScriptで一つ前のページへ戻る
//                     (「-1」は1ページ分戻る)
◆正規表現によるチェック(教科書510P)
preg_match(正規表現,チェックする文字列)
| 引数 | 内容 | 
|---|---|
| 第1引数 | 正規表現 | 
| 第2引数 | チェックする文字列 | 
結果は true/false で返される!!!
※^~$で、頭から最後まで(メアドなど特殊な場合除き、必須)
※「~/u」はUTF-8の指定
if (preg_match("/^[ぁ-んァ-ヶーa-zA-Z0-9一-龠0-9、。\n\r]+$/u",$message)) {
$message = $message;
}else{
$error = '変な記号は使わないでね。';
}
■郵便番号 書式チェック
if (preg_match('/^([0-9]{3})(-[0-9]{4})?$/i', $data)) {
■電話番号 書式チェック
if (preg_match('/^[0-9]{2,4}-[0-9]{2,4}-[0-9]{3,4}$/', $data)) {
■数値 書式チェック
if (preg_match('/^[0-9]+$/', $data)) {
■英字 書式チェック
if (preg_match('/^[a-zA-Z]+$/', $data)) { // 英字の場合
■英数字 書式チェック
if (preg_match('/^[a-zA-Z0-9]+$/', $data)) { // 英数字の場合 }
■メールアドレス編 Emailアドレス 書式チェック
if (preg_match("/^[A-Za-z0-9]{1}[A-Za-z0-9_.-]*@[A-Za-z0-9_.-]+\.[A-Za-z0-9]+$/", $mail)) { // メールアドレスやで
■漢字・ひらがな・カタカナ編 書式チェック
mb_regex_encoding("UTF-8");
if (preg_match("/^[ぁ-んァ-ヶー一-龠]+$/u",$name)) {
◆フォームのファイル送信・保存
$_FILES['name属性値']['コード']
■コード(以下5種類)
| コード | 内容 | 
|---|---|
| name | ユーザが決めたファイル名 | 
| tmp_name | ファイルの一時保管場所 | 
| size | ファイルサイズ(byte) | 
| type | ファイルのmimeタイプ(拡張子など) | 
| error | エラーコード(0~8) | 
<エラーコード>
0:成功
1:php.ini(サーバ側の設定)で制限したサイズをオーバー
2:HTMLで制限したサイズをオーバー
3:ファイルが一部しか転送されていない
4:ファイルが全部転送されていない
5:欠番
6:テンポラリーフォルダ(一時保管場所)がない
7:書き込み失敗
8:PHPの拡張モジュールによる制限
■htmlによるファイルサイズ制限
<form ~~>
 ︙
<input type="hidden" name="MAX_FILE_SIZE" value="byte数">
<input type="file" name="~"> ↑←※順番固定!!!!
◆一時保管場所から保存フォルダへの移動
一時保管されたファイルは、当該PHPファイルから別ファイルへ実行が移った時点で削除。
したがって、<form>の「action」で指定したファイルでのみ保存処理が可能。
@move_uploaded_file(一時保管場所,保存する相対パス)
//                           ̄ ̄ ̄ ̄↑ ̄ ̄ ̄
//                         PHPから見た相対パス
| 引数 | 内容 | 
|---|---|
| 第1引数 | 一時保管場所 | 
| 第2引数 | 保存する相対パス | 
結果は true/false で返される
move_uploaded_file($_FILES['upload_csv']['tmp_name'], $storeDir.$filename);
move_uploaded_file( $_FILES['file1']['tmp_name'], './upload/pic.jpg');
命令の実行中のみ一時保管される
◆指定したファイルが存在するか確認
file_exists(相対パス)
| 引数 | 内容 | 
|---|---|
| 第1引数 | 相対パス | 
- 結果がtrue :存在する
- 結果がfalse:存在しない
◆流れ
- エラーコードチェック
- ファイルの種類やサイズ等のチェック(任意だが、ほぼ必須)
- 保存する相対パスの作成
- 同名で保存されているファイルがないかチェック
- ファイルの移動
◆セッション
■セッションとは
フォームを使用せず、ページ移動してもデータを持っていける。
(一度ログインしたらサイト内移動してもログインを保つ時などに使用)
session_start();
各ページで宣言が必要(なければ新規、あれば既存と結び付け)
- 実行すると、サーバからユーザにcookieとしてセッションIDが送られる。
 サーバ内にはセッションIDごとに$_SESSIONを使用した連想配列が保持。
- プログラム上で$_SESSIONにデータを保存しておき、他ページでこの値のチェック(存在チェック等)を行うことで、セッションの継続を確認する。
■セッションの有効時間
プログラムで終了処理をしなかった場合、どちらか早い方で終了する。
- php.ini記載の継続時間(xamppは1440秒)
- cookieの保存期間(デフォルトはブラウザ閉じマデ)
■流れ
1)セッション開始
  session_startで取得、$_SESSIONにtime等をセットする。
2)以降のページでセッション継続
  session_startで同期、$_SESSIONにtime等があるか判定する。
3)セッションを終了する
session_start();
$_SESSION['email']=$_POST['email'];
◆セッションのセキュリティ対策
セッションによりcookieに保存されるIDは、セキュリティ対策として不定期に更新することが望ましい。
session_regenerate_id(true);
スマホ主流の現状、この頻度を上げるとその度にサーバとのデータのやり取りが発生→セッションが切れてしまうこともある。
どの程度行うかは、開発の責任者が判断
◆セッションをプログラムから終了
終了するには、以下の手順が必要となる。
- $_SESSIONのデータ消去
- cookieの削除
- セッションの破棄
//1)
$_SESSION=array();
//2)
if(isset($_COOKIE[session_name()])):
    setcookie(session_name(),"",time()-1000);
    endif;//                       ̄ ̄ ̄今の時間より前に期限設定=即時破棄
//3)
session_destroy();
3のみでOKの本もあるが、1と2のデータ残るので注意
◆JavaScriptでのリロード処理
ブラウザバック・JavaScriptにより戻るページはキャッシュで表示のため、
サーバとのやりとりがない=PHPが実行されない!
この時、PHPの処理を行う場合はJavaScriptでのリロード処理が必要。
window.onpageshow=function(event){
    if(event.persisted){
//   ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄キャッシュで表示している時にtrueを返す
        window.location.reload();
    }
}
◆PHPによるファイルの削除
unlink(相対パス);
◆ひとこと掲示板作成(教科書178P)
■1)DBの新規作成
1つのDBには、複数のテーブルを持つことが出来る。
Excelでいえば、「DB=ファイル」「テーブル=タブ」にあたる。
【手順】
1.XAMPPから、MySQLの[Admin]ボタンでphpMyadminへ
2.左メニューで「新規作成」
3.DB名を入れ、「utf8~4_bin」選択
■2)テーブルの作成
- テーブル名の入力
- カラム数の設定
カラム数は後で増やすことも可能だが、データを入れてからの増加は現実的ではない。
最初からどの項目がどのテーブルに必要なのか確定させておく!!
テーブルの「構造」タブで変更など可能
間違えてユニークにした場合は下の「インデックス」から削除可能
◆PHPでDB操作する命令(教科書P189~)
| 型 | 内容 | 
|---|---|
| mysqliによる手続型 | 旧MySQLからの移行が簡単 | 
| mysqliによるオブジェクト型 | ほぼ使わない | 
| PDOによるオブジェクト型 | PHP5-6以降に作成されたものはほぼこれ | 
※PDO…MySQLだけでなく、ポスグレやオラクルDBも扱える新しい命令
新規開発ならPDO、改修はmysqli(どっちも知っとけ)
◆DBへの接続
$link = mysqli_connect('ホストサーバ','ログインid','ログインpass')
※教科書は古いので、「i」がない。つける 例)$link = mysql_connect(~)
| 引数 | 内容 | 
|---|---|
| 第1引数 | ホストサーバー | 
| 第2引数 | DBのログインID | 
| 第3引数 | DBのログインパスワード | 
データベースへの接続を行う。以下が返る。
- 成功:接続情報
- 失敗:false
◆接続失敗のエラーメッセージ
mysqli_error()
※教科書は古いので「i」がない。つける 例)mysql_error()
接続失敗のエラーメッセージ。(なんでエラーか)
◆DBの選択
mysqli_select_db(接続情報,'DB名');
※教科書は古いので「i」がない。つける
 例)mysql_select_db('oneline_bbs',$link)
| 引数 | 内容 | 
|---|---|
| 第1引数 | 接続情報 | 
| 第2引数 | DB名 | 
古いと第1と第2が逆なので注意!!
データベース選択。
(教科書にないが、この後に以下の行を追加!!)
◆DBの文字コード設定
mysqli_set_charset(接続情報,'文字コード');
| 引数 | 内容 | 
|---|---|
| 第1引数 | 接続情報 | 
| 第2引数 | 文字コード | 
MySQLのDBの文字コードをPHPでも設定。
mysqli_set_charset($link,'utf8');
◆DBとの切断
mysqli_close(接続情報);
※教科書は古いので「i」がない。つける 例)mysql_close($link);
| 引数 | 内容 | 
|---|---|
| 第1引数 | 接続情報 | 
DBとの切断はPHPプログラム終了の際に自動でも行われるが、
DBのユニークアクセスを考え、不要になった時点で明示的に切断が望ましい。
   ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄※接続待ちを短くするため、早く解放!
◆DBへの新規データ書込
INSERT INTO `テーブル名` (`カラム名`,...) VALUES (値,...);
カラム名の順に値を設定。
「`」は「'」(コーテーション)じゃない注意!!!!(shift+@キー)
◆DBへ書込時のエスケープ処理
mysqli_real_escape_string(接続情報,エスケープする文字列)
※教科書は古いので「i」がない。つける 例)mysql_real_escape_string(
| 引数 | 内容 | 
|---|---|
| 第1引数 | 接続情報 | 
| 第2引数 | エスケープする文字列 | 
今回のひとこと掲示板は
mysqli_real_escape_string($link,$name  )
                $comment)
◆作成したSQL文の実行
mysqli_query(接続情報,SQL文);
※教科書は古いので「i」がない。つける 例)mysql_query($link,$sql);
| 引数 | 内容 | 
|---|---|
| 第1引数 | 接続情報 | 
| 第2引数 | SQL文 | 
古いと第1と第2が逆なので注意!!
◆書込み後のリダイレクト
■header()関数
httpに生のデータを送信。リダイレクト等で使用
※書込みを表示するためにリロードする!
■location
リダイレクト命令
■$_SERVER[]
サーバー情報の入った連想配列。
- 
$_SERVER['HTTP_HOST']- サーバのURL(~.co.jp/まで)
 
- 
$_SERVER['REQUEST_URI']- 今開いているページ(.co.jp/~の、「~」部分)
 
header('Location: http://' .$_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
◆DBのデータ取得
■SELECT文
SELECT `カラム名`... FROM `テーブル名`
//      ̄ ̄ ̄ ̄「*」で全カラム取得!
■オプション(↑に続けて記述)
| SQL | 内容 | 
|---|---|
| WHERE句 | 条件指定。 'ago'>30など | 
| ORDER BY句 | 並び替え | 
ORDER BY `カラム名` DESC//…降順
//              ASC   …昇順
SELECT `username`,`pass` FROM `user_tbl` WHERE `username`=?
◆SELECT文の実行結果
以下が返ってくる。
- 成功:要求データ
- 失敗:false
このデータの取得行数(件数)は、以下で取得できる
mysqli_num_rows($変数)
※教科書は古いので「i」がない。つける 例)mysql_num_rows(
| 引数 | 内容 | 
|---|---|
| 第1引数 | SELECT文の実行結果を受けた変数 | 
◆fetch(SELECT結果を切り取って取得)
$変数 = mysqli_fetch_assoc($SELECT結果変数)
※教科書は古いので「i」がない。つける 例)mysql_fetch_assoc(
一回実行すると、取得データの一件目を切り取り、変数に代入。
渡すデータがない場合、「false」を代入。
コピーではなく切り取りなので、元データから無くなる!!
$post = mysqli_fetch_assoc($result)
fetchで代入した変数の中身は配列!!
  (カラム名をキーとした「連想配列」)
◆SELECT結果を受け取った変数の解放
mysqli_free_result($変数)
※教科書は古いので「i」がない。つける 例)mysql_free_result(
fetchにより全件切り取られても、DBとの接続は自動で切れず残る。
解放しないと、以降のDBへの命令がエラーになる!!
◆プリペアドステートメント
DBのセキュリティ対策の一つ。
real_escape_stringではない新しい方法で、ユーザの入力した文字をエスケープ処理。
後発なので、real_escape_stringsより高度!
1)SQL文を変数に入れる
変数 = mysqli_prepare(~,~);
| 引数 | 内容 | 
|---|---|
| 第1引数 | 接続情報 | 
| 第2引数 | SQL文(ただしユーザ入力文字の部分は「?」にする) | 
$sql=mysqli_prepare($link,'INSERT INTO ~('~',…)')VALUES(?,…)');
2)「?」をエスケープ処理後、バインド
mysqli_stmt_bind_param(変数,順に型,順に値,…)
| 引数 | 内容 | 
|---|---|
| 第1引数 | SQL文の入った変数 | 
| 第2引数 | バインドする物の型を「?」の順番通りに(i…数値型、s…文字列型) | 
| 第3引数以降 | バインドする値を「?」の順に | 
mysqli_stmt_bind_param($sql,'iss',$id,$name,$pass);
3)SQL文実行
mysqli_stmt_execute(~);
| 引数 | 内容 | 
|---|---|
| 第1引数 | SQL文の入った変数 | 
4)プリペアドステートメント終了
mysqli_stmt_close(~);
| 引数 | 内容 | 
|---|---|
| 第1引数 | SQL文の入った変数 | 
- mysqli_close(~)は別途実行する!!
- 使った直後に、毎回終了する!!
◆ひとこと掲示板に画像添付機能を追加
■画像について
$_FILES同様に、保存した後、DBには相対パスを保存する
(パス、ファイル名をアップして繋げても)
※画像はDBにしまえないので
出来た相対パスをimgテーブルに追加
■コメントをにする場合
そのままだとユーザの入力した改行が無視される。
「nl2br()」という改行コードを<br>に変換してくれる命令を使用すると、ユーザの改行そのまま表示できる。
nl2br(htmlspecialchars~);
DBはテーブル作成、ぷらいまりー、最初の段階を作るところまで
INSERT INTOなし
エラーで終わる時もDBきる
通常のクエリ実行は結果が返るが、プリペアドステートメントのexecuteは結果がtrue/false
◆DBのカラムの中身を変更
UPDATE `tbl名` SET `カラム名` = 値 WHERE レコードを選択する条件式
$sql=mysqli_prepare($link,"UPDATE `kaiin` SET `tel`=? WHERE `name`=?");
mysqli_stmt_bind_param~
※SET、WHELEに?が分かれてるけど、変わらず出てきた順でいい(tel、name)
UPDATEだけFROM句が無い!!!!!ので注意
◆DBのレコードを削除
DELETE FROM `tbl名` WHERE レコードを選択する条件式
$sql=mysqli_prepare($link,"DELETE FROM `kaiin` WHERE `name`=?");
mysqli_stmt_bind_param~
◆CSVファイル出力
1)文字列にする
- セルの横の区切りに「,」
- セルの縦の区切りに「\r\n」
 を付与する(文字列の連結)
作成した文字列の入った変数を$str
ダウンロードするファイル名が入った変数を$fnameとした場合、
2)ファイル名指定
$fname = ~.csv;
3)DLファイルのMIMEタイプ指定
header('Content-type:text/csv');
4)DLファイル名をPHPで指定
header('Content-Disposition:attachment;filename='.$fname);
5)出力
echo $str;
※shift-JIS出力は、
echo mb_convert_encoding($str,'SJIS','UTF-8');
$str作成から連結した処理として行う!!!
(順番は厳守、間に他の命令挟まない)
◆try-catch文
try{例外の発生する処理}
catch(Exception 変数名){例外発生時の処理}
finally{例外があってもなくても実行する処理}
throw new Exception('例外メッセージ');
あんまfinallyは使わない(catchでdieするので)
◆PDOによるDB接続
try{変数名 = new PDO('mysql:host=localhost;dbname=DB名;charset=文字コード',
'DB接続のユーザID','〃パスワード',array(PDO::ATTR_EMULATE_PREPARES=>false));
※書くとき、変える部分(日本語)は変数に入れると楽
sqliでいう「$link=mysqli_connect~mysqli_charset」までに相当!!
- オブジェクト型は「->」(〇〇を使って->〇〇)
- DB接続情報(変数)、DB取得処理わかるようコメントする(引継ぎ用に
//DB接続情報
$dbname = 'mysql:host=localhost;dbname=DB名;charset=文字コード';
$id =  'root';
$pw =  '';
try {
    //DB取得処理
    $pdo = new PDO($dbname,$id,$pw,array(PDO::ATTR_EMULATE_PREPARES=>false));
}
catch(PDOException $e){
    die('DB接続失敗'.$e->getMessage());
//                ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄開発用なのであとでけす
$dsn = 'mysql:dbname=uriage;host=localhost';
$user = 'testuser';
$password = 'testuser';
try{
    $dbh = new PDO($dsn, $user, $password);
}catch (PDOException $e){
    print('Error:'.$e->getMessage());
    die();
}
◆DBの処理終了(解放)
new PDOを代入した変数に「null」を代入
$pdo = null;
◆プリペアド不使用の場合(ユーザ入力文字無し)
※$pdoにnew PDOを代入している。
※$sql、$stmtはよく使われる変数名
$sql=SQL命令文
$stmt=$pdo->prepare($sql)
$stmt->execute();
// ︙
$stmt=null;// ←開放する(close代わり
( ..)φメモメモ
SELECT * FROM だけのやつ
◆ユーザ入力文字のエスケープ処理あり
※$pdoにnew PDOを代入している。
$sql='INSERT INTO `tbl名`(`mail`,`pass`) VALUES(:mail,:pass)';
//                                       ̄「:~」で仮の変数
$stmt=$pdo->prepare($sql);
$stmt->bindParam(':mail',値);// ←上記の「:~」に
$stmt->bindParam(':pass',値);//      値をバインド
//     ̄ ̄ ̄ ̄ ̄※「bindParam」は変数、「bindValue」は変数・実数どちらも値に設定できる
$stmt->execute();
// ︙
$stmt=null;
※bindParam:executeで評価する(変数の名前だけを渡す) ←変数はこっち、
 bindValue:書いた行ですぐ評価(変数の実数だけを渡す) ←実数はこっち…が多い!
名前がふってるので、mysqliと違って順番固定じゃない!
◆SELECT文で取得したデータの取り出し
※実行時の変数は$stmtとする
$stmt->fetch(PDO::FETCH_ASSOC)
上記を変数に代入する。
whileの場合は、変数に代入する命令を条件式とする。
- (PDO::FETCH_ASSOC)
- カラム名とデータを持ってくる
 
- ()
- 添字でも回せるし、連想でも回せる形で取得(Wでとってくる無駄がある
 
どうせ添字使わないのでFETCH_ASSOCでいい
◆PDOのSELECT行数(mysqli_stmt_num_rowsに相当)
$sql='SELECT COUNT(*) FROM~WHERE~';
$stmt = $pdo -> prepare($sql);//あればプリペアド
$stmt -> execute();
$stmt->fetchColumn();
※WHERE句付で実行
別途、行数取得のためのSQLを実行。
$sqlに代入し、$stmtでプリペアド~executeまで行う。
その後、$stmt->fetchColumn()で行数を取得。
■件数の有無のみ必要な場合
SELECTをexecute後、一件目のfetch命令を受けた変数がfalseか判定。
(falseなら、取得件数=0!!!!)
〇件取得、等の場合はSELECT COUNT(*)する
◆DBでの文字コードの違い!(照合順序の違いがある)
- utf8bin:大文字小文字や、ひらがなカタカナなど全てを区別する
- utf8_general_ci:大文字小文字を区別しない
- utf8_unicode_ci:ひらがなカタカタを区別しない。商品検索などに
◆JOIN‐内部結合(INNER JOIN)
SELECT ~ FROM ~ INNER JOIN 結合するtbl名 ON キー
INNERを省略することもできるが、明示するのが一般的。
また、ON演算子の指定を行わないと、たすき掛け状態で合体する。
■ON演算子
テーブル名.カラム名 = テーブル名.カラム名
結合するtblで、どのカラムをキーとするか指定。
それぞれ、tbl名とカラム名を「.」で繋ぎ、一致したら…という意味で「=」で結ぶ。
- JOINは基本「内部結合」(欠けたレコードを省く)
- たすき掛けJOINと区別するため、INNERを書く!!
◆JOIN‐外部結合(〇〇 OUTER JOIN)
SELECT ~ FROM ~ (LEFT ) OUTER JOIN 結合するtbl名 ON キー
//             (RIGHT)
//         ※ベースtblが左か右か
二つのtblのうち、ベースとなるtblのデータに、もう片方のtblを結合。
片方のtblのみに存在するデータは、以下の扱い。
- ベースtblにあり、結合tblに無い
- 結合tblに入る
 
- ベースtblに無く、結合tblにある
- 結合tblに入らない!
 ※一つのシステムではLEFTかRIGHTのどちらかのみで統一するのが一般的。
 
- 結合tblに入らない!
◆phpMyAdminから直接データ入力
SQL画面から
※A.Iのカラムは消す!!
◆LIKE演算子
DBのデータ取得時に「部分一致」での取得を行う。
(WHEREの条件式に演算子としてLIKEを使用)
SELECT ~ FROM ~ WHERE カラム名 LIKE %検索ワード%
※カラム名に検索ワードを含む値が入ったものを取得
<条件>
- 
%:0文字以上の任意
- 
_:1文字の任意
 ※組み合わせて使用!!(__で2文字、_%で1文字以上、___%で3文字以上…など)
例)
| 書き方 | 意味 | 
|---|---|
| %テレビ% | テレビという文字列を含むものすべて | 
| 3_ | 年齢カラムで30代の人すべて | 
| _%テレビ_% | テレビの前後に1文字以上の文字が入るもの全て | 
■_%\を検索文字列として使用する!
%や_は意味があるため、また\はエスケープに使用するため、\を付けてエスケープ。
- 「_」:\_
- 「%」:\%
- 「\」:\\
◆暗号化
password_hash(文字列,PASSWORD_DEFAULT)
//               ※一般的なモードこれ!
| 引数 | 内容 | 
|---|---|
| 第1引数 | 暗号化する文字列 | 
| 第2引数 | 暗号化のモードを指定 | 
元の文字列の長さに関わらず、60文字以上の文字列に暗号化する。
■PASSWORD_DEFAULTとは
常に最新のアルゴリズムによって暗号化。なので、暗号化後の文字列はさらに長くなる可能性あり。
オフィシャルではDBの長さを255に設定することが推奨されている!!
◆暗号化されたものの一致確認
password_verify(暗号化前,暗号化後)
| 引数 | 内容 | 
|---|---|
| 第1引数 | 暗号化前の値 | 
| 第2引数 | 暗号化後の値 | 
結果は、以下で返る。
- true :一致
- false:不一致
◆バッファリング
PHPのバッファは、バッファ中の出力がファイルでなくメモリ上に行われる。
(画面に表示されず、メモリ上に書かれる!!)
メモリ上の出力は、バッファ中に関数を実行することで変数に格納できる。
//バッファ開始
ob_start();
//バッファ終了&メモリ解放
ob_end_clean();
//バッファ中のメモリ書込み内容を取得
//変数にバッファ中の処理を格納。上書きではなく、後ろに追加していく!!
$変数=ob_get_contents();
※ob_start中にob_get_contentsしなかったものは闇に葬られる…ナム
◆新規ファイルの作成・保存
新しいファイルを作る命令。
file_put_contents(新規ファイルの相対パス,ファイルの中身);
| 引数 | 内容 | 
|---|---|
| 第1引数 | 新規ファイルの相対パス | 
| 第2引数 | ファイルの中身 | 
◆別ファイルの読み込みを行う(教科書102P、105P)
require "ファイルのパス";
- 
require/require_once- ファイルがないときFatalエラー
 
- 
include/include_once- ファイルがないときwarning ※テスト用
 
~_onceは、一つのファイル内で同一ファイルを2回読み込めない
テスト段階で、読み込みファイルができていない時はincludeにし、
読み込みファイルの完成後はrequireにする等の運用を行う。
- 一回しか読まないものは事故防止でonce!!
- 
includeは開発用なので残さない!!
require_once "ファイルのパス";
◆class(教科書119P~)
class クラス名{
// ︙
}
工場で作られる製品の、「設計図」のようなもの。
■インスタンス
「量産品」のようなもの。(工場出荷状態)
インスタンスの作成は、「new演算子」を使用。
classのプログラムは複数存在できる(別々に動かせる)
class ~{//←classはprivate/publicが必要
    private ~ //←privateは直接アクセスできない
    public ~ 
}
◆class‐class内の変数/関数
■アクセス方法
以下を指定する必要がある。
- 
public:直接使用可
- 
private:class内(インスタンス)からのみ使用可
- 
protected:class内および継承(子)classのみで使用可
※定数は上記の設定は不要。publicと同様の扱い
■変数・関数を使用
- インスタンス内:「$this->変数名/関数名」
- インスタンス外:「$インスタンス名->変数名/関数名」
- 定数:「::」を使用
◆class‐class内定数
const 定数名;
■インスタンス内
- 
self::定数名
 インスタンス内で定数にアクセス
■クラス外
- 
クラス名::定数名
 クラス外ではインスタンスなしにアクセス可能
◆class‐static(共通の値を持つ変数)
public static $変数名;
echo $インスタンス::$変数名;
- クラスの中にあり、定数ではなく(中身を変更でき)&全インスタンスで共通の値を持てる
- 
publicと併用(インスタンスの生成に関係なくアクセス可)
- アクセスは定数同様「::」「self」を用いる
※別インスタンスからアクセスしても、値は共通になってしまう
◆class‐コンストラクタ
インスタンス生成時に自動実行される関数。
値を受け取りたい時は適宜。
◆class‐デストラクタ
インスタンス破棄時に自動実行される関数。
<インスタンスの破棄>
- 明示する場合 :unset(インスタンス名)
- 明示しない場合:PHPプログラム終了時に自動破棄
値は渡せないのでなし
◆名前空間
<?php
//※ファイルの1行目は絶対<?php
namespace エリア名;
//※2行目は絶対名前指定
他者のプログラムを使用する際、変数/関数名の被り(衝突)が発生しないよう、
エリアで名前を付与できるようにしたのが名前空間。
変数は名前空間が適用されない=上書きしてしまう!!
ので、上書きを防ぐのに変数はclassに入れる
以前は開発者別のコードを名前に付与したりした

