PHPでURIをパーセントエンコード

urlencode関数を使うと全部エンコード対象になりますが、一部だけエンコードしたい場合はどう対応すべきでしょうか。

ひとまず、以下3段階を実験中です。

  • %は対象外
  • %を対象に含める
  • 予約文字なども対象に含める(全部)

urlencode関数は文字コードが混在していてもそれぞれのパーセントエンコード文字になるようなので、内部でのエンコード処理はurlencode関数を利用しています。

原則、pchar以外をエンコード対象として扱っていますが、間違いでしょうか?

<?php
 
/**
 * URI class
 *
 * @author  koshigoe<KoshigoeBushou@gmail.com>
 * @since   2007/01/18
 * @version $Id: Uri.php 127 2007-01-19 17:00:48Z koshigoe $
 * @see     RFC3986<http://www.ietf.org/rfc/rfc3986.txt>
 */
class Uri
{
 
    const ENCODE_SAFE         = 0;
    const ENCODE_WITHOUT_PCT = 1;
    const ENCODE_FORCE        = 2;
 
    private $_regex;
    private $_map;
 
    public function __construct()
    {
        $this->_regex = '|^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?|';
        $this->_map   = array(
                              "scheme"    => 2,
                              "authority" => 4,
                              "path"      => 5,
                              "query"     => 7,
                              "fragment"  => 9,
                              );
    }
 
    /**
     * parse well-formed URI(or URI Reference)
     *
     * @param  string $uri URI stirng
     * @return array  URI Components array
     */
    public function parse($uri)
    {
        if (preg_match($this->_regex, $uri, $match) == 0) {
            return false;
        }
        $components = array();
        foreach ($this->_map as $name => $number) {
            if (isset($match[$number])) {
                $components[$name] = $match[$number];
            }
        }
        return $components;
    }
 
    /**
     * percent encoding about not pchar
     *
     * @param  string $uri   URI string
     * @param  int    $level encoding level
     * @return string pct-encoded URI string
     */
    public function encode($uri, $level = self::ENCODE_SAFE)
    {
        $pattern = preg_quote(":/?#[]@!$&'()*+,;=", '|');
        if (($level & self::ENCODE_FORCE) === self::ENCODE_FORCE) {
            return urlencode($uri);
        }
        if (($level & self::ENCODE_WITHOUT_PCT) === self::ENCODE_WITHOUT_PCT) {
            $pattern .= preg_quote('%', '|');
        }
        if (preg_match('|([^' . $pattern . ']+)|', $uri) > 0) {
            return preg_replace('|([^' . $pattern . ']+)|e', "urlencode('\\1')", $uri);
        } else {
            return $uri;
        }
    }
 
}
 
?>
プロフィール

このブログ記事について

このページは、koshigoeが2007年1月20日 02:19に書いたブログ記事です。

ひとつ前のブログ記事は「PHPのparse_urlは文字コード依存ですか?」です。

次のブログ記事は「ローカルでのマニュアル検索」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。