SNIとはServer Name Indicationの略でSSLプロトコルの拡張機能。何が?というと名前ベースのSSLサイトが設定できるようになる。つまり、1IP上に複数のSSLサイトを構築できることになる。 今まではSSLサイトを作成するにあたり、必ず1IPを消費していた。
ApacheのSNIについて

SNI(Server Name Indication RFC 4366)を使えば、一つのIPアドレスで複数のサイトのSSLを実現することが可能になる。名前ベースのバーチャルホストでSSLを使えるようにする技術。
【apache】SNI(Server Name Indication)でSSLをVirtual Hostsでも

動かない。OpenSSL/Apache/PHPのコンパイルか設定がまずいとは思うのだが・・・

Apache2.2.xでVirtualHost + SSL
1つのIPアドレスで複数のコモンネームのSSL証明書を利用する(=SNI)。
さくらVPSにopensslインストールしてphpからhttps接続させる
apache+mod_sslでSSL
[Mac][Apache][PHP][Leopard] openssl が有効にならない その2(とりあえず解決)
2008-11-22 サービスに使えるapache/opensslの構築方法
1つのサーバに複数の仮想サーバ?
PHP の OpenSSL サポートを使用

Posted in PHP.

CodeIgniterEmailクラス はそこそこ便利に使えるサーバーサイドメール送信用クラスなんだけど、subject にちょい長めの日本語を渡すと見事に文字化けしてくれたりする。

subject()関数内部で呼んでいる_prep_q_encoding()が微妙なエンコーディングをしてるのが原因なのだが、PHPでは mb_encode_mimeheader っていう便利なエンコード関数が別途存在しているため、これを使ってエンコードした文字列をそのまま渡したい。エンコードしたASCII状態のものを渡せばOKなんじゃないの?とおもいきや、これまた内部処理が邪魔してくれていたりする。

ってことで system/libraries/Email.php をちょっと改造。
_prep_q_encoding()に手をつけるのはBadな解決策なのでヘタレな回避で。

Before:

	public function subject($subject)
	{
		$subject = $this->_prep_q_encoding($subject);
		$this->_set_header('Subject', $subject);
		return $this;
	}

After:

	public function subject($subject, $encoding = TRUE)
	{
		if ($encoding) $subject = $this->_prep_q_encoding($subject);
		$this->_set_header('Subject', $subject);
		return $this;
	}
Posted in PHP.

CodeIgniterは、そのまま使うと、全ての呼び出しはindex.phpへの引数ってことになるんだけど、
CodeIgniter ユーザガイド 日本語版に書いてあるように、ApacheのRewrite設定とCodeIgniterの設定(config.php)を組み合せて、これを除去することができる。

このとき、以下のようなPHP警告メッセージが出ることがある。

A PHP Error was encountered

Severity: Warning

Message: strpos() [function.strpos]: Empty delimiter.

Filename: core/URI.php

Line Number: 160

A PHP Error was encountered

Severity: Warning

Message: strpos() [function.strpos]: Empty delimiter.

Filename: core/URI.php

Line Number: 164

以下、対処方法。

修正前。core/URI.phpの160行目あたりはこうなってる。

        /**
         * Detects the URI
         *
         * This function will detect the URI automatically and fix the query string
         * if necessary.
         *
         * @access      private
         * @return      string
         */
        private function _detect_uri()
        {
                if ( ! isset($_SERVER['REQUEST_URI']) OR ! isset($_SERVER['SCRIPT_NAME']))
                {
                        return '';
                }

                $uri = $_SERVER['REQUEST_URI'];
                if (strpos($uri, $_SERVER['SCRIPT_NAME']) === 0)
                {
                        $uri = substr($uri, strlen($_SERVER['SCRIPT_NAME']));
                }
                elseif (strpos($uri, dirname($_SERVER['SCRIPT_NAME'])) === 0)
                {
                        $uri = substr($uri, strlen(dirname($_SERVER['SCRIPT_NAME'])));
                }

$_SERVER[‘SCRIPT_NAME’]をstrposしてるんだけど、何も入ってないことを想定していないっぽい。

修正後。なんか入ってた時だけstrpos&substrをやる。

        private function _detect_uri()
        {
                if ( ! isset($_SERVER['REQUEST_URI']) OR ! isset($_SERVER['SCRIPT_NAME']))
                {
                        return '';
                }

                $uri = $_SERVER['REQUEST_URI'];
                if (strlen($_SERVER['SCRIPT_NAME']))
                {
                        if (strpos($uri, $_SERVER['SCRIPT_NAME']) === 0)
                        {
                                $uri = substr($uri, strlen($_SERVER['SCRIPT_NAME']));
                        }
                        elseif (strpos($uri, dirname($_SERVER['SCRIPT_NAME'])) === 0)
                        {
                                $uri = substr($uri, strlen(dirname($_SERVER['SCRIPT_NAME'])));
                        }
                }

同士はここに。

Posted in PHP.