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側でのファイル選択

INPUT要素でtype="file"を指定し、サーバー側で参照するためのname属性を設定する。

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メソッドを指定したそのフォームからの送信でないと効果がない。

 

MYSQL – インポートできない

文字コード

ローカルにインストールしたMySQL/phpMyAdminからクラウド上の別のphpMyAdminにテーブルをエクスポート、インポートしようとしたところ、’Unknown collation: ‘utf8mb4_unicode_520_ci’でインポートできなかった。元のMySQLがVer8でインポート先がVer5だったためらしい。テキストのSQLの文字コード部分を変更して読み込み。

  • utf8mb4→utf8
  • utf8mb4_unicode_520_ci→utf8_general_ci

 

PHP/MySQL – トランザクション確認(PDO)

概要

PHPのオブジェクト型(PDO)でMySQLのトランザクションを確認。

トランザクション中の動作はデータベースステートメントには設定されるが、トランザクション終了後のコミット/ロールバックによって設定結果がデータベースに反映されるかどうかが決まる。

確認コード

  1. 5行目でトランザクションでコミットフラグをtrueにセット
  2. 通常モードで’one’を書き込み
  3. 14行目でトランザクション開始
  4. ‘two’, ‘three’を書き込み
  5. 25行目でコミット、トランザクション確定
    • 通常モードへは自動的に復帰

確認結果

以下、出力を見ながらトランザクションの動作を確認。

  • 通常モードでは普通に書き込み
  • トランザクション開始後、データベースステートメントの内容は指示通り設定
  • トランザクション終了後、データベース内容の変更が確認できる
  • 通常モード復帰後も普通に書き込み

以下は出力結果で、終了後のデータベースの内容は’one’, ‘two’, ‘three’, ‘four’となる。

次にコミットフラグを$commit=falseにすると、commit()メソッドではなくrollback()メソッドが実行され、実行結果は以下のようになる。

  • 通常モードで普通に’one’が書き込まれる
  • トランザクションに入り、データベースステートメントには’two’, ‘three’が設定される
  • トランザクション終了後にロールバックされると、データベースステートメントがデータベースに反映されてもトランザクション中の’two’, ‘three’は書き込まれない
  • 通常モードに復帰後’four’が書き込まれる