[UTF-8] UTF-8に移行したサイトに、移行前のページ名(URL)に対するアクセスがあった場合のケア

メッセージ

EUC-JP -> UTF-8に移行した場合、旧ページ名*1へのアクセスが悲しいことになります。

PukiWiki 1.5.4 での対策:

PageURIHandler を使ってリダイレクトを行う。

pukiwiki.ini.php:

// Page-URI mapping handler ( See https:// pukiwiki.osdn.jp/?PukiWiki/PageURI )
class EucjpUtf8RedirectPageURIHandler extends PukiWikiStandardPageURIHandler {
       function filter_raw_query_string($query_string) {
               if (! $query_string) {
                       return $query_string;
               }
               if (strpos($query_string, '&') !== FALSE) {
                       return $query_string;
               }
               if (strpos($query_string, '=') !== FALSE) {
                       return $query_string;
               }
               if (strpos($query_string, '%') === FALSE) {
                       return $query_string;
               }
               $page = rawurldecode($query_string);
               if (mb_check_encoding($page, 'UTF-8')) {
                       return $query_string;
               }
               if (! mb_check_encoding($page, 'CP51932')) {
                       return $query_string;
               }
               $utf8_page = mb_convert_encoding($page, 'UTF-8', 'CP51932');
               if (!$utf8_page) {
                       return $query_string;
               }
               $location = get_page_uri($utf8_page, PKWK_URI_ROOT);
               header('HTTP/1.0 302 Found');
               header('Location: ' . $location);
               exit;
       }
}
$page_uri_handler = new EucjpUtf8RedirectPageURIHandler();

このコードを pukiwiki.ini.php の $page_uri_hanlder がある行と置き換えてください。

以下の情報は、PukiWiki 1.5.4より前の過去の議論と、動作の説明です。


とりあえず悲しさを軽減できるパッチを作ったので参考までにどうぞ。 (okkez)

