PDOのプリペアステートメントでORDER BY句が動作してくれない。
つまりこういうこと。
やりたいことは、同じテーブルに対してさまざまな条件でソートしたいだけ。
ORDER BY の後を変数でSQL文に渡したいだけなのです。
例えば従業員一覧テーブルで、
$stmt = $pdo -> prepare("select * from `staff_table` order by age"); $stmt -> execute();
これは何の問題もない(とりあえず昇順降順は省略)。ところが、
$stmt = $pdo -> prepare("select * from `staff_table` order by :age"); $stmt -> bindValue(':age', "age", PDO::PARAM_STR); $stmt -> execute();
これが全く効かない。
エラーも全く吐き出さず、primary_keyであるスタッフID順に取り出してくれる。
ageを変数にしてみてもダメ。何してもだめ。
さっきからいろいろググってみてるんだけど、例文はwhere句ばっかり。
やっと見つけたページでは、結局ここの部分だけは変数そのまま突っ込むって解決法。さわやか。文句も言えんわ。
http://stackoverflow.com/questions/2542410/how-do-i-set-order-by-params-using-prepared-pdo-statement
あれこれ頑張って英語のサイトとか調べてたんだけど、どうやらテーブルのカラムはプレースホルダーに出来ないらしく。
合ってます?
とにかくそういうことだと理解。
もしかして、これって常識なの?俺が知らなかっただけ?
とにかく、結局変数のまま突っ込むしかないってことか。
まあ、カラム名なので、変数の段階できちんとチェックしてインジェクション対策をやっとけばOKなのかな。
カラム名のみの配列を取得して、その中での存在チェックして、って感じでOKなんかな?
他に方法知ってる方いらっしゃいましたら教えて下さいませ。
毎日一回バックアップを自動でやる設定
ここの記事を参考に。
http://masha.maakikaku.jp/2007/05/mysql.php
phpMyBackupPro というフリーウェアだけど、日本語パッチも配布していてイイ感じ。
記事の内容どおり設定してうまく行きました。
続いて、毎日午前1時に自動的にバックアップを取るようにレンサバ側のcron設定。
これはsakuraサーバーということで
http://zapanet.info/blog/item/2467
このあたりを参考に。
で、いったん時間設定を今から5分後にしてみて、ちゃんとバックアップファイルが指定メールアドレスに届いたのを確認して午前1時に戻す。
簡単。以上。
SQLインジェクション対策について
いろいろな記事を読んで読んで、まあひとつの結論にたどり着いた。
■単にプリペアドステートメントを使え
■文字列結合でSQLを構築するな
from: http://d.hatena.ne.jp/ajiyoshi/20100409/1270809525
ということで、昨日全てPDOで書き直したSQL文をこの原則に沿って再度修正していきます。
※上記記事で必読とされていた「安全なウェブサイトの作り方」の
「安全なSQLの呼び出し方」
http://www.ipa.go.jp/security/vuln/websecurity.html
※あと、とても参考になった徳丸記事
「SQLインジェクション対策」でGoogle検索して上位15記事を検証した
http://d.hatena.ne.jp/ockeghem/20111109/p1
PHP PDOの「bindParam」と「bindValue」の違い
今書いてるやつのDBまわりをPDOで書き直す遊び中。
bindParam(':id',$value,PDO::PARAM_INT);
と、
bindValue(':id',$value,PDO::PARAM_INT);
の違いについてだけど、bindされるタイミングの違いらしく。
bindParamだと、execute()の実行時、
bindValueだと、bindValue実行時
ということだそうな。
参照: http://webmaster.chielog.com/php/133.html
executeメソッドでは型の指定ができず、全て文字列で処理されるそうな。
したがって、数値型で処理したい場合はbindValueを使うということになりそう。
ここ参照。
http://oshiete.goo.ne.jp/qa/5656159.html
セキュリティ関連メモ
やったこと。
[1]大事なファイルをインクルードファイルにしてドキュメントルートの上に置く。
[2].htaccessでいくつかの拡張子を deny from allに。
[3]indexファイルが無い場合の挙動を拒否に。レンサバの仕様か、htaccessで設定しようとしたら500が出る。レンサバのファイルマネージャーから設定できた。
[4]※.htaccess クリックジャッキング対策。「Header set X-FRAME-OPTIONS "DENY"」追記したら500に。どうやらレンサバの仕様でOPTIONSの記述がNGなようだった。
ということで、HTMLにメタタグで記述。
<meta http-equiv="X-FRAME-OPTIONS" content="DENY" />
[5]CSRF対策。これはhttp://ss.hamachiya.com/easy_csrf/ が便利そうなので拝借。取り急ぎ一部だけ導入。あとはゆっくり全部やっていく。
[6]いくつかの設定項目や関数をまとめて外部ファイルに。
これからやること
PHPのエスケープ文字をスグ忘れる
\n 改行
\r キャリッジリターン
\t タブ
\\ \文字
\$ $文字
\( 左括弧
\) 右括弧
\[ 左括弧
\] 右括弧
\' シングルクオーテーション
\" ダブルクオーテーション
\nnn 8 進数表記
\xnn 16 進数表記
です。
PHP POSTで受け取ったデータ数が分からん場合にとりあえず配列に格納する
<?php foreach($_POST as $key => $val){ // データを配列に代入 $data_arr[$key] = $val; }
なるほど。