자바스크립트 escape()를 PHP로 받기
Q&A 보다보니 가-끔 올라오는 주제인듯 싶어서 슬쩍 써둡니다.
알아두기
우 선 분명히 해야할 점은, 자바스크립트 자체에서 escape()와 unescape() 는 사용이 배제되는, 권장하지 않는 함수입니다. 자바스크립트 1.5부터는 encodeURI(), decodeURI() 함수의 사용을 권장하며, ECMA 스크립트(자바스크립트의 표준안입니다) 리비전 3부터 이쪽을 사용하게 되어있습니다. 브라우저에서는 넷스케이프 6, IE 5.5, 모질라(언제부터인지 조사 안함. 1.5에서는 잘 됩니다) 이상에서 잘 지원됩니다. encodeURI(), decodeURI()는 PHP의 rawurlencode(), rawurldecode()와 완벽하게 호환됩니다.
escape()의 작동 원리
escape() 는 영숫자 및 * @ - _ + . /를 제외한 모든 문자를 별도의 방법으로 처리합니다. ASCII 코드의 문자는 %xx 형태로 변경하며, 그 외의 문자는 %uxxxx로 나타나는 유니코드로 처리합니다. (반면 encodeURI()는 제외 문자 이외는 전부 %xx 형태로 변환합니다)
escape() 문자열 받기, PHP js_unescape() 함수
이 함수를 사용하려면, ctype 모듈(기본값으로 들어갑니다), 그리고 이후 변환을 위한 iconv 모듈이 필요합니다. 자바스크립트 escape()로 만들어진 문자열이 아닐 경우(% 변환 오류시) 반환값은 boolean FALSE입니다.
js_unescape() 소스
function js_unescape($src) {
$len = strlen($src);
$dst = array();
for ($i = 0; $i < $len; $i++) {
if ($src{$i} == '%') {
if (isset($src{$i+5}) && $src{$i+1} == 'u' &&
ctype_xdigit($src{$i+2} . $src{$i+3} . $src{$i+4} . $src{$i+5})) {
$dst[] = chr(hexdec($src{$i+2} . $src{$i+3}));
$dst[] = chr(hexdec($src{$i+4} . $src{$i+5}));
$i += 5;
} elseif (isset($src{$i+2}) && ctype_xdigit($src{$i+1} . $src{$i+2})) {
$dst[] = chr(0);
$dst[] = chr(hexdec($src{$i+1} . $src{$i+2}));
$i += 2;
} else {
return FALSE;
}
} elseif ($src{$i} >= 0x20 && $src{$i} <= 0x7E) {
$dst[] = chr(0);
$dst[] = $src{$i};
} else {
return FALSE;
}
}
return implode('', $dst);
}
js_unescape() 함수 사용법
이 함수가 반환하는 문자열은 유니코드이므로, 문자열을 받으려면 다음과 같은식으로 사용을 해야합니다. UTF-8 부분을 원하는 인코딩으로 바꾸면 됩니다. (예: EUC-KR)
$unescaped_string = js_unescape($escaped_string);
$original_string = iconv('ISO-10646-UCS-2', 'UTF-8', $unescaped_string);
소스 이해하기
전체를 설명하진 않습니다. 이해를 돕기 위한 간단한 설명일 뿐입니다. 어려운 소스도 아니니 나머지 부분은 자력으로 연구하십시오.
$src{$i}
이 는 문자열에서 한 문자를 가져오는 방법입니다. C에서는 문자열을 문자의 집합을 나타내는 포인터로 다루기 때문에 자주 쓰이지만, PHP로 시작한 분은 처음볼지도 모르겠습니다. $src = "ABCDEFG"라고 할 경우, $src{0}는 'A'를, $src{5}는 'F'를 나타내는 방식입니다.
$dst[] = chr(0);
이는 유니코드(UCS-2)의 인코딩 방식으로 인해 들어가는 부분입니다. UCS-2인코딩은 다른 인코딩과는 달리, 영숫자 등도 2바이트를 차지하게 되어있습니다. 즉, 'A'의 코드값이 0x41이 아닌, 0x0041입니다. 이를 채워넣기 위함입니다.
끝맺음
마 지막으로 강조하지만, 자바스크립트에서 인코드할때는 encodeURI(), decodeURI()를 우선적으로 고려해보시기 바랍니다. 여담으로, 문자열을 포인터로 다룰 수 없었던게 매우 귀찮았다는게 만들면서 든 생각이였습니다 -ㅅ- 혹시 오류라던지가 발생하면 알아서 고치십시오. 이 소스에 대한 모든 권리와 의무는 포기합니다.
Q&A 보다보니 가-끔 올라오는 주제인듯 싶어서 슬쩍 써둡니다.
알아두기
우 선 분명히 해야할 점은, 자바스크립트 자체에서 escape()와 unescape() 는 사용이 배제되는, 권장하지 않는 함수입니다. 자바스크립트 1.5부터는 encodeURI(), decodeURI() 함수의 사용을 권장하며, ECMA 스크립트(자바스크립트의 표준안입니다) 리비전 3부터 이쪽을 사용하게 되어있습니다. 브라우저에서는 넷스케이프 6, IE 5.5, 모질라(언제부터인지 조사 안함. 1.5에서는 잘 됩니다) 이상에서 잘 지원됩니다. encodeURI(), decodeURI()는 PHP의 rawurlencode(), rawurldecode()와 완벽하게 호환됩니다.
escape()의 작동 원리
escape() 는 영숫자 및 * @ - _ + . /를 제외한 모든 문자를 별도의 방법으로 처리합니다. ASCII 코드의 문자는 %xx 형태로 변경하며, 그 외의 문자는 %uxxxx로 나타나는 유니코드로 처리합니다. (반면 encodeURI()는 제외 문자 이외는 전부 %xx 형태로 변환합니다)
escape() 문자열 받기, PHP js_unescape() 함수
이 함수를 사용하려면, ctype 모듈(기본값으로 들어갑니다), 그리고 이후 변환을 위한 iconv 모듈이 필요합니다. 자바스크립트 escape()로 만들어진 문자열이 아닐 경우(% 변환 오류시) 반환값은 boolean FALSE입니다.
js_unescape() 소스
function js_unescape($src) {
$len = strlen($src);
$dst = array();
for ($i = 0; $i < $len; $i++) {
if ($src{$i} == '%') {
if (isset($src{$i+5}) && $src{$i+1} == 'u' &&
ctype_xdigit($src{$i+2} . $src{$i+3} . $src{$i+4} . $src{$i+5})) {
$dst[] = chr(hexdec($src{$i+2} . $src{$i+3}));
$dst[] = chr(hexdec($src{$i+4} . $src{$i+5}));
$i += 5;
} elseif (isset($src{$i+2}) && ctype_xdigit($src{$i+1} . $src{$i+2})) {
$dst[] = chr(0);
$dst[] = chr(hexdec($src{$i+1} . $src{$i+2}));
$i += 2;
} else {
return FALSE;
}
} elseif ($src{$i} >= 0x20 && $src{$i} <= 0x7E) {
$dst[] = chr(0);
$dst[] = $src{$i};
} else {
return FALSE;
}
}
return implode('', $dst);
}
js_unescape() 함수 사용법
이 함수가 반환하는 문자열은 유니코드이므로, 문자열을 받으려면 다음과 같은식으로 사용을 해야합니다. UTF-8 부분을 원하는 인코딩으로 바꾸면 됩니다. (예: EUC-KR)
$unescaped_string = js_unescape($escaped_string);
$original_string = iconv('ISO-10646-UCS-2', 'UTF-8', $unescaped_string);
소스 이해하기
전체를 설명하진 않습니다. 이해를 돕기 위한 간단한 설명일 뿐입니다. 어려운 소스도 아니니 나머지 부분은 자력으로 연구하십시오.
$src{$i}
이 는 문자열에서 한 문자를 가져오는 방법입니다. C에서는 문자열을 문자의 집합을 나타내는 포인터로 다루기 때문에 자주 쓰이지만, PHP로 시작한 분은 처음볼지도 모르겠습니다. $src = "ABCDEFG"라고 할 경우, $src{0}는 'A'를, $src{5}는 'F'를 나타내는 방식입니다.
$dst[] = chr(0);
이는 유니코드(UCS-2)의 인코딩 방식으로 인해 들어가는 부분입니다. UCS-2인코딩은 다른 인코딩과는 달리, 영숫자 등도 2바이트를 차지하게 되어있습니다. 즉, 'A'의 코드값이 0x41이 아닌, 0x0041입니다. 이를 채워넣기 위함입니다.
끝맺음
마 지막으로 강조하지만, 자바스크립트에서 인코드할때는 encodeURI(), decodeURI()를 우선적으로 고려해보시기 바랍니다. 여담으로, 문자열을 포인터로 다룰 수 없었던게 매우 귀찮았다는게 만들면서 든 생각이였습니다 -ㅅ- 혹시 오류라던지가 발생하면 알아서 고치십시오. 이 소스에 대한 모든 권리와 의무는 포기합니다.