PHP – 雛形 – Cookie

概要

  • Cookieはサーバー側からクライアントのブラウザーに変数のように情報を記録する仕組み
  • クライアントに対するCookieの設定はsetcookie()関数で行う
    • Cookieの設定の際はtime()関数を使って有効期限をセットする
  • PHPではスーパーグローバル変数$_COOKIEを通して参照する
  • Cookieの削除はsetcookie()で過去の時刻を有効期限としてセットする

基本の流れ

Cookieのセット

サーバー側のPHPでsetcookie()でクライアントのCookieをセットする。

setcookie('キー', 値, 有効期限)

有効期限は現時点からの秒数で指定し、通常はtime()+破棄までの秒数で指定する。

Cookieの参照

クライアントに特定のキーのCookieがセットされているかどうかはisset()でチェック。

isset($_COOKIE['キー']) : true/false

セットされている場合は連想配列としてキーを指定して参照する。

Cookieの削除

Cookieの削除は、setcookie()で有効期限を過去の時刻でセットする。たとえばtime()-ある程度の秒数、0を指定してもよい。

HTMLは以下を処理する。

  • もしPHP側で変数が定義されていれば、既に登録された好きな食べ物として表示
  • 好きな食べ物を登録する

PHPコードでは以下のような処理をしている。

  • Cookieがセットされていればその内容を変数に代入する
  • 全てが空白であれば無視する
  • 空白でなければその内容をCookieにセットする
  • header()関数で改めてこのページを実行しなおす

 

PHP – 雛形 – 全角も含めた文字列のトリム

概要

  • PHPにはtrim系の関数が準備されているが、全角スペースには対応していない
  • str_replace()を使うと、前後だけでなく文字列中のスペースが除去されてしまう
  • そこで、preg_replace()で正規表現によって前後のスペースだけ除去する

実装例

以下のコードの関数の中でトリムを実装している。

第1引数でサーチする文字、第2引数でマッチした文字の変更後の文字、第3引数で対象文字列を指定。

第1引数は「先頭か末尾にある半角か全角のスペース」を表現しているが、その過程は以下のとおり。

  • '/.../u'で正規表現の文字列をUTF-8として扱う
  • '/\A...|...\z/'uで先頭部分か末尾部分を指定
  • [\x20\xE3\x80\x80]は文字クラスで、\x20が半角スペース、\xE3\x80\x80が全角スペースを表し、それらの何れかの文字を指定
  • []++文字クラスの後の++は絶対量指定子と呼ばれるもので、通常使われる最大量指定子+(1文字以上にマッチ)に対してバックトラックが抑制されるとのこと

その他の文字のトリム

文字クラス[]の中に指定する文字列。

\p{Z}
区切り文字(半角・全角スペースも含まれる)。
\p{C}
その他の文字(制御文字)。

PHP – 複数のsubmitで処理を分ける

概要

複数のsubmitから異なるターゲットに遷移するには、formタグでaction属性を設定せず、それぞれのinputでformacion属性を設定する。

一つのターゲットで異なるsubmitごとの処理を分けたいときは、それぞれのinputにname属性を設定し、PHP側のissetでそれぞれが定義されているかどうかによって処理を分けるとよい。

以下のHTMLでは3つのsubmit(送信1、送信2、その他の送信)を配置し、前者2つにはname属性の値として”submit1″、”submit2″を設定し、その他の送信にはname属性を設定していない。

以下はこれを受け取るPHPコードで、isset()によって$_POST['submit1']$_POST['submit2']が定義されていればそれぞれに対応した処理をし、それ以外の場合には「その他の送信」としている。

実行すると3つの送信ボタンが表示され、それぞれを押すとボタンに対応したメッセージが表示される。

 

PHP – 雛形 – 現在日付・時刻

現在の日時の取得

date()関数は引数で指定したフォーマットで日付・時刻の文字列を返す。たとえば現在の日付・時刻の文字列は以下で得られる。

date('Y-m-d H:i:s')

フォーマット文字列の詳細はPHP-manualを参照。

現在のUNIXタイムスタンプ

time()関数はUnix エポック (1970 年 1 月 1 日 00:00:00 GMT)からの通算秒をintで返す。PHP-manual

 

 

PHP – ドキュメントルート外のファイル

スタイルファイル(css)

HTMLのスタイルを別のcssファイルにするとき、ファイルの位置がドキュメントルートの外にあるとlinkタグからは読み込めない。

