- ベストアンサー
$_GETで2バイト文字列を取得することは可能?
2バイトで作成されたフォルダ名(漢字やひらがななど)を、 ブラウザにツリー表示して、それがクリックされた時に クリックされたフォルダ名を取得して、 ブラウザがそのフォルダ先を参照し、 フォルダ中のファイル名をブラウザ上に表示できるようにしています。 $_GETを用いて、フォルダ名を取得しているのですが、 2バイトのフォルダ名だと、中身がどうやらバケています。 フォルダ名が英数半角の時は、上手く処理されるのですが、 漢字やひらがななどの2バイトのフォルダ名だと、 どうしても上手くいきません。 エンコードのurlencode()関数やデコードのurldecode()関数 を用いて、いろいろやってみましたが、上手く変換してくれません。 URLと違って、パス名、フォルダ名なので、2バイトだとそもそも $_GETで取得すること自体が無理なのでしょうか? どなたか詳しい方、ご教授いただけると幸いです。 よろしくお願い致します。
- みんなの回答 (12)
- 専門家の回答
質問者が選んだベストアンサー
#10> ウチの環境の場合 function uuee(uu) { return(escape(uu).replace(/\+/g,"%2b")); } で 新しいフォルダを変換した場合 /%u65B0%u3057%u3044%u30D5%u30A9%u30EB%u30C0 になります。 これが、 %u3057%u3044の部分(しい)が %u30FBmicro;%u30FBcent; になるのは、 「しい」がSJISで82B582A2になるので、 82:わかんない文字→ナカグロ B5:μ(マイクロ)→µ 82:わかんない文字→ナカグロ A2:¢(セント)→¢ の様な感じで変換されているようです。 それで、なんで'&'がなくなっているのかもよくわかりませんが なんか変な処理してませんか? magic_quotes は、とりあえず関係なさそうですけど・
その他の回答 (11)
- BLUEPIXY
- ベストアンサー率50% (3003/5914)
>半角カタカナは、まだダメみたいですが >htmlentities()を用いて、渡していたのですが、 フォルダ名を埋め込む部分にhtmlentities って必要なんですか?
お礼
ソースを追っていてたどり着いたところが、 htmlentities だったんです。 何故、必要だったのかは・・・?? すいません、別のデバッグ続きで覚えてないです。 m(__)m
- BLUEPIXY
- ベストアンサー率50% (3003/5914)
>これは、何がおかしいのでしょう? %u{16進4桁} は、16進4桁がユニコードの文字コードを表しています。 そのつもりで、変換する手順なんですが、 30FB は、(文字パレットなんかで確認して貰えると判ると思いますが) ・(ナカグロ)です。 その前の段階で、文字コードとして無い文字を割り当てようとしたので、ナカグロが割り当てられたのかもしれません。 ところで、その元のパス名はなんだったのでしょうか?
補足
フォルダ名は /新しいフォルダ です。 その上は、ルート(実際のHDDドライブのルートではなくて、 データ格納先としてプログラム内で指定した仮想ルート)です。 つまり、ルートのすぐ下に、/新しいフォルダ としてフォルダを作成し、それをブラウザに表示させて、 そのフォルダ名をクリックすると、そのフォルダ名に移る という具合にしたいわけです。
- BLUEPIXY
- ベストアンサー率50% (3003/5914)
>PHP4なのです。 PHP5なのは、foreach の &$value の部分なので foeach { } の部分を foreach ($array as $index => $value){ if($value[0] != '%'){ $conv=""; for($i=0;$i<strlen($value);$i++){ $conv .= sprintf("%%u%04X",ord($value[$i])); } $array[$index]=$conv; } } に置き換えれば良いと思います。
補足
現在のプログラム内の $_GET で取得した中身を表示させ確認したところ、 /%u65B0%u30FBmicro;%u30FBcent;%u30D5%u30A9%u30EB%u30C0 となっていましたので、 教えていただいたソース「すごくちからわざ(php4)」)を使用させていただき 変換させてみたところ、 /新・micro;・cent;フォルダ となって表示され、正常にデコードできませんでした。 これは、何がおかしいのでしょう? お手数おかけしますが、もし、おわかりになりましたら、 ご教授下さいませ。m(__)m <ちなみに抜粋的となりますが、以下、当方のソースを書き出しておきます> <?php $aaa=$_GET["aaa"]; ?> var aaa='<?=addslashes($aaa)?>'; function uuee(uu) { return(escape(uu).replace(/\+/g,"%2b")); } ↓そしてこのような感じでjavascriptで実行させています。 ・・・href='hoge.php?aaa='+uuee(aaa)+'・・・・;
- gama001
- ベストアンサー率50% (3/6)
「サーバー側でurlencodeしたものでリンクを生成する」について 以前の内容を見るとEUCで統一されているようなので こんな感じかと 【test.php】 <?php if ( isset( $_GET['next'] ) ) echo $_GET['next']."<br>"; $fname = 'XYZ新しいフォルダ'; echo "<A href='test.php?next=".urlencode($fname)."'>$fname</A>"; ?> #もしかしたらこういう話ではないのかなぁという気がしてきましたが どうでしょうか?
補足
ありがとうございます。 問題は、どうやらANo.5さんがご回答くださったように、フォルダ名をクリックした後、javascriptが走り、javascriptのencode()でエンコードしているので、PHPでデコードしても正しく戻らず文字化けしているらしいんです。 文字コードについては詳しくないので、皆さんからいただいた内容で試したり思考錯誤中です・・
- BLUEPIXY
- ベストアンサー率50% (3003/5914)
すごくちからわざ(php5) <?php $str="/%u65B0microcent%u30D5%u30A9%u30EB%u30C0"; $array=preg_split("/(%u[0-9A-Fa-f]{4})/", $str, -1, PREG_SPLIT_NO_EMPTY|PREG_SPLIT_DELIM_CAPTURE); foreach ($array as &$value){ if($value[0] != '%'){ $conv=""; for($i=0;$i<strlen($value);$i++){ $conv .= sprintf("%%u%04X",ord($value[$i])); } $value=$conv; } } $str = join("", $array); $str = preg_replace("/%u([0-9A-F]{2})([0-9A-F]{2})/ei","chr(hexdec('$1')).chr(hexdec('$2'))",$str); $str = mb_convert_encoding($str,"sjis","unicode"); print $str; ?>
補足
残念ながら、用いているのはPHP4なのです。 サーバー環境の変更できなくもないですが、さすがにPHPヴァージョンを変えることを依頼するのは無理そうです。 上記のコードをPHP4で使えるように記述し直し用いることは可能でしょうか? <参考までに> サーバ環境:Windows2003Server、IIS、PHP4.4.2 開発クライアント環境:WindowsXPpro、Apache2.0.55、PHP4.4.2
- gama001
- ベストアンサー率50% (3/6)
どうしてもクライアント側で エンコードしなくてはならない理由があるなら まずjavaScript側で encodeURIComponentを使ってエンコードしておく。 php.iniは mbstring.encoding_translation = Off の設定にしておいて $_GETで受けたデータをrowurldecodeして 更にUTF-8から内部コードにmb_convert_encodingしてやると 正しく動作しそうです。 いろいろ事情があるでしょうが サーバー側でurlencodeしたものでリンクを 生成したほうが簡単だと思いますよ^^
補足
ありがとうございます。 サーバーはレンタルサーバーではないので、 ある程度、希望どおりに環境は変更してもらえます。 「サーバー側でurlencodeしたものでリンクを生成する」とは、 具体的にどういったものでしょうか? ご教授いただけると幸いです。
- taskuni
- ベストアンサー率71% (49/69)
化けてるのではなく、JavaScriptでエンコードしているのでは?
お礼
<補足追加させて下さい> いただいたURLの、escape、unescapeを参考に $_GET()内のバケ文字を変換してテスト表示してみたところ、 カタカナと半角カタカナのフォルダ名は、 問題なく戻すことができました。 しかし、ひらがなは余計にバケてしまい、漢字も一部戻りますが、 やはりバケる部分があるので、このままだと使えず・・ このあたりの原因は何なのか、もしおわかりになるようでしたら ご教授下さいませ。 すでに、ブラウザ表示させたフォルダ名を、マウスクリックで JavaScriptを走らせている箇所を多く作りこんでいるので、 今からJavaScriptをやめるのは、ちょっと大変なのです。 半角英数のフォルダでテストしながらほとんど作成してしまったので、 後になって、2バイトフォルダ名がこのようになってしまうとは、 気がつかず・・・うかつでした。m(__)m
補足
そのとおりです! ブラウザ表示されたフォルダ名をクリックすると JavaScriptでの処理に走ります。 以下の方たちに、補足したかったのですが、 ソースが複雑になっているので、掲示板では ちょっと説明しきれず、思案していたところです。 参考URLはまだじっくり見ておりませんが、 早速、拝見させていただきます。
- yambejp
- ベストアンサー率51% (3827/7415)
普通は、そんなことが面倒なので、URL直接指定 では2バイト系の文字の受渡しはしません。 ユーザーが任意に入力した文字を引数にしたいなら formを使って正規の手段で渡せばすみます。 そうでないなら、任意のidなどで管理するのが 確実です。構造を考え直してはいかがでしょうか?
- gama001
- ベストアンサー率50% (3/6)
そもそものフォルダリンクを出力している部分はどうなっているのでしょう? (そこが間違ってると後でいくらいじっても変になるだけ) あと出力している画面はEUCですか? SJISの場合 mbstring.encoding_translation = Off とされてますから自分でそれなりの処理をしてますか? 私はあまり文字コードに長けていないので 記載された化け方を見てもぴんと来ません。 >どなたかピンときませんか?
- gama001
- ベストアンサー率50% (3/6)
$_GETで取得ということはもしかして <A href="xxx.php?name=日本語フォルダ名"> ということでしょうか。 だとしたら先にこのリンクを表示する時点で urlencodeしておかなければいけません。 あとはphp.iniのマルチバイト関連の設定を見直す。
補足
試行錯誤してみていますが、どうも上手く行きません。 もし、おわかりになるようであれば、ご教授下さいませ。m(__)m ブラウザに表示させてあるフォルダ名をクリックしたときに、 xxx.php?name=/%u65B0%u30FBmicro;%u30FBcent;%u30D5%u30A9%u30EB%u30C0 のような感じで送信されているようで、$_GETで取得しても、 バケてしまって、正しいフォルダ先に飛んでくれないのです。 例えば、 新しいフォルダ という名称のフォルダだと、 /%u65B0%u30FBmicro;%u30FBcent;%u30D5%u30A9%u30EB%u30C0 のようにバケます。 (一番最初の'/'はaddslashesでバックスラッシュを挿入しています) また、 XYZ新しいフォルダ という名称のフォルダだと、 /XYZ%u65B0%u30FBmicro;%u30FBcent;%u30D5%u30A9%u30EB%u30C0 のように、最初の半角英字(XYZ)は正しく取得されますが、 その後の2バイト文字は、同様にバケます。 以下、php.iniの関連しそうなところの設定を抜き出してみました。 [mbstring] ; language for internal character representation. mbstring.language = Japanese ; internal/script encoding. ; Some encoding cannot work as internal encoding. ; (e.g. SJIS, BIG5, ISO-2022-*) mbstring.internal_encoding = EUC-JP ;mbstring.internal_encoding = SJIS ; http input encoding. ;mbstring.http_input = auto mbstring.http_input = ASCII,JIS,EUC-JP,SJIS ; http output encoding. mb_output_handler must be ; registered as output buffer to function ;mbstring.http_output = SJIS mbstring.http_output = EUC-JP ; enable automatic encoding translation according to ; mbstring.internal_encoding setting. Input chars are ; converted to internal encoding by setting this to On. ; Note: Do _not_ use automatic encoding translation for ; portable libs/applications. mbstring.encoding_translation = Off ;mbstring.encoding_translation = On ; automatic encoding detection order. ; auto means ;mbstring.detect_order = auto mbstring.detect_order = ASCII,JIS,EUC-JP,SJIS ; substitute_character used when character cannot be converted ; one from another mbstring.substitute_character = none;
- 1
- 2
お礼
自己解決いたしました! 原因は、やはりフォルダ名を渡す時点で、バケていたようです。 htmlentities()を用いて、渡していたのですが、 第三番目の引数を指定せずに渡していたので、 ISO-8859-1 文字セットがデフォルトの文字エンコーディングとして使用されました。 第三番目の引数に、"SJIS"を指定して、 $_GETで取得した値を、教えていただいたソース「すごくちからわざ(php4版)」を 使用させていただき変換させてみたところ、 全角ひらがな、全角カタカナ、漢字のフォルダ名については、 正常な値となり、認識しました。 (ただ、半角カタカナは、まだダメみたいですが…) <参考:htmlentities()> http://php.s3.to/man/function.htmlentities.html 長々とお付き合いくださって、本当にどうもありがとうざいました。 根本原因にたどり着くまで、非常に助かり、 また、「すごくちからわざ(php4版)」も、とてもありがたいコードと なりました。 どうも、ありがとうございました!m(__)m
補足
長くお付き合いいただき、本当にすいません。恐縮です。m(__)m 抜粋なので、これでおわかりになるかどうかわかりませんが、 さらにソースの一部を付け加えて書きます。 <SCRIPT> parent.lsctl.oroot.valor="root=['','','','',0,'','m0',0,0,[ ['/','javascript:mmexec(\"/\")','','',0,'','',0,0,['%%','/']] ]]"; eval(parent.lsctl.oroot.valor); parent.lsctl.oroot.treedeep=0; parent.lsctl.oroot.treeleaves=0; parent.lsctl.oroot.treeheavy=0; heavy=parent.lsctl.oroot.treeheavy; </SCRIPT> function uuee(uu) { return(escape(uu).replace(/\+/g,"%2b")); } function mmexec(s) { parent.lstop.location.href='hoge.php?aaa='+uuee(s); return true; } -------- <SCRIPT></SCRIPT>の部分は実際は呼び出していて、 ちょっと複雑なので、取りあえず、走らせた後、 ブラウザのソース表示で表示させたままのをコピペしました。 -------- では、function uuee(uu)のescape処理に間違いなさそうで、 問題は、function mmexec(s)に渡している値が おかしいかも??という感じでしょうか?