こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

$_GETで2バイト文字列を取得することは可能?

2バイトで作成されたフォルダ名(漢字やひらがななど)を、
ブラウザにツリー表示して、それがクリックされた時に
クリックされたフォルダ名を取得して、
ブラウザがそのフォルダ先を参照し、
フォルダ中のファイル名をブラウザ上に表示できるようにしています。

$_GETを用いて、フォルダ名を取得しているのですが、
2バイトのフォルダ名だと、中身がどうやらバケています。
フォルダ名が英数半角の時は、上手く処理されるのですが、
漢字やひらがななどの2バイトのフォルダ名だと、
どうしても上手くいきません。
エンコードのurlencode()関数やデコードのurldecode()関数
を用いて、いろいろやってみましたが、上手く変換してくれません。
URLと違って、パス名、フォルダ名なので、2バイトだとそもそも
$_GETで取得すること自体が無理なのでしょうか?
どなたか詳しい方、ご教授いただけると幸いです。
よろしくお願い致します。

投稿日時 - 2006-03-01 00:42:07

QNo.1998673

困ってます

質問者が選んだベストアンサー

#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 は、とりあえず関係なさそうですけど・

投稿日時 - 2006-03-02 20:15:35

補足

長くお付き合いいただき、本当にすいません。恐縮です。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)に渡している値が
おかしいかも??という感じでしょうか?

投稿日時 - 2006-03-02 21:37:01

お礼

自己解決いたしました!
原因は、やはりフォルダ名を渡す時点で、バケていたようです。
htmlentities()を用いて、渡していたのですが、
第三番目の引数を指定せずに渡していたので、
ISO-8859-1 文字セットがデフォルトの文字エンコーディングとして使用されました。
第三番目の引数に、"SJIS"を指定して、
$_GETで取得した値を、教えていただいたソース「すごくちからわざ(php4版)」を
使用させていただき変換させてみたところ、
全角ひらがな、全角カタカナ、漢字のフォルダ名については、
正常な値となり、認識しました。
(ただ、半角カタカナは、まだダメみたいですが…)

<参考:htmlentities()>
http://php.s3.to/man/function.htmlentities.html

長々とお付き合いくださって、本当にどうもありがとうざいました。
根本原因にたどり着くまで、非常に助かり、
また、「すごくちからわざ(php4版)」も、とてもありがたいコードと
なりました。

どうも、ありがとうございました!m(__)m

投稿日時 - 2006-03-03 11:29:13

ANo.11

このQ&Aは役に立ちましたか?

11人が「このQ&Aが役に立った」と投票しています

回答(12)

ANo.12

>半角カタカナは、まだダメみたいですが
>htmlentities()を用いて、渡していたのですが、
フォルダ名を埋め込む部分にhtmlentities って必要なんですか?

投稿日時 - 2006-03-03 20:15:26

お礼

ソースを追っていてたどり着いたところが、
htmlentities だったんです。
何故、必要だったのかは・・・??
すいません、別のデバッグ続きで覚えてないです。
m(__)m

投稿日時 - 2006-03-10 13:52:06

ANo.10

>これは、何がおかしいのでしょう?
%u{16進4桁}
は、16進4桁がユニコードの文字コードを表しています。
そのつもりで、変換する手順なんですが、
30FB
は、(文字パレットなんかで確認して貰えると判ると思いますが)
・(ナカグロ)です。
その前の段階で、文字コードとして無い文字を割り当てようとしたので、ナカグロが割り当てられたのかもしれません。

ところで、その元のパス名はなんだったのでしょうか?

投稿日時 - 2006-03-02 18:11:11

補足

フォルダ名は
/新しいフォルダ
です。
その上は、ルート(実際のHDDドライブのルートではなくて、
データ格納先としてプログラム内で指定した仮想ルート)です。
つまり、ルートのすぐ下に、/新しいフォルダ
としてフォルダを作成し、それをブラウザに表示させて、
そのフォルダ名をクリックすると、そのフォルダ名に移る
という具合にしたいわけです。

投稿日時 - 2006-03-02 18:47:32

ANo.9

>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;
}
}
に置き換えれば良いと思います。

投稿日時 - 2006-03-02 11:18:11

補足

現在のプログラム内の $_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)+'・・・・;

投稿日時 - 2006-03-02 16:32:10

ANo.8

「サーバー側で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>";
?>

#もしかしたらこういう話ではないのかなぁという気がしてきましたが
どうでしょうか?

投稿日時 - 2006-03-02 10:03:33

補足

ありがとうございます。
問題は、どうやらANo.5さんがご回答くださったように、フォルダ名をクリックした後、javascriptが走り、javascriptのencode()でエンコードしているので、PHPでデコードしても正しく戻らず文字化けしているらしいんです。

文字コードについては詳しくないので、皆さんからいただいた内容で試したり思考錯誤中です・・

投稿日時 - 2006-03-02 10:06:29

ANo.7