このようなとき、style定義であればstyle要素の内容としてphpでそのファイルをincludeするとHTML内に展開される。

 

PHP – PDO プリペアードステートメント

基本形

  • $pdo = new PDO()PDOオブジェクトを得る
  • $stmt = $pdo->prepare()でプレースホルダー入りのSQLを準備する
  • $stmt->bindValue()$stmt->bindParam()でプレースホルダーを埋める
  • $stmt->execute()でバインドを有効化する

bindValueによる値の設定

'?'によるプレースホルダー

以下の例では、prepare()のSQL中2つの'?'がプレースホルダーになる。

bindValue()の第1引数は何番目のプレースホルダー'?'かを指定し、第2引数にそのプレースホルダーにセットする値を指定する。第3引数は省略するとPDO::PARAM_STRになる。

この結果、データベースのnum_datastr_dataにそれぞれ10, 'ABC'が追加される。

名前によるプレースホルダー

以下の例では、prepare()のSQL中':num'':str'の2つがプレースホルダーになる。

bindValue()の第1引数でそれぞれのプレースホルダーを指定し、第2引数にそのプレースホルダーにセットする値を指定する。第3引数は省略するとPDO::PARAM_STRになる。

この結果、データベースのnum_datastr_dataにそれぞれ20, 'DEF'が追加される。

bindParamによる変数の設定

bindValue()はプレースホルダーに値を設定したが、bindParam()は変数を設定する。

変数がバインドされた時点ではSQLの内容は決定されていない。変数に値をセットし、execute()を実行した段階でSQLの値が確定する。

この例では2つのプレースホルダーに変数をバインドし、その変数に値を与えてからexecute()を実行している。プレースホルダーに'?'を用いてもよい。

この結果、データベースのnum_datastr_dataにそれぞれ30, 'GHI'が追加される。

 

JS/ES – 雛形・テンプレート

記述場所

bodyセクションの最後かheadセクション内。headセクションに置く場合はDOM生成後に必要な処理は以下の中に記述。

window.onload = function() { ... }

無名関数はアロー関数() => {}でもよい。

DOMの操作

DOMの取得

bodyの取得

document.body

要素名で取得

var element = document.getElementsByTagName('要素名');

'Elements'と複数形であることに注意。結果は配列になる。

idで取得

var element = document.getElementById('ID名');

ID名は#を付けない。結果は単体のDOM。

DOMの内容

要素.innerHTML

innerHTMLプロパティーで直接参照・設定

DOMの作成

var element = document.createElement('要素名');

DOMの追加

body内の指定要素の前に追加

document.body.insertBefore(追加要素, 指定要素);

body内の最後に追加

document.body.appendChild(追加要素);

指定要素の中の最後に追加

指定要素.appendChild(追加要素);

 

PHP – 雛形 – ファイルアップロード

概要

HTML側でアップロードされたファイルをPHP側で受け取り、妥当性のチェック、所定の場所への保存などを行う最低限の手順。

HTML側でのファイル選択

  • FORM要素でenctype="multipart/form-data"を指定する
  • INPUT要素でtype="file"を指定し、サーバー側で参照するためのname属性を設定する
  • 複数ファイルを送る場合はINPUT要素にmultiple="multiple"を指定する

HTML表示の際、デフォルトで”ファイルを選択”ボタンが表示され、これをクリックするとダイアログによるファイル選択が可能となる。

PHPで受け取る値

HTML側からの結果が受信されたとき、スーパーグローバル変数$_FILESに連想配列としてアップロードされたファイルの情報が格納される。以下、'name値'はINPUT要素で指定されたname属性の値。

$_FILES['name値']['error']
エラーコード。PHPで定義された定数でエラーステータスを確認可能。(PHP-manual)
$_FILES['name値']['name']
アップロードファイル名。
$_FILES['name値']['tmp_name']
アップロードされたファイルのフルパス。
$_FILES['name値']['type']
アップロードファイルのMIMEタイプを取得。たとえばimage/jpeg、image/pngなど。
$_FILES['name値']['size']
アップロードされたファイルのサイズ

PHP側の処理

