본 포스트는 네이버페이 연동하면서 진행했던 내용을 중심으로 정리하고자 한다.
다음과 같은 XML 데이터를 생성해서 응답하는 기능을 구현 한다고 가정해 보자.

<response>
   <item id="xxx">
      <name><![CDATA[ 상품명 ]]></name>
      <url>http://xxx.xxx.com/mainNew/.../xxx.php</url>
      <description><![CDATA[...상세설명...]]></description>
      <image>
         http://xxx.xxx.com/xxx_file/xxx.jpg
      </image>
      <thumb>
         http://xxx.xxx.com/xxx_file/xxx.jpg
      </thumb>
      <price>27000</price>
      <quantity>100</quantity>
      <category>
         <first id="xxx">대분류</first>
         <second id="xxx">중분류</second>
         <third id="">소분류</third>
      </category>
   </item>
</response>

이때 주의해야 할 사항 및 요령은
    
① 엘리먼트 값으로 한글이 들어가야 하는 부분에 대해 character encoding 처리를 잘 해줘야 한다. 
위의 경우는 name, description 엘리먼트에 한글 값이 설정되는 부분이다. 그리고 통상적으로 XML를 생성할 때 XML의 엘리먼트에 들어갈 값은 DB로부터 획득해서 설정하게 될 것이다. 이때 DB에 저장된 한글 데이터가 EUC-KR인지 UTF-8인지 잘 분별해서 엘리먼트에 값이 들어가도록 해야한다. 만일 DB에 저장된 데이터가 EUC-KR인데 XML 생성은 UTF-8로 한다면 다음과 같이 처리해야 한다. 그렇지 않으면 XML 생성시 Encoding error라는 XML parsing 에러가 발생되고 XML이 생성되지 않는다.

$nameFromDB = "여기에 DB로부터 가져온 name의 값이 들어있다고 하면";
$name = iconv("EUC-KR", "UTF-8", $nameFromDB);

$nameFromDB에 있는 EUC-KR 타입의 한글을 UTF-8로 변경해서 $name에 저장한다.

$descriptionFromDB = "여기에 DB로부터 가져온 description의 값이 들어있다고 하면";
$description = iconv("EUC-KR", "UTF-8", $descriptionFromDB);

② http url 정보가 들어가야 하는 엘리먼트에서(위의 경우 url, image, thumb) http url에 &가 포함되어 있을 경우 &라는 특수문자는 &문자 자체로 인식되지 않고 특수한 기능을 하는 문자로 취급되기 때문에 EntityRef: expecting ';'라는 에러 발생한다. 예를들어서 다음과 같은 경우이다.

http://xxx.xxx.com?id=1234&tid=3456
이를 경우 str_replace()함수를 이용해서 &를 &로 바꿔줘야 한다.

$itemUrl = str_replace("&", "&", $원본데이터);

③ XML을 생성중 다음과 같은 에러가 발생했다면 왜, 어디서, 어떤 이유때문에 에러가 발생했는지를 쉽게 파악할 수 있는 방법이 있다.
This page contains the following errors:
error on line 4 at column 19: xmlParseEntityRef: no name
Below is a rendering of the page up to the first error.

이 경우 웹 브라우저의 해당 페이지에서 마우스 우측 클릭하여 "페이지 소스 보기"(크롬의 경우)를 하면 아래와 같은 내용이 표시되는 4번 라인에서 url 엘리먼트에 특수문자들이 들어가 있다(아래의 경우는 에러를 의도적으로 발생시키기 위해 이 값들을 넣은 경우이다). 이를 경우 urlencode() 함수 등으로 특수 문자들을 변환해줘야 한다.

<?xml version="1.0" encoding="euc-kr"?><response>
<item id="itemid">
	<name><![CDATA[상품 명]]></name> 
	<url>http://"/:@&%=?.#"#$%=+/test.html</url> 
	<description><![CDATA[간지나는 아이템]]></description> 
	<image>http://localhost/test.jpg</image> 
	<thumb>http://localhost/test.jpg</thumb> 
	<price>1000</price> 
	<quantity>1</quantity>
	<category>
		<first id="MJ01">대분류</first>
		<second id="ML01">중분류</second>
		<third id="MN01">소분류</third> 
	</category>
</item> 
</response>

