PHPのODBC関数を使うときの注意点
PHPのODBC関数でプリペアードステートメントを使うには
odbc_prepare, odbc_executeの2つの関数を使います。
例1
<?php $a = 1; $b = 2; $c = 3; $stmt = odbc_prepare($conn, 'CALL myproc(?,?,?)'); $success = odbc_execute($stmt, array($a, $b, $c));
odbc_executeの第2引数にはパラメータの配列($parameters_array)を渡す。
ただし、次のような注意点がある。
parameter_array の中でシングルクォートで括られたデータがある場合、 それはファイル名と解釈されます。そのファイルの内容が、 該当するプレースホルダのデータとしてデータベースサーバに送信されます。
だから
シングルクォートで括られたデータを純粋に文字列として使用したい場合は、 空白などの別の文字を前後に付加する必要があります。 それにより、パラメータがファイル名とみなされることがなくなります (もしこのオプションが不要なら、別の仕組み、たとえば odbc_exec() で直接クエリを実行するなどを使用する必要があります)。
つまり、「''でくくられた文字列をファイル名とみなす」という特例を必要としない場合*1例1のコードはそのままの形で使用することはできない。
次のような「'で始まり'で終わる文字列の末尾に空白を付ける関数」なりなんなりでパラメータをエスケープしなければならない。
例2
<?php function odbc_escape_params ($params) { if (!is_array($params) or empty($params)) { return array(); } foreach ($params as $key=>$val) { if (strlen($val) > 1 and $val{0} == "'" and $val{strlen($val)-1} == "'") { $params[$key] .= ' '; } } return $params; }
これでとりあえずしのげはするが、''でくくられた文字列をそのままの形でDBに収めることは結局できてないわけだ。。。はあ。。。
参考・引用元: PHPマニュアル
http://www.php.net/manual/ja/function.odbc-execute.php
*1:ほとんどの人はそうだろう
php-modeからPHP Manualを開く
Emacsにはデフォルトでphp-modeあるけどまずインデントからしておかしいのでこっち使いましょう、ってのが前提。
PHP mode for Emacs http://php-mode.sourceforge.net/
このphp-mode、マニュアルへのジャンプ機能があるみたい。
C-cRETでマニュアルのトップページへジャンプ、
C-cC-fでカーソル位置の単語についての説明ページを開いてくれます。
そのままだと英語のページが開きますが、
設定すれば日本語のPHPマニュアルが開けます。
<?php (setq php-search-url "http://www.php.net/ja/") (setq php-manual-url "http://www.php.net/manual/ja/")
PHPの->がよくわからない
array_map($func, $array)じゃなくて$array->map($func)って書きたいよなあと思ってちょっとやってみたんだけど、チェーンすると
PHP Fatal error: Unsupported operand types in ...
ってなる。なんでだろう。
<?php class MyArray { private $array; public function __construct() { $this->array = func_get_args(); } public function map($func) { return new MyArray(array_map($func, $this->array)); } public function copy() { return new MyArray($this->array); } } $array = new MyArray(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); $double = function ($x) { return 2 * $x; }; var_dump($array->map($double)); var_dump($array->map($double)->copy()); //これはできる var_dump($array->copy()->map($double)); //これはできない
関数渡すとだめだったりすんのかなあ。わからん。
PHPのuse
#wpscala にて、Scalaでは「1から100までの素数」がこれで得られますよー、ってのをやったんだけど
(0 to 100).filterNot(n => (2 until n).exists(n % _ == 0))
\ キャー、みじかーい /
そこでPHPでやってみようと思った。
ちょうど仕事で使うPHPのバージョンがやっと5.3になったので無名関数を使ってみたかったのです。
<?php print_r(array_filter(range(1, 100), function ($a) { if ($a == 1) return true; return ! array_filter(range(2, $a - 1), function($b) use ($a) { return $a % $b == 0; }); }));
まあともかくPHPでクロージャを作ったり、親?のスコープで定義されてる変数を見たいときはuseというキーワードを使うらしい。
PHP: 無名関数 - Manual http://php.net/manual/ja/functions.anonymous.php
PHPのstrtotime()がなんだかすごい
PHPのstrtotime()関数は
英文形式の日付をいい感じにUnixタイムスタンプに変換してくれます。
最高にきもい便利です。
たとえば
<?php echo strtotime("now"), "\n"; ?>
これで現在のタイムスタンプが取得できます。
なんだかこれだけ見てもPHPのかほりがしますね。
一日後、一週間後のタイムスタンプがほしいなあ、ってときは
<?php echo strtotime("+1 day"), "\n"; echo strtotime("+1 week"), "\n"; ?>
これでいけます。
混ぜてもいけます。
<?php echo strtotime("+1 week 2 days 4 hours 2 seconds"), "\n"; ?>
<?php echo strtotime("10 September 2000"), "\n"; ?>
こういうのもOK。これはその日の0時のタイムスタンプを返します。
まあこのくらいならわかるけど、
<?php echo strtotime("next Thursday"), "\n"; echo strtotime("last Monday"), "\n"; ?>
ここまで来るとさすがって感じがしますね。
で、もしかしてできるんじゃね?って思って適当に
<?php echo strtotime("today"), "\n"; echo strtotime("yesterday"), "\n"; echo strtotime("tomorrow"), "\n"; ?>
ってやったらできました。
でも
<?php echo strtotime("tommorrow"), "\n"; ?>
スペルミスするとfalseが返ってくるので注意しましょう。
PHP + flymake
phpでflymake使おうと思ったんだけど
flymakeの設定のしかた調べるのめんどかったから
適当にネット徘徊して設定パクろうと思った。
メモメモ
ついでにjsとrubyのもくっついてますね。
VimからEmacsに乗り換えたので便利機能紹介します - 八発白中
(when (require 'flymake nil t) (global-set-key "\C-cd" 'flymake-display-err-menu-for-current-line) ;; PHP (when (not (fboundp 'flymake-php-init)) (defun flymake-php-init () (let* ((temp-file (flymake-init-create-temp-buffer-copy 'flymake-create-temp-inplace)) (local-file (file-relative-name temp-file (file-name-directory buffer-file-name)))) (list "php" (list "-f" local-file "-l")))) (setq flymake-allowed-file-name-masks (append flymake-allowed-file-name-masks '(("\.php[345]?$" flymake-php-init)))) (setq flymake-err-line-patterns (cons '("\(\(?:Parse error\|Fatal error\|Warning\): .*\) in \(.*\) on line \([0-9]+\)" 2 3 nil 1) flymake-err-line-patterns))) ;; JavaScript (when (not (fboundp 'flymake-javascript-init)) (defun flymake-javascript-init () (let* ((temp-file (flymake-init-create-temp-buffer-copy 'flymake-create-temp-inplace)) (local-file (file-relative-name temp-file (file-name-directory buffer-file-name)))) (list "/usr/local/bin/jsl" (list "-process" local-file)))) (setq flymake-allowed-file-name-masks (append flymake-allowed-file-name-masks '(("\.json$" flymake-javascript-init) ("\.js$" flymake-javascript-init)))) (setq flymake-err-line-patterns (cons '("\(.+\)(\([0-9]+\)): \(?:lint \)?\(\(?:Warning\|SyntaxError\):.+\)" 1 2 nil 3) flymake-err-line-patterns))) ;; Ruby (when (not (fboundp 'flymake-ruby-init)) (defun flymake-ruby-init () (let* ((temp-file (flymake-init-create-temp-buffer-copy 'flymake-create-temp-inplace)) (local-file (file-relative-name temp-file (file-name-directory buffer-file-name)))) '("ruby" '("-c" local-file))))) (add-hook 'php-mode-hook '(lambda () (flymake-mode t))) (add-hook 'js-mode-hook (lambda () (flymake-mode t))) (add-hook 'ruby-mode-hook (lambda () (flymake-mode t))))
followerの一覧を取得するPHPスクリプト
http://github.com/abraham/twitteroauth
↑これ使いました。
<?php require_once("twitteroauth.php"); $consumer_key = "[consumer_key]"; $consumer_secret = "[consumer_secret]"; $access_token = "[access_token]"; $access_token_secret = "[access_token_secret]"; $to = new TwitterOAuth($consumer_key,$consumer_secret,$access_token,$access_token_secret); $next_cursor = -1; do{ $req = $to->OAuthRequest("https://api.twitter.com/1/statuses/followers.xml", "GET", array("cursor"=>"$next_cursor")); $xml = simplexml_load_string($req); $next_cursor = $xml->next_cursor[0]; foreach($xml->users->user as $user){ $screen_name = $user->screen_name; print $screen_name . "\n"; } }while($next_cursor != 0); ?>
りむったー、ってあるけどあれってどうやってんのかなーと思って。
自分だったらcronでこれ走らせてdiff取るかなあとか。
しっかしPHPは楽だなあ。