Perl cgi를 php로 포팅중입니다. 이 함수좀 도와주세요..

mirr의 이미지

function DECODE { 
 
	if ($ENV{'REQUEST_METHOD'} eq "POST") { 
		if ($ENV{'CONTENT_LENGTH'} > 51200) { Error("내용이 너무 깁니다."); } 
		read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); 
	} else { $buffer = $ENV{'QUERY_STRING'}; } 
	@pairs = split(/&/, $buffer); 
	foreach (@pairs) { 
		($name,$value) = split(/=/, $_); 
		$value =~ tr/+/ /; 
		$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; 
 
		# 태그 처리 
		$value =~ s/</&lt;/g; 
		$value =~ s/>/&gt;/g; 
		$value =~ s/\"/&quot;/g; 
 
 
		# 줄바꿈등 처리 
		if ($name eq "ins") { 
			$value =~ s/\r\n/<br>/g; 
			$value =~ s/\r/<br>/g; 
			$value =~ s/\n/<br>/g; 
		} else { 
			$value =~ s/\r//g; 
			$value =~ s/\n//g; 
		} 
 
		# 일괄 삭제용 
		if ($name eq 'del') { push(@DEL,$value); } 
 
		$in{$name} = $value; 
	} 
	$mode = $in{'mode'}; 
	$in{'url'} =~ s/^http\:\/\///; 
	$cookie_pass = $in{'pass'}; 
	$cookie_id = $in{'id'}; 
} 

태그부분들을 파싱해서 웹브라우저에서 제대로 보일수 있도록 해주는루틴같은데요,
다른부분은 어느정도 포팅이 쉬웠는데 이부분에서 영 모르겠군요.
php로 환경변수를 이용하고 html 파싱해본적이 없어서 말이죠..

이부분 설명과 어떻게 php로 변환시킬 수 있을지 가르침좀 부탁드립니다 :roll:

nohmad의 이미지

환경변수 가져오는 부분은 getenv() 함수를 쓰면 되는데, PHP에는 POST나 GET 요청에 대한 처리가 기본으로 포함되어 있으므로, 올려주신 예제에선 사용할 일이 없습니다. 위 코드는 POST와 GET 요청을 모두 처리하므로 PHP에서는 $_POST['PARAM_NAME'], $_GET['PARAM_NAME']을 사용하면 됩니다. 그외 태그 처리 부분은 htmlspecialchars(), 몇가지 문자열 치환은 replace()나 ereg_replace(), preg_replace() 등을 사용하면 되겠네요.

그외 다른 부분은 매뉴얼 참고.
http://kr.php.net/manual/kr/

mirr의 이미지

nohmad wrote:
환경변수 가져오는 부분은 getenv() 함수를 쓰면 되는데, PHP에는 POST나 GET 요청에 대한 처리가 기본으로 포함되어 있으므로, 올려주신 예제에선 사용할 일이 없습니다. 위 코드는 POST와 GET 요청을 모두 처리하므로 PHP에서는 $_POST['PARAM_NAME'], $_GET['PARAM_NAME']을 사용하면 됩니다. 그외 태그 처리 부분은 htmlspecialchars(), 몇가지 문자열 치환은 replace()나 ereg_replace(), preg_replace() 등을 사용하면 되겠네요.

그외 다른 부분은 매뉴얼 참고.
http://kr.php.net/manual/kr/

도움 감사합니다.

function DECODE() 
{
   $buffer = $GLOBAS['HTTP_RAW_POST_DATA'];
   $pairs = split("&", $buffer);
   
   while(list(, $value) = each($pairs)) 
   {
      list($name,$value) = split("=", $pairs);
      $value = str_replace("+", " ", $value);
      $value = str_replace("%([a-fA-F0-9][a-fA-F0-9])", pack("C", hexdec(${1})), $value);
 
      # 태그 처리
      $value = htmlspecialchars("$value");
 
      # 줄바꿈등 처리
      if ($name == "ins") {
      	 $value = ereg_replace('\r\n', '<br>', $value);
      	 $value = ereg_replace('\r', '<br>', $value);
      	 $value = ereg_replace('\n', '<br>', $value);
      } else {
      	$value = ereg_replace('\r', ' ', $value);
      	$value = ereg_replace('\n', ' ', $value);
      }
 
      # 일괄 삭제용
      if ($name == 'del') { array_push($DEL, $value); }
 
      $in{$name} = $value;
   }

   $mode = $in{'mode'};
   $in{'url'} = str_replace("http://", ' ', $in{'url'});
   
   $cookie_pass = $in{'pass'};
   $cookie_id = $in{'id'};
}

