3値論理とNULL

http://codezine.jp/a/article/aid/532.aspx

 しかし、NOTの場合は単純だからいいとして、ANDとORの組み合わせを全部覚えるのはなかなか大変です。そこで、3つの真理値の間に次のような優先順位があると考えてください。
* ANDの場合: false > unknown > true
* ORの場合 : true > unknown > false
 強い方が弱い方を呑み込みます。例えば、「true AND unknown」なら、unknownの方が強いので、結果もunknownになります。ところが、「true OR unknown」の場合、今度はtrueの方が強くなるので、結果はtrueになります。この順位を覚えておけば、3値論理演算も見通しがよくなります。特に、ANDの演算にunknownが含まれた場合、結果が絶対にtrueにならないという特徴をよく覚えておいてください。後でこれが重要なキーになります。

http://codezine.jp/a/article.aspx?aid=532&p=2

NOT INのサブクエリで使用されるテーブルの選択列にNULLが存在する場合、SQL全体の結果は常に空になります。これは恐ろしい現象です。
正しい結果を得るには、EXISTS述語を使って書きます。
EXISTS述語が絶対にunknownを返さないからです。EXISTSは、trueとfalseしか返しません。そのために、INとEXISTSは同値変換が可能なのに、NOT INとNOT EXISTSは同値ではないという紛らわしい状況が生じています。

http://codezine.jp/a/article.aspx?aid=532&p=2

...これは、入力が空テーブル(空集合)だった場合はNULLを返すという極値関数の仕様によります。...入力が空テーブルだった場合にNULLを返すのは、極値関数だけではありません。COUNT関数以外の集約関数もそうです。

unlink

[PHP-users 23600] Re: バージョンアップ後にunlinkでエラー

> オープンしたままのファイルに対して削除(unlink)するなんて
> ルール違反ですしOS、バージョン、タイミングによって
> 挙動が変化するのは当然です。
まさにおっしゃる通りで、基本的には OS によって挙動が変化するのは当り
前ですが、UNIX 系の OS では一時的に作成したテンポラリファイルを確実に
消す方法としては
open 直後に unlink して、そのまま使いつづける
というのは定番的な tips だったりします。
というのは、どれかのプロセスがそのファイルをオープンしていた場合、そ
のオープンしている最後のプロセスがファイルを close するまで、そのファ
イルは存在しつづけることが保証されるからです。確か POSIX でもそう決まっ
ていたはず。
どういうときに嬉しいかというと、先ほども書いたようにプログラム内で一
時ファイルを作るときです。プログラム内で一時ファイルを使用終了したら
unlink するという処理でも良いのですが、それではエラーで終了するときに
もいちいち unlink しなければなりませんし、予想外の異常終了の場合は一時
ファイルが残ったままになってしまいます。open 直後に unlink しておけば、
例えどんなケースであれ、プロセスが終了したら確実にファイルは消去されま
す。

array_walkの三番目の引数はarray

PHP: array_walk - Manual
bool array_walk ( array &array, callback funcname [, mixed userdata] )

通常、 funcname は引数を二つとります。 array パラメータの値が最初の引数、 キー/添字は二番目の引数となります。 オプションの userdata パラメータが指定された場合、 コールバック関数 funcname への三番目の引数として渡されます。

※このuserdataはarrayで受け渡しする。

入力文字コード変換

内部エンコーディングと出力エンコーディングが異なる場合は、php.iniでは入力エンコーディング変換をせず、mb_convert_variablesなどで、自力で変換する。
※mb_convert_variablesでは、だめな場合がある。
これは、

mb_convert_variables() は、エンコーディング検出の ためにArrayまたはObjectの文字列を結合します。これは、 エンコーディング検出は短い文字列では失敗する傾向があるためです。このため、 1 つの配列またはオブジェクトにエンコーディングを混ぜることはできません。

だからだろうか?
なので、
array_walkとmb_convert_encodingで再帰処理する。
また、
変換するのは$_POSTのみにする。$_GET、$_COOKIE、$_REQUESTは変換しない。
例:


function convert_encoding(&$item, $key, $encoding){
  if (is_array($item)){
    array_walk($item, 'convert_encoding', $encoding['to'], $encoding['from']);
  } else {
    $item = mb_convert_encoding($item, $encoding['to'], $encoding['from']);
  }
}
//array_walk($_GET, 'convert_encoding', array('to' => $internal_encoding, 'from' => $http_output));
array_walk($_POST, 'convert_encoding', array('to' => $internal_encoding, 'from' => $http_output));
//array_walk($_COOKIE, 'convert_encoding', array('to' => $internal_encoding, 'from' => $http_output));
//array_walk($_REQUEST, 'convert_encoding', array('to' => $internal_encoding, 'from' => $http_output));

mb_convert_variables
PHP/tips/日本語環境php.ini設定 - PukiWiki

mbstring Shift_JISを使う場合

入出力にShift_JISを使用する場合は、以下のmbstring設定が必要。

※このやり方はよくない。下記を参照。

mbstring.encoding_translation = On (php.ini または .htaccess)
mbstring.http_input = auto (php.ini または .htaccess)
mbstring.language = Japanese (php.ini または .htaccess またはスクリプト)
[php.ini]
;; HTTP 入力変換を有効にする
mbstring.encoding_translation = On
;; HTTP 入力エンコーディング変換を auto に設定
mbstring.http_input = auto
[.htaccess]
# shift_jis の場合のためのmbstring設定
# HTTP 入力変換を有効にする
php_value mbstring.encoding_translation 1
# HTTP 入力エンコーディング変換を auto に設定
php_value mbstring.http_input auto
[スクリプト]
mb_language($language);
mb_internal_encoding($internal_encoding);
mb_http_output($http_output);
//mb_detect_order('auto');
mb_substitute_character('none');

PHP: マルチバイト文字列関数 (mbstring) - Manual

※このやり方はよくない。

Shift_JISの場合はこれでいけるが、エンコードを動的に切り替える場合、UTF-8で入力エンコードがおかしくなる。
php.iniや.htaccessで、入力エンコーディング変換をせず、スクリプトで変換が必要な場合だけ、自力で変換する方がよい。
入力文字コード変換

urlパラメータに使用できない文字

symfonyでは、urlパラメータに以下の文字は使用できない。
? & /
「?」と「&」は、routing処理で区切り文字になっているため。
「/」は、apacheのpathinfoで%2Fを使用できないからだろう。これは、apacheでpathinfoを使用しているサイトはみな同じだ。
voxでは「?」と「&」はOKだが、「/」はつけることはできるが、「/」タグの記事一覧は見ることはできない。Not Foundになる。
movable type は「?」「&」「/」とも、タグとしてつけることはできない。

デバッグメッセージの出力方法

// in an action
$this->logMessage($message, $level);
// in a template
<?php echo log_message($message, $level) ?>

例:

<code>
// in a template
<?php use_helper('Debug') ?>
<?php echo log_message('{mainActions} been there', 'err') ?>
// in an action
$this->getLogger()->info($message);
$this->getLogger()->err($message);
$this->getLogger()->warning($message);
// from anywhere in your application
sfContext::getInstance()->getLogger()->info($message);
sfContext::getInstance()->getLogger()->err($message);
sfContext::getInstance()->getLogger()->warning($message);
</code>

There are 8 levels of log messages:
emerg, alert, crit, err, warning, notice, info, debug
http://www.symfony-project.com/book/trunk/debug