INPUT要素を受け取ったPHP側での最低限の処理の流れは以下のとおり。

  1. $_FILES['name値']['error'] === UPLOAD_ERR_OKでアップロード時のエラーをチェック
  2. 以下の変数を設定
    • $image_file_name = $_FILES['name値']['name'];
    • $tmp_name = $_FILES['name値']['tmp_name'];
    • $type = $_FILES['name値']['type'];
  3. is_uploaded_file($tmp_name)でアップロードファイルの妥当性をチェック
  4. $type === 'image/jpeg' && $type !== 'image/png'でファイルタイプをチェック
  5. move_uploaded_file($tmp_name, IMAGE_DIR . $image_file_name);でアップロードされたファイルを任意のディレクトリー(この場合IMAGE_DIR)に移動
    • この実行結果のtrue/falseに応じてファイル名のデータベースへの登録などの処理を実行

$_FILES['name値']['type']ユーザーから送信されたものなので、偽装・改竄に対する完璧な防御にはならないが、上記は最低限の流れ。

 

JQuery – 要素指定方法

基本形

要素種類

$('要素名')

全てのp要素の色が緑になる。

id指定

$('#id値')

id=1の要素が赤くなる。

クラス指定

$('.class値')

class='target'が指定された要素が青くなる。

包含関係

$('セレクター1 セレクター2')

スペースで並べる→セレクター1に含まれるセレクター2

$('セレクター1 > セレクター2')

'>'でつなぐ→セレクター1直下のセレクター2

$('セレクター1 + セレクター2')

'+'でつなぐ→セレクター1の次に現れるセレクター2

属性値指定

1つの属性値

HTML中の要素のうち、特定の属性が指定された要素をJQueryで指定したい場合。

$('要素名[属性=値])

value属性が"1"div要素が赤くなる。

2つの属性値のAND

$('要素名[属性1=値1][属性2=値2]')

name属性が"NAME"value属性の値が"VALUE"div要素の色が黄色になる。

 

PHP – GETの流れ

概要

GETメソッドの挙動・手順を確認した。

  • 普通にHTML/PHPファイルが呼ばれると、GETメソッドになる
  • なので初回起動時の処理はGETメソッド前提で、$_GET変数は定義済み、要素数0をチェック
  • $_GETの要素数が0より大きければ初回以降のGETメソッド処理
  • 初回以降の$_GETの要素チェックは''との比較でok

確認コード

以下のHTMLとPHPで動作を確認する。

HTML

  • フォームからGETメソッドで送信する
  • 送信するのはテキストボックスの内容のみ
  • PHP側で処理された$msgを出力する

PHP本体

  • 全体の処理開始以降、節目の経過を$msgに累積記録し、HTMLでの出力に備える

結果

初期起動時

HTMLの表示は以下の通り。

  • 起動時にGETで始まっている
  • そのため$_GET変数も定義済みになっている
  • ここには書いていないがvar_dumpで確認すると'Array  ()'となっている
  • ただし$_GETの要素数は0

このときブラウザーでのURL表示は以下のとおり。

起動後のGET時

テキストボックスに’abc’と入れて送信した結果が以下の通り。

このときブラウザーでのURL表示は以下のとおり。ファイル位置の後ろに?でパラメーターが加えられている。

なお、上記の実行後にはテキストボックスの内容は空になっている。

再度GETの実行時

このときのブラウザーでのURL表示は以下のとおり。

リロード時

ブラウザーのリロードで再読み込みをすると、最後に表示されていたURLのままでリロードされ、同じ結果が表示される。

?以降のパラメーター部分を消してリロードしても、元のパラメーターが付加されたURLに戻ってしまう。

パラメーター部分を消してENTER、つまり直接URLを入力すれば初期状態からスタートする。

改竄に対して

上記コードで、Chromeの検証ツールでinput要素のname属性を改竄した場合、元のisset($_GET['get_input'])が存在しなくなるのでチェックが必要。

まとめ

処理の流れ

初回起動時

  • ファイルを最初に実行する場合はGETメソッド
  • 初期起動時の$_GETは要素数0の配列

フォームからのGETメソッド

  • その後フォームからGETメソッドが実行されると、INPUT要素の内容がURLのパラメーターに付加されてページの最初から実行される

リロード時

  • ブラウザー機能でリロードしただけではURLはリフレッシュされず、直前のパラメーターで再実行される

GETのみの場合

処理全体を通してGETメソッドのみの場合、$_SERVERによるチェックは不要になる。

GET処理とPOST処理を併用する場合は、GET処理を切り分ける必要がある。

action属性

form要素のaction属性をaction="./get.php"と設定しても、リロード時には元のパラメーターが復活する。この属性はGETメソッドを指定したそのフォームからの送信でないと効果がない。