이렇게 고쳐보았고 이클립스를 이용했는데 미리보기상태에선
특별한 에러메시지를 볼 수 없었습니다만, 제대로 동작하고 있는건지는
잘 모르겠습니다.
고쳐놓은 코드에서 잘못된 부분좀 지적해 주시면 감사하겠습니다.

내 마음속의 악마가 자꾸만 나를 부추겨.
늘 해왔던 것에 만족하지 말고 뭔가 불가능해 보이는 것을 하라고 말야.

sh.의 이미지

원래 함수를 1:1로 포팅하는게 중요한 상황인지는 잘 모르겠습니다만... 그게 아니라면 nohmad님이 언급하신대로 php에서는 일부러 HTTP_RAW_POST_DATA를 직접 파싱할 필요는 없습니다.

perl코드를 기준으로 할 때..

if ($ENV{'REQUEST_METHOD'} eq "POST") {
   if ($ENV{'CONTENT_LENGTH'} > 51200) { Error("내용이 너무 깁니다."); }
   read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
} else { $buffer = $ENV{'QUERY_STRING'}; }

이 부분은
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    $pairs = $_POST;
} else {
    $pairs = $_GET;
}

그리고 pairs를 & 와 = 로 구분하는것은 php에서 parse_str() 이라는 함수가 있습니다. 이 함수가 알아서 분리를 해주고요.. foreach의 초반에서 정규식으로 처리한 부분은 urldecode() 라는 함수를 사용하시면 될것같습니다.
아래의 태그처리는 htmlspecialchars()를 쓰시는게 맞고요.
아래의 줄바꿈 처리는 nl2br()을 사용하시면 됩니다.

$cookie_pass = $in{'pass'};
이런 부분은 그냥
$cookie_pass = $pairs['pass']; (post만 처리할것이라면 $_POST['pass'])
으로 하시면 되겠구요.

그런데 php로 바꾸신 부분 중에
$in{'url'} = str_replace("http://", ' ', $in{'url'});

$in{'url'} = str_replace("http://", '', $in{'url'});
' ' 안의 공백을 빼셔야 정확하게 될거같네요.

아 그런데 $in{'url'} 이런 표현이 php로는 안되는걸로 압니다.
$var = 'inurl';
$$var; 이렇게는 가능하고요 ( = $inurl)

송효진의 이미지

펄에서 직접 작성한 부분이 거의 몽땅 php에서 제공되는군요.
웹용 스크립트니 당연한거겠죠.

이것 하나 추가로 넣으시고,

function apply_all(&$arrtext, $callback, $function)
{
	if(is_array($arrtext)) {
		array_walk($arrtext, 'apply_all', $function);
	} else {
		$arrtext = $function($arrtext);
	}

	return true;
}

function DECODE()
{
	array_walk($_POST, 'apply_all', 'urldecode');
	array_walk($_POST, 'apply_all', 'htmlspecialchars');
	array_walk($_POST, 'apply_all', 'nl2br');

이렇게 시작하면 위쪽의 대부분이 처리 됩니다.
$_POST['ins'] 만 \r\n 을 <br> 로 고치고, 다른 변수는 \r\n을 없애는것만 적용 안되었군요.
귀찮으니 몽땅 <br> 넣는걸로 하죠.

$name 으로 받아와서 $in{'name'} 으로 처리 하도록 되어 있는데,
php 는 $_POST['name'] 으로 받아오니 $_POST 변수를 그냥 쓰는것을 추천합니다.
수퍼글로벌이라 펄에서 처럼 리턴 없이 그냥 사용하면 됩니다.
변수 할당 부분까지 그대로 한다면 처음에 global 선언을 해 줘야 하는 등의 불편함이 있습니다.
저 함수 내용으로는 post 되는 전체 변수도 모르는데, 알아봐야 하는 귀찮음 까지 있겠네요.

------------------

${'in' + 'url'}
${'in' + $name}

이런 표현이 가능합니다.

송효진의 이미지

다시보니 post, get 다 받도록 되어 있군요.
그걸 위해 $_REQUEST 변수가 있습니다.
편해요.

sh.의 이미지

$_REQUEST로 하시면... variables_order지시자(기본값 EGPCS)에 따라 쿠키나 세션 변수가 적용될 위험이 있습니다

변수표현은... 긴가민가했는데 php에서 그렇게 해도 되는군요 감사 :)

