Japan.R 2014で絶対に描いてはいけないグラフ入りスライド12枚と題して発表してきました。発表時間は5分という制約があったので、あえなく当日のスライドは半分に。本来発表に使いたかったものを含めてスライド数は倍にしての公開です。
2015年2月2日月曜日
2014年11月27日木曜日
Rでオブジェクトの存在を確認する方法
Rでは変数名の上書きをうっかりしないよう、プログラマは変数を意識してコードを書かなければならない。そこで、Rにおいてオブジェクトが既に存在しているか確認する方法についていくつか挙げてみる。
- ls()関数
- オブジェクトの一覧を表示する関数である。search()関数を利用するとサーチパス上にある名前空間の一覧をすべて見ることができる。
> search() [1] ".GlobalEnv" "package:stats" "package:graphics" [4] "package:grDevices" "package:utils" "package:datasets" [7] "package:methods" "Autoloads" "package:base"
単にls()とすると、".GlobalEnv"の中にあるオブジェクト一覧が表示される。
> a < -5 > ls() [1] "a"
他の名前空間にあるオブジェクト一覧を知りたいというときは、search()関数で分かった順番を基に、pos引数を使って指定すればよい。以下の例では、2番目の値にあったstatsパッケージのオブジェクト一覧を見ていることになる。> head(ls(pos=2)) [1] "acf" "acf2AR" "add.scope" "add1" "addmargins" [6] "aggregate"
- exists()関数
- オブジェクトの存在をダイレクトに確認するのであれば、この関数を利用するとよい。
2014年10月31日金曜日
PHPにおける文字のエスケープ処理
magic_quotes_gpcというオプションがphp.iniにある。このオプションが有効になっていると、データを渡していくことを繰り返すうちに文字列のエスケープの回数が増えるという問題が発生するそうだ(詳しくはこちらを参照)。オプションが有効化されていることで、エスケープされてしまう文字としては5c問題に該当する文字になる。そこで、一般的な処理としてどのようにエスケープ処理のコードを書くのかということについて示しておく。今回はDB(PostgreSQL)に入れるための文字列がフォームから入ってきた場合を想定しておく。
<?php
function convert_str_for_query($string){
if( get_magic_quotes_gpc() ){ // magic_quotes_gpcオプションの状態を取得
$string = stripslashes($string); // 全体に対しバックスラッシュを取り除いた文字列を返す
}
$string = htmlspecialchars($string); // <や&のような文字列をエスケープする
// 上のコードは一般的には表示の際に対策を立てておくためと考えられる
$string = pg_escape_string($string); // PostgreSQLのクエリとなる文字列をエスケープする
// ちなみにMySQLであれば、$string = mysql_real_escape_string($string); とする
return $string;
}
?>
2014年10月28日火曜日
PHPmemo_day15
PHPの基本に関するメモ。参考にしているのはPostgreSQL徹底入門の第5章です。
- header関数を用いることで、charsetを指定することができる。htmlのheadタグ内に書かなくてもよい。またリダイレクト先を指定することもできる。書き方は以下のコード参照。
-
<?php header('Content-Type: text/html; charset=UTF-8'); // 文字コードの指定 header('Location: リダイレクト先のURL'); // リダイレクト先の指定 ?> - pg_query_params関数は文字列を挿入してqueryを実行する関数であるが、自動的にエスケープ処理を行うことができる。これによりSQLインジェクションを回避することができる。
- PHPにもCやJavaと同じく三項演算子がある。
- $_REQUESTというスーパーグローバル変数がある。これはphp.iniのvariables_orderの項目でリクエストの内容をマージしたものが含まれている。普通は$_GET、$_POST、$_COOKIEの優先順位となる。リクエストメソッドに関係なく、$_REQUESTから参照すればパラメータの値を受け取ることができる。
- htmlのコードとしてPHPを入れる場合はinclude関数でファイルを読み込む。同じファイルで何度も読み込む場合があるのでinclude_once関数自体はあるが一般的ではない(何度も読み込むミスを防ぐ場合に使う)。関数を読み込みたい場合はrequire_once関数を使うという棲み分けがある。
- 最近のwebシステムにおけるユーザ登録ではメールを仮登録し、仮登録した先のメールアドレスに本登録用のURLを送ることでメールアドレスが正しいものであるか検証することが多い。メールアドレスの形式が妥当なものであるか判断するのは厳しくしすぎないようにしておく(厳密にRFCに従っているか調べるということまではしないということ)。
- パスワードを単純にsha1関数で暗号化したものを保存しておくのは、レインボーテーブル(暗号化前の文字列と暗号化後の文字列がペアになったテーブル)により、容易にパスワードが破られる可能性があるためよくない。そこで、ソルトと呼ばれる、ランダムな文字列を適当につけてから暗号化することにより、レインボーテーブルによるパスワード対策を行うことができる。
- require関数はリダイレクトすることになるが、このときリダイレクト先はURLではなく相対パスにしなければならない。ファイルの位置関係で指定の仕方が変わってくることに注意。
- HTTPの仕様として、データは文字列でやりとりされるので、0という値がブラウザから渡されるとそれは数値ではなく文字列となっている。ただしPHPでは配列の添字の数字は数値として扱われる。以下の例では10は数値として、testという文字列はtestという文字列で扱われることになる。
-
<?php <a href="?a[]=1&a[10]=5&a[test]=10">link</a> ?>
- pg_affected_rows関数はDELETEをクエリで実行した際に影響を受けた行数を返す関数である。これを利用して削除処理の成功/不成功を判定することができる。
- ini_get関数でクッキーを使っているか確認できる。session_get_cookie_params関数でクッキーのパラメータを取得し、session_name()関数の返り値となるセッション名に空文字を設定することでセッションIDをクリアできる。サーバ上のセッションファイルはsession_destroy関数を呼び出せばOK。
- トランザクション機能を使うと、一連の処理におけるSQLの実行が途中で失敗しても、その処理の直前までもとに戻すことができる。
-
<?php pg_query(コネクション名, 'BEGIN'); (ここに書いたSQL文がトランザクションになる) pg_query(コネクション名, 'COMMIT'); ?>
2014年10月25日土曜日
PHPmemo_day14
PHPの基本に関するメモ。参考にしているのはPHPによるWebアプリケーションスーパーサンプル第2版の第13章(処理制御)です。Smartyなど素のPHPとは関係のないところは省略。
- スクリプトを途中で終了する場合にはexit関数、die関数を使う。前者は終了時にエラーメッセージを出さないのに対し、後者は終了時にエラーメッセージが出てくるようになっている。関数の引数に文字列を与えることでエラー時のメッセージを制御することができる。また、関数を引数に与えることで異常時でも正常終了させるなどすることができる。
- 処理を一時停止するにはsleep関数を使う。これは秒単位で停止する。マイクロ秒単位で制御する場合はusleep関数を用いる。
- エラーメッセージの抑制は変数、関数の前に@マークをつけることでできる。例えば@num = 10/0;のようにすればnumに関するエラーメッセージは出なくなる。
- error_reporting関数はエラーを表示させるレベルを設定できる。関数を呼出した後からレベルが変化する。
- error_log関数はエラーメッセージを任意のファイルに送信することができる。Webサーバのログ、メールなどにも書き込める。
- trigger_error関数を使うと、ユーザエラーを発生させることができる。このとき、引数にE_USER_ERRORを指定することになる。
- header関数でHTTPヘッダを送信することが可能になる。例えばLocationヘッダを指定することで移動先のURLを指定できる。
- exec関数を利用すると外部プログラムを実行する。exec関数は返り値を要求しない場合に使う。system関数は標準出力を返してくる。
- 外部プログラムでシェルを使うときはescapeshellargでシェル引数として与える文字列をエスケープしなければならない。これはexec、system関数の両方に対して言える。
2014年10月23日木曜日
PHPmemo_day13
PHPの基本に関するメモ。参考にしているのはPHPによるWebアプリケーションスーパーサンプル第2版の第12章(セッション/クッキー)です。
セッションはデータの受け渡しに使われる、ユーザの情報を継続して管理するための仕組みである。
- セッション情報が置かれるディレクトリはphp.iniのsession.save_pathに書かれている。
- セッションの自動開始はphp.iniのsession.auto_startを参照する。1であれば自動で始まる。
- セッションの開始をスクリプトで制御するにはスクリプトの最初の方で、session_start関数を呼び出せばよい。
- セッション変数はスーパーグローバル変数で、$_SESSIONである。$_SESSION["name"]="abc";のように設定すればよい。これはPHP5以上であれば問題なく利用できる。
- 設定されたセッション変数はunsetで削除できる。設定されているかどうかはisset関数で調べられる。
- セッション変数の保存先はsession_save_path関数でスクリプト側から調べることができる。ディレクトリがないと保存できずエラーになるので、そのような問題が発生した場合の調査に用いる関数である。
- session_id関数で現在のセッションIDを取得することができる。クッキーが使用できる場合はクッキーにセッションIDが保存される。クッキーが使えない環境では、ページの遷移の度にセッション変数を遷移先に渡さないとセッション情報が引き継げない。
- セッションハイジャックを防ぐ方法としてsession_regenerare_id関数を使う方法がある。この関数はセッションIDを新しいものに置き換えることができる。最近のPHPではsession_regenerate_id(TRUE)とすることで、古いセッションデータが削除され、よりセキュアになる仕組みが提供されている。
- クッキーはユーザ側でデータを保存するための仕組みである。ただし、悪意あるサイトなどにクッキーの情報を盗まれる危険性があるので、カード番号などの重要情報はクッキーに設定しないようにしておく必要がある。
- クッキーにデータを設定するにはsetcookie関数を用いる。参照する場合は$_COOKIE["変数名"]とする。setcookie関数の引数には変数名、値、有効期限、パス、ドメイン、HTTPSが必要か否かを与えることができる。
- クッキーのデータを削除するには、setcookie関数の引数に古い有効期限を与えればよい。それにより特定の変数名のデータを削除することができる。削除されたことを確認するにはisset関数の返り値がFALSEになっていることを調べればよい。
2014年10月22日水曜日
PHPmemo_day12
PHPの基本に関するメモ。参考にしているのはPHPによるWebアプリケーションスーパーサンプル第2版の第2章(フォーム)後半です。
- SQLコマンドに入る文字列をエスケープするにはmysql_real_escape_string(MySQL)、pg_escape_string(PostgreSQL)などの関数を用いる。ただし、php.iniでmagic_quotes_gpcをOnにしている場合、一旦stripslashes関数で文字列のエスケープ処理を解除してからDB専用の関数でエスケープ処理を行うのが良い。
- フォームから受け取った値を用いてSQLクエリを構成する場合、数値は数値に変換してから挿入する。つまりintval関数で数値に変換するか、sprintfを使って数値を受け取る場合は"%d"として受け取ることになる。
- フォームから受け取ったデータをsystem関数、exec関数を用いてシェルに渡すことがある。そのまま渡すと意図しないコマンドを実行される可能性があるので、シェルのメタ文字をエスケープするにはescapeshellcmd関数を用いる。
- 特殊文字をエスケープするにはhtmlspecialchars関数を用いる。ただし「'」をエスケープするには関数の引数にENT_QUOTESを指定する必要がある。また、「"」、「'」をエスケープしない場合はENT_QUOTESを引数に与えることになる。
- htmlタグをフォームから受け取った内容から取り除くにはstrip_tags関数を用いる。悪意のあるコード対策で用いられる。
- 一部のタグだけ置換したいという場合はstr_replaceで置き換える。置換前と置換後の文字列を配列で指定することで複数のタグを一括で置換することもできる。
- リンクに漢字を含むものについてはurlencode関数でエンコードを行う。これにより%5Cのように%と16進数から構成される文字列に置き換えられる。これをもとに戻すにはurldecode関数を用いる。
- textarea内で改行をしても、表示では改行が含まれないようになっている。改行して表示するためにはnl2br関数を用いる必要がある。
- アクセスの種類を判別するにはif( $_SERVER["REQUEST_METHOD"] == "POST" ){ ... }などとする。
- explode関数で区切り文字を指定して、1つの文字列を配列に分割・収納することができるようになる。
- mktime関数は日付をタイムスタンプ形式に変換できる。この関数では3月32日を4月1日のように自動的に解釈するようになっている。
- checkdate関数は指定した年月日がグレゴリオ暦と矛盾がないかを調べる関数である。
- mb_detect_encoding関数は文字コードの検出に使われる。引数で文字コードの検出の優先順位をつけておくことになる。
- 文字コードの変換はmb_convert_encoding関数を使う。
- 「$$変数名」という表記法がある。
-
$a = "abc"; $$a = "xyz"; echo $abc; // xyzと表示される。
登録:
投稿 (Atom)