이제 본격적으로 PHP로 위의 예시와 같은 XML을 생성하는 코드를 작성해 보자.

<?php
    header('Content-Type: application/xml;charset=utf-8'); 
    echo ('<?xml version="1.0" encoding="utf-8"?>');
?>

<response>

<?php
    $dbData = "위의 XML예시에서 XML에 들어갈 item 요소가 여러개 일 경우의 데이터";	

    //아래와 같이 반복문을 통해 위의 예시의 XML에서 복수개의 item 항목을 가진 XML을 만들고자 할 경우
    for($i=0; $i<count($dbData); $i++) {
        $price = "DB로부터 가져온 가격 데이터";
        $quantity = 50;
        $itemUrl = "http://xxx.xxx.com/...";
        $imgUrl = "http://xxx.xxx.com/...";

        $nameFromDB = "여기에 DB로부터 가져온 name의 값이 들어있다고 하면";
        $name = iconv("EUC-KR", "UTF-8", $nameFromDB);

        $descriptionFromDB = "여기에 DB로부터 가져온 description의 값이 들어있다고 하면";
        $description = iconv("EUC-KR", "UTF-8", $descriptionFromDB);
?>

<item id="<?=$id?>">
	<name><![CDATA[<?=$name?>]]></name> 
	<url><?=$itemUrl?></url> 
	<description><![CDATA[<?=$description?>]]></description> 
	<image><?=$imgUrl?></image> 
	<thumb><?=$imgUrl?></thumb> 
	<price><?=$price?></price> 
	<quantity><?=$quantity?></quantity>
	<category>
		<first id="<?=$product[0][bdr_category_code1]?>">대분류</first>
		<second id="<?=$product[0][bdr_category_code2]?>">중분류</second>
		<third id="<?=$product[0][bdr_category_code3]?>">소분류</third>
	</category>
</item> 
<?php
	} //for
	//end while;
	echo('</response>');
?>

이렇게 하면 PHP에서 간단하게(?) XML을 생성해서 클라이언트들의 request에 응답할 수 있다. 
이상의 내용은 네이버페이 연동 개발을 하면서 진행했던 내용이었다.

PHP로 웹 프로그래밍시 "미팅 일시"를 기준으로 DB의 정보를 정렬해서 웹에 보여준다고 가정할때 어떤 식으로 처리하면 좋을까?

예를 들어 미팅 일시는 2018.6.19 15:30과 같은 시간이라고 가정해 보자. DB의 특정 필드에 이 값 그대로를 저장한다면 추후에 미팅 일시 필드를 기준으로 오름차순이나 내림 차순으로 정렬하기가 불편해 지게 된다.

이럴 경우에 '타임스탬프'를 이용하면 모든 것이 깔끔해진다.


타임스탬프란 1970년 1월 1일 0시 0분 0초를 기점으로 총 경과한 시간을 초 단위로 표현한 정수 값이다.

가령 2018.6.19 4:28분 정도의 시간이면(초는 귀찮으니 그냥 생략) 타임스탬프로 1529393299 정도의 값이 나올 것이다.


정리하면

 -. "미팅 일시"를 사람이 입력할때는 2018.6.19 15:30과 같은 형식으로 입력

 -. 2018.6.19 15:30의 시간을 DB에 저장할 때는 이에 해당하는 타임스탬프로 저장

 -. DB에 저장되어 있는 "미팅 일시" 필드의 타임스탬프를 기준으로 정렬 후 웹 페이지에 보여줄 때는 타임스탬프를 "년.월.일 시:분"과 같은 형태로 표시


결국은 이 과정을 위해서는 

타임스탬프 시간 ↔ 년.월.일 시:분

의 시간 형태로 상호 변환을 처리하는 과정이 필요하게 되어진다.


이를 위한 함수를 PHP에서는 제공해 주고 있다. 그 함수가

date()

strtotime() 두 함수이다.


년.월.일 시:분의 값을 타임스탬프로 변환해 보자. 

여기서 참고적으로 "1970.01.1 13:22"과 같은 형태는 strtotime() 함수가 인식하지 못하는 형태이다. 인식할수 있는 형태는

1970-01-01 13:22 혹은

1970/01/01 13:22과 같은 형태라야 한다.


$meetingTime = '1970-01-1 13:22';