mirr의 이미지

효진님과 bs0048님의 도움을 통해 이렇게 고쳐보았습니다.

Quote:
function Decode()
{
if ($_SERVER['REQUEST_METHOD'] == 'POST')
{
$pairs = $_POST;
}
else
{
$pairs = $_GET;
}

$pairs = parse_str($pairs, $pairs1);

while(list($name, $value) = each($pairs1))
{
//foreach($pairs as $val)
//{
# 태그 처리, 줄바꿈등 처리
$value = array_walk($_POST, 'apply_all', 'urldecode');
$value = array_walk($_POST, 'apply_all', 'htmlspecialchars');
$value = array_walk($_POST, 'apply_all', 'nl2br');

# 일괄 삭제용
if ($name == 'del') { array_push($DEL, $value); }

$_POST['name'] = $value;
}

$mode = $_POST['mode'];
$_POST['url'] = str_replace("http://", ' ', $_POST['url']);

$cookie_pass = $_POST['pass'];
$cookie_id = $_POST['id'];
}

제대로 고친게 맞는지 가르침 부탁드립니다...
이작업 하면서 php에 대한 재미를 느끼게 ㅤㄷㅚㅆ네요.....
아무래도 이참에 php책좀 사서 정식으로 배워봐야 겠습니다..^^

내 마음속의 악마가 자꾸만 나를 부추겨.
늘 해왔던 것에 만족하지 말고 뭔가 불가능해 보이는 것을 하라고 말야.

송효진의 이미지

$_POST['name'] = 'value' 가 이미 할당 되어 있습니다.
parse_str() 은 오류가 날겁니다.

array_walk() 는 배열 전체에 한번에 적용되는것입니다.
루프 안에서 사용할 것이 아닙니다.

return 값을 넘겨야 하므로,
수퍼글로벌인 $_POST 를 그냥 사용할 것을 권해드렸습니다.
저대로는 $mode, $cookie_pass, $cookie_id 가 return 이 안됩니다.

$pairs = &${'_'.$_SERVER['REQUEST_METHOD']}; (포인터 비슷)

이렇게 하고 내부의 $_POST 를 $pairs 로 교체하면 나름 깔끔 하겠습니다.

foreach($pairs as $key => $value) {}

mirr의 이미지

function Decode() 
{ 
	if ($_SERVER['REQUEST_METHOD'] == 'POST') 
	{    
		$pairs = $_POST;
	} 
	else 
	{
		$pairs = $_GET;
    }
    
      # 태그 처리, 줄바꿈등 처리
	array_walk($pairs, 'apply_all', 'urldecode');
	array_walk($pairs, 'apply_all', 'htmlspecialchars');
	array_walk($pairs, 'apply_all', 'nl2br');

	foreach($pairs as $key => $value)
   	{	  
  		# 일괄 삭제용
                if ($name == 'del') { array_push($DEL, $value); }
   	}

   $pairs = &${'_'.$_SERVER['REQUEST_METHOD']};
   $mode = $pairs['mode'];
   $pairs['url'] = str_replace("http://", ' ', $pairs['url']);
   
   $cookie_pass = $pairs['pass'];
   $cookie_id = $pairs['id'];
}

이렇게 고치면 된건가요? ^^

내 마음속의 악마가 자꾸만 나를 부추겨.
늘 해왔던 것에 만족하지 말고 뭔가 불가능해 보이는 것을 하라고 말야.

송효진의 이미지

$pairs = &${'_'.$_SERVER['REQUEST_METHOD']};
이것을 맨위 if 문 대신 사용하세요.

DECODE 가 함수잖아요.
$mode = $pairs['mode'];
이렇게 놓고 끝내면 $mode 값은 없어집니다.
$pairs['mode'] == $_POST['mode'] 이고,
$_POST 는 함수 밖에서도 사용할 수 있는 전역변수라서
그것을 그냥 이용하시라는 것입니다.

함수 밖에서도 $pairs = &${'_'.$_SERVER['REQUEST_METHOD']};

하면 $pairs['mode'] 로 이용할 수 있습니다.