すごくちからわざ(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;
?>

投稿日時 - 2006-03-02 03:53:25

補足

残念ながら、用いているのはPHP4なのです。
サーバー環境の変更できなくもないですが、さすがにPHPヴァージョンを変えることを依頼するのは無理そうです。
上記のコードをPHP4で使えるように記述し直し用いることは可能でしょうか?

<参考までに>
サーバ環境:Windows2003Server、IIS、PHP4.4.2
開発クライアント環境:WindowsXPpro、Apache2.0.55、PHP4.4.2

投稿日時 - 2006-03-02 08:48:45

ANo.6

どうしてもクライアント側で
エンコードしなくてはならない理由があるなら
まずjavaScript側で
encodeURIComponentを使ってエンコードしておく。
php.iniは
mbstring.encoding_translation = Off
の設定にしておいて
$_GETで受けたデータをrowurldecodeして
更にUTF-8から内部コードにmb_convert_encodingしてやると
正しく動作しそうです。

いろいろ事情があるでしょうが
サーバー側でurlencodeしたものでリンクを
生成したほうが簡単だと思いますよ^^

投稿日時 - 2006-03-02 01:15:27

補足

ありがとうございます。
サーバーはレンタルサーバーではないので、
ある程度、希望どおりに環境は変更してもらえます。
「サーバー側でurlencodeしたものでリンクを生成する」とは、
具体的にどういったものでしょうか?
ご教授いただけると幸いです。

投稿日時 - 2006-03-02 08:46:14

ANo.5

化けてるのではなく、JavaScriptでエンコードしているのでは?

参考URL:http://ns1.php.gr.jp/pipermail/php-users/2003-April/015213.html

投稿日時 - 2006-03-01 16:46:55

補足

そのとおりです!
ブラウザ表示されたフォルダ名をクリックすると
JavaScriptでの処理に走ります。
以下の方たちに、補足したかったのですが、
ソースが複雑になっているので、掲示板では
ちょっと説明しきれず、思案していたところです。
参考URLはまだじっくり見ておりませんが、
早速、拝見させていただきます。

投稿日時 - 2006-03-01 17:24:15

お礼

<補足追加させて下さい>
いただいたURLの、escape、unescapeを参考に
$_GET()内のバケ文字を変換してテスト表示してみたところ、
カタカナと半角カタカナのフォルダ名は、
問題なく戻すことができました。
しかし、ひらがなは余計にバケてしまい、漢字も一部戻りますが、
やはりバケる部分があるので、このままだと使えず・・
このあたりの原因は何なのか、もしおわかりになるようでしたら
ご教授下さいませ。
すでに、ブラウザ表示させたフォルダ名を、マウスクリックで
JavaScriptを走らせている箇所を多く作りこんでいるので、
今からJavaScriptをやめるのは、ちょっと大変なのです。
半角英数のフォルダでテストしながらほとんど作成してしまったので、
後になって、2バイトフォルダ名がこのようになってしまうとは、
気がつかず・・・うかつでした。m(__)m

投稿日時 - 2006-03-01 18:10:54

ANo.4

普通は、そんなことが面倒なので、URL直接指定
では2バイト系の文字の受渡しはしません。
ユーザーが任意に入力した文字を引数にしたいなら
formを使って正規の手段で渡せばすみます。
そうでないなら、任意のidなどで管理するのが
確実です。構造を考え直してはいかがでしょうか?

投稿日時 - 2006-03-01 15:54:12

ANo.3

そもそものフォルダリンクを出力している部分はどうなっているのでしょう?
(そこが間違ってると後でいくらいじっても変になるだけ)

あと出力している画面はEUCですか?
SJISの場合
mbstring.encoding_translation = Off
とされてますから自分でそれなりの処理をしてますか?

私はあまり文字コードに長けていないので
記載された化け方を見てもぴんと来ません。
>どなたかピンときませんか?

投稿日時 - 2006-03-01 14:54:41

ANo.2

$_GETで取得ということはもしかして
<A href="xxx.php?name=日本語フォルダ名">
ということでしょうか。

だとしたら先にこのリンクを表示する時点で
urlencodeしておかなければいけません。

あとはphp.iniのマルチバイト関連の設定を見直す。

投稿日時 - 2006-03-01 09:34:19

補足

試行錯誤してみていますが、どうも上手く行きません。
もし、おわかりになるようであれば、ご教授下さいませ。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;

投稿日時 - 2006-03-01 11:51:57

ANo.1

マルチバイト文字の場合、フォームでURLエンコードされていると思うので
やはり、urldecode してやればいいはずです。
多分、urldecode した文字列が文字コードが違うのだと思います。
mb_convert_encoding してやればいいかと思います。

投稿日時 - 2006-03-01 04:05:37

補足

ありがとうございます。
mb_convert_encodingも用いていろいろやってみましたが、
やはりだめなようです。

投稿日時 - 2006-03-01 11:50:42

あなたにオススメの質問