echo "1970년 1월 1일 13:22을 타임스탬프 값으로 : ".strtotime($meetingTime)."<br/>";


1970년 1월 1일 13:22의 타임스탬프 값은 15720이다.

이번에는 타임스탬프의 값을 년.월.일 시:분의 형태로 변환해 보자.


$mTimeStamp = '15720';

echo "타임스탬프의 값을 한국형 시간형태로 변환 : ".date('Y.m.d H:i', $mTimeStamp)."<br/>";




PHP에서 2차원 배열의 내용을 출력하는 편리한 방법.


PHP에서 2차원 배열 전체를 출력하고자 할때 

list()함수와 each()함수를 이용하면 쉽게 구현할 수 있다.



<?php

$kkk = array(

        array('TIR', 'Tires', 100),

      array('OIL', 'Oil', 10),

      array('SPK', 'Spark Plugs', 4),

      array('ABC', 'Alphabet', 50)

          );


for($i=0; $i<4; $i++) {

while(list($k, $v) = each($kkk[$i])) {

echo $k." => ".$v."<br>";

}

echo "<br/>";

}

?>


each()함수는 배열(여기서는 $kkk)의 처음부터 차례대로 하나씩 key-value의 쌍으로 반환하다가 끝에 도달하면 자동으로 멈춘다.

list()함수는 key-value의 쌍을 2개의 변수(여기서는 $k와 $v)에 나누어 담는 역할을 한다.


위의 코드를 실행하면 아래와 같이 출력된다.


0 => TIR

1 => Tires

2 => 100


0 => OIL

1 => Oil

2 => 10


0 => SPK

1 => Spark Plugs

2 => 4


0 => ABC

1 => Alphabet

2 => 50





안드로이드에서 JSON으로 보낸 데이터를 PHP에서 수신하기


$value = json_decode() 함수를 이용한다.


$value = 

     json_decode(file_get_contents('php://input'));



입력된 JSON 값을 출력해 볼려면


$value = json_encode($value);

echo("JSON 데이터 : ".$value);





<?
session_start();
echo "세션 시작";
?>

위의 php 코드에서 아래와 같은 에러가 발생할 때

Warning: session_start() [function.session-start]: Cannot send session cache limiter - headers already sent (output started at C:\APM_Setup\htdocs\kkk\vvv.php:1) in C:\APM_Setup\htdocs\kkk\vvv.php on line 3


원인은 session_start() 앞에 다른 명령어가 없어야 되는데 있을 때 발생한다.
그런데 위의 코드에서 다른 명령어가 없는데도 이런 에러 발생하는 경우가 있는데
그 이유는 이 파일을 저장할 때 utf-8로 저장을 하면 발생한다.
이유는 utf-8의 경우는 문서를 저장할 때 문서 맨 앞에 특정한 3byte를 집어 넣는다.
이유는 utf-8임을 구별하기 위해서 이다.

따라서 이 문제가 발생하지 않을려면 방법은 두 가지

① ANSI로 저장하면 된다. 그런데 이건 웹 브라우저를 셋팅할 때 euc-kr로 설정되어 있으면 문제가 없지만 utf-8로 설정되어 있으면 ANSI로 저장한 상태에서 한 글을 사용하면 웹브라우저에서 한글이 깨지는 문제가 발생한다. 왜냐하면 ANSI는 한글을 euc-kr 형태로 표현하기 때문이다.


② utf-8로 저장하되 BOM 없음으로 저장하면 된다.
utf-8을 BOM 없음으로 저장할려면 윈도우 메모장에서는 안된다. 
Notepad++ 과 같은 것으로는 가능하다.


그런데 또 문제는 utf-8 BOM 없음으로 저장하면 한글이 깨지는 경우가 발생한다.
이 문제를 해결할려면 다음 코드를 넣으면 된다. 니하하하~~~

header("Content-Type:text/html; charset=utf-8"); ==> 이 코드를 넣어 주면 한글 깨지는 문제를 해결 할 수 있다.
혹시 euc-kr일 경우는 utf-8 대신에 euc-kr을 넣어 주면 된다.
아래 샘플 코드이다.


<?php

session_start();

header("Content-Type:text/html; charset=utf-8");

echo ("세션이 시작되었습니다. UTF-8 BOM 없음 입니다.");

?>


+ Recent posts