일괄삭제에서 $name 은 $key 죠.

$DEL[] = $value;
하면 됩니다.

$DEL 은 return 되어야 겠습니다.
없어지니까요.

mirr의 이미지

으흠...왠지 이해가 잘 안되고 있는데요

송효진 wrote:
DECODE 가 함수잖아요.
$mode = $pairs['mode'];
이렇게 놓고 끝내면 $mode 값은 없어집니다.
$pairs['mode'] == $_POST['mode'] 이고,
$_POST 는 함수 밖에서도 사용할 수 있는 전역변수라서
그것을 그냥 이용하시라는 것입니다.

이 부분에서 두번째 수정했을때 _POST를 사용했었는데,
다시 효진님께서 $pairs = &${'_'.$_SERVER['REQUEST_METHOD']};
로 사용하라고 하셨고, _POST로 된부분들을 pairs로 바꾸라고 하셔서 바꿨는데, 다시 POST를 이용하라는 것이 무슨말씀인지 이해가 안가구요...ㅜ,.ㅜ

Quote:

일괄삭제에서 $name 은 $key 죠.

$DEL[] = $value;
하면 됩니다.

$DEL 은 return 되어야 겠습니다.
없어지니까요.


$name을 $key로 바꾸는건 깜빡 했습니다.
근데, $DEL[] = $value로 하면 된다는 말씀은 array_push($DEL, $value); 이부분 대신
$DEL[] = $value로 대체하라는 말씀이신가요?

또 $DEL은 return되야 한다고 하셨는데, 무슨의미며, 어떻게 리턴시킬수 있는건지 모르겠습니다. ㅜ,.ㅜ

내 마음속의 악마가 자꾸만 나를 부추겨.
늘 해왔던 것에 만족하지 말고 뭔가 불가능해 보이는 것을 하라고 말야.

kirrie의 이미지

Quote:
이 부분에서 두번째 수정했을때 _POST를 사용했었는데,
다시 효진님께서 $pairs = &${'_'.$_SERVER['REQUEST_METHOD']};
로 사용하라고 하셨고, _POST로 된부분들을 pairs로 바꾸라고 하셔서 바꿨는데, 다시 POST를 이용하라는 것이 무슨말씀인지 이해가 안가구요...ㅜ,.ㅜ

$pairs = &${'_'.$_SERVER['REQUEST_METHOD']}; 이 라인은 결국 $pairs = &$_GET; 혹은 $pairs = &$_POST; 와 같은 의미입니다. 이렇게 사용하면 굳이 비교문으로 넘어오는 값이 GET인지 POST인지 구분할 필요가 없겠죠. (이거 괜찮은 방법이네요. ^^)

그리고 함수 내에서의 변수는 해당 함수 내에서만 사용할 수 있으므로(즉 함수가 종료되면 변수값도 사라지죠), 함수 밖의 메인 스크립트에서도 $pairs를 사용하려면 전역변수인 $_POST을 $pairs가 참조하도록 하라는 말씀인 것 같습니다.

Quote:
$name을 $key로 바꾸는건 깜빡 했습니다.
근데, $DEL[] = $value로 하면 된다는 말씀은 array_push($DEL, $value); 이부분 대신
$DEL[] = $value로 대체하라는 말씀이신가요?

또 $DEL은 return되야 한다고 하셨는데, 무슨의미며, 어떻게 리턴시킬수 있는건지 모르겠습니다. ㅜ,.ㅜ

$DEL[] = $value;와 array_push($value, $DEL) 둘 다 기능하는 것은 같습니다. 둘 다 배열의 끝에 새로운 원소를 추가합니다.

위와 같은 방법으로 함수가 호출되었을 때 $DEL에는 어떤 값이 들어가 있을 것이고 함수 호출이 종료되는 시점에서 $DEL변수의 값은 사라집니다. 만약 이 값을 호출된 함수가 output하게 하기 위해서 결과값을 리턴하는 과정이 필요하며, 리턴은 간단하게 함수의 끝에 return 반환할 변수값; 하시면 됩니다. 즉,

function foo ($var) {
..
..
..

return $DEL;
}

$DEL = foo($var);

이렇게 하면 foo 함수에 $var란 값을 넣어서 얻어지는 결과값 $DEL을 얻을 수 있습니다.

--->
데비안 & 우분투로 대동단결!

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.