Index: read.inc.php
===================================================================
--- read.inc.php	(revision 225)
+++ read.inc.php	(working copy)
@@ -25,7 +25,15 @@
 
 	} else {
 		// 無効なページ名
+		if ('EUC-JP' === mb_detect_encoding($page)) {
+			$page = mb_convert_encoding($page, 'UTF-8', 'EUC-JP');
+			$body = make_pagelink($page);
+			return array(
+				'msg'=>'maybe this page?',
+				'body'=>$body
+			);
+		}
 		return array(
 			'msg'=>$_title_invalidwn,
 			'body'=>str_replace('$1', htmlspecialchars($page),

PukiWiki 1.5.4 での対策

EUC-JPの日本語文字のうちそのバイナリ列をUTF-8文字として解釈できるのは以下の930文字

与丐丕丙両个丱丶丹丼丿乂乃之乏乖乘乢亂亅了予亊于亞亟亠亡亢亮亰亳亶仂仄仆仍从仏他
仗任伐伴但佑余佞併侫侶促俗俵側傍傳僂僉僊働僖僚僞僣僥僭僮僵價儁儂儉儔儕儖儚儡優儷
儺儻儼儿兀兌兒兔兢八六兵其典冥凌函分判則剖劉劬劭労劵劼勁勅勇勍動勗務勞勠勣勦勳勵
勸勹匆匈匍匏匐匕匚匣匯匱匳匸匹匿區半卒単即友反叩同名吻呂味命咤咫咯咼咾哂哘哢哥哦
哭哮哲哺哽唏唔售唯唳唸唹啀啅啌啖啗啜啝啣喀喊喙嗇嘆噴噺嚢圈國圍圓圖團圜圦圷圸圻址
坊坎坏坡坦坩坿垈垉垓垠垤垪垰垳埀埃埆埒埔埜堂塀塙填墳夕多夢天奪奮奸妁如妊妍妙妛妝
妣妨妲姆姙姚姜姨姫娉娑娘娚娜娟娥娵娶婀婁婉婢婪婬婿媚媛媼媾嫂嫋存孫孱宥密寧尊導尿
屏屐展属屬屮屶屹岌岑岔岫岬岶岷岻岼岾峅峇峙峠峩峪峭峺峽崋崕崗嵜嶌巳巽帖帳帽幡幣平
年幽庁店廊廖廚廛廝廡廢廣廨廩廬廰廱廳廴廸廼廾弃弄弉弋弌弍弑弔弖弗弩弭弯張弸弼彁彈
彌彎彜彝彦彪彫律徴徹必忍忘忙忰念息悄悋悒悖悗悛悠悧悩悴悵悸悽惆惓惘惠惡惱惴惶惷惺
惻愀愃愆愍愎愕愡慍慮憂憤憧懲戞戡截戮戰戲戳房扁扎払扛扞扠扣扨扮扼找抂抃抉抒抓抔抖
抜抬抻担拆拏拑拔拗拿挑捉捗捻掠探揃揖損摘撚撞撤撻擂擅擇擒擔擘據擠擡擢擣擧擯擱擲擴
擶擺擽攀攅攘攜攣攤攫攬攴攵攷敵文旅族旦昿暢暴暸曄曖曚曠曦曩曰曵曷有朏朕朖朗望朝朞
朦朧未朮朶朷朸朿杁杆村杙杞束杠杣杤杰枉柊某柚桧棆棔棕棗棚棠棣棧棯棹椄椋椒椚椡椣椥
椨椪椰椶椹椽楔楙楜楫楮楴楷楸楹楼楾榔標樽檗檪檬檳檸檻櫂櫃櫑櫓櫚櫞櫟櫨櫪櫺櫻欅欒欖
欟欷欸欹歃歇歉歎歐民氷沸沺法泙泛泡泥泪泯洌洒洙洞洟洫洳洵洶洸洽流浙浚浣浤浪浹涅涌
涎涓涕涵淇淡淵淹添渊渕測湊湛湧溌溜溺滴滷漂漏漓漫漾潘潛潦潭潮潯潸潺潼澀澁澂澆澎澑
澡澣澤澪澳澹濂濃濆濔濕濘濟濡濤濬濳炉炭烹焚無熱燃牒牟牢物狸狼猫猶猷率琉瓢甜由甸町
畑留畠畢略疋痢発百的盜直眠眺瞳矛短砲硫硲祐祢票禄福禰稔稗立竜童竪端竸笛筆筈筏箕箪
箱箸篭粉粍粒粘糞納紐紛続綻縫纏罰老耽聞聴聾肇肋肌肘胞胴能脈脱脳脹腸腹膝膿臓舉舒芳
菱萄萌葎董葱蓑蓬蓮蔓蔵蕩藤蘖蘗虜蛤蜂蜜蝋蝶融衍表袖裏裕裡複褒覆討訪評認誘誰調諜諭
謄謬谷豆豊豫豹貼賂賊贈超足路跳踏転輸轍辧辰辿迭逃透速造連逼遊道達遜適邑邦邸郎郵鄭
醗里釘鉄鉢銅銚鋒錬録鏑鐙長閥闘陶陸隆隼雄離雰霧露霸韮頂頭顛飭飮飽騰髪髭鬱魅魯鮒鱈
鳥鳩鳳鴇鵡鵬麓鼎鼻龍

これ以外の文字が1文字でも含まれているページであれば、 mb_check_encoding($eucjp_page, 'UTF-8') が FALSE になる。

さらに、mb_check_encoding($eucjp_page, 'CP51932') がTRUEなものを UTF-8 変換してリダイレクトすれば、 旧URLにアクセスした場合でもUTF-8変換後の同盟ページにアクセスできる

救えない (リダイレクトされない) のはUTF-8として解釈しても問題ない930文字のみで構成されたページ名。 これは十分少ないと推測できる。

調査用コード:

for ($i = 127; $i <= 65536; $i++) {
    $c = IntlChar::chr($i);
    $c_eucjp = mb_convert_encoding($c, 'CP51932', 'UTF-8');
    $c_utf8 = mb_convert_encoding($c_eucjp, 'UTF-8', 'CP51932');
    if ($c === $c_utf8) {
        if (mb_check_encoding($c_eucjp, 'UTF-8')) {
            echo $c;
        }
    }
}

PageURIHandler を使って対策

pukiwiki.ini.php:

// Page-URI mapping handler ( See https:// pukiwiki.osdn.jp/?PukiWiki/PageURI )
class EucjpUtf8RedirectPageURIHandler extends PukiWikiStandardPageURIHandler {
       function filter_raw_query_string($query_string) {
               if (! $query_string) {
                       return $query_string;
               }
               if (strpos($query_string, '&') !== FALSE) {
                       return $query_string;
               }
               if (strpos($query_string, '=') !== FALSE) {
                       return $query_string;
               }
               if (strpos($query_string, '%') === FALSE) {
                       return $query_string;
               }
               $page = rawurldecode($query_string);
               if (mb_check_encoding($page, 'UTF-8')) {
                       return $query_string;
               }
               if (! mb_check_encoding($page, 'CP51932')) {
                       return $query_string;
               }
               $utf8_page = mb_convert_encoding($page, 'UTF-8', 'CP51932');
               if (!$utf8_page) {
                       return $query_string;
               }
               $location = get_page_uri($utf8_page, PKWK_URI_ROOT);
               header('HTTP/1.0 302 Found');
               header('Location: ' . $location);
               exit;
       }
}
$page_uri_handler = new EucjpUtf8RedirectPageURIHandler();

UTF-8としてinvalidなページ名のリクエストが来たら、リクエストをEUC-JP(CP51932)とみなしてUTF-8に変換してリダイレクトする。本体コードに手を入れずに対応が可能。

詳細ロジック:




*1 日本語を含む

トップ   編集 凍結 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2023-01-22 (日) 21:09:58
Site admin: PukiWiki Development Team

PukiWiki 1.5.4+ © 2001-2022 PukiWiki Development Team. Powered by PHP 8.2.12. HTML convert time: 0.282 sec.

SourceForge