티스토리 뷰
PHP에서 Ajax사용 (euc-kr일 경우)
이번 포스팅은 PHP에서 Ajax를 사용하는 예제를 생성해 보았다.
우선 Ajax는 UTF-8을 사용해야 된다는 점을 꼭!!! 알고 있어야한다.
따라서 EUC-KR을 사용할 경우 적절하게 인코딩과 디코딩을 해야한다.
==================================index.php==================================
<html>index.php 에서는 우선 검색할 데이터를 입력하는 table로 구성되어 있는 페이지이다.
조회일 같은 경우는 Select 박스로 생성하였으며, 페이지가 로드가 될 때 onload="javascript:calendar();" 호출하여
현재의 날짜를 가져와서 뿌려 준다.아래는 index.php page 소스이다.
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
<title>SMS로그 조회</title>
<script type="text/javascript" src="js/Common.js"></script>
<link rel="stylesheet" href="style.css" type="text/css" />
</head>
<body style="font-family:verdana,sans-serif" bgcolor="#eeeeee" onload="javascript:calendar();">
<h5>SMS Log Search Tool</h5>
<form name="search">
<table bgcolor="#ffffff">
<tr>
<td width="100" align="center" style="padding:5px 5px 5px 5px">조회일</td>
<td>:<span id="SelectView" style="padding:5px 5px 5px 10px"></span></td>
</tr>
<tr>
<td width="100" align="center" style="padding:5px 5px 5px 5px">통신사</td>
<td>:
<span style="padding:5px 5px 5px 5px">
<select name="Carrier">
<option value="1" >SKT</option>
<option value="2" >KT</option>
<option value="3" >LGU+</option>
</select>
</span>
</td>
</tr>
<tr>
<td width="100" align="center" style="padding:5px 5px 5px 5px">휴대폰 번호</td>
<td>:<span style="padding:5px 5px 5px 10px"><input type="text" name="phoneNum" onKeyPress="javaScript:IsNumKey(event);" maxlength="11"/></span></td>
</tr>
<tr align="right">
<td colspan="2" style="padding:5px 5px 5px 5px"><input type="button" value="조회" class="LongButton" onclick="javascript:getData();"/> </td>
</tr>
</table>
</br></br></br>
<div id="listDiv"></div>
</form>
</body>
</html>
==================================process.php==================================
process.php 에서는 해당 POST데이터를 가져와 Binary 파일을 실행하여 json으로 리턴하는 데이터를 가공하여
XML로 return 한다.
아래는 process.php 소스이다.
<? header("Content-type: text/xml;charset=utf-8"); require_once("./inc/function.php"); $Year = substr($_POST["Syear"],2,2); $Month = sprintf('%02d',$_POST["Smonth"]); $Day = sprintf('%02d',$_POST["Sday"]); $Date = $Year.$Month.$Day; $Phone = $_POST["phoneNum"]; $Carrier = $_POST["Carrier"]; $Res = CallLogClient($Date,$Carrier,$Phone,false); $Result = $Res["Result"]; $Data = objectToArray(jsondecode($Res["Data"])); echo "<smslog>"; if($Result=="0"){ echo "<result>$Result</result>"; echo "<TotalCount>".$Res["TotalCount"]."</TotalCount>"; echo "<IsResaller>".rawurlencode(iconv("CP949","utf-8",($Res["IsResaller"] == "Y" ? "기업형"
: "일반")))."</IsResaller>"; for( $i = 0 ; $i < sizeof($Data) ; $i++){ echo "<log>"; echo "<number>".$Data[$i]["number"]."</number>"; echo "<date>".$Data[$i]["date"]."</date>"; echo "<text>".rawurlencode(iconv("CP949","utf-8",(($Data[$i]["text"]!="") ?
$Data[$i]["text"]:"-")))."</text>"; echo "<callback>".(($Data[$i]["callback"]!="") ?$Data[$i]["callback"]:"-")."</callback>"; echo "</log>"; } }else{ echo "<result>$Result</result>"; echo "<log>"; echo "<error>".rawurlencode(iconv("CP949","utf-8",$Res["ErrMsg"]))."</error>"; echo "</log>"; } echo "</smslog>"; ?>rawurlencode : -_.을 제외한 모든 영숫자가 아닌 문자를 퍼센트(%) 사인에 이어지는 두 16진수로 교체한
문자열을 반환합니다. 이는 표시 문자가 특별한 URL 구분자로 해석되는걸 방지하고,
문자 변환이 이루어지는 전송 매체(몇몇 email 시스템 등)에서 URL을 보호하기 위한
RFC 1738에 설명된 인코딩 입니다.
==================================function.php=================================
function.php는 php에서 사용되는 함수를 정의 해 놓은 php 파일이다.
<?
$SMSLogClientBinPath = "./bin";
// SMSClient binary 파일 호출
// 호출 ex ) ./SMSLogClient 121017 xxxxxxxxxxx 1 ( 날짜, 번호, 통신사 구분 : 1.SKT 2.KT 3.LGU+ )
function CallLogClient($Day, $Carrier, $Phone, $Debug=false){
global $SMSLogClientBinPath;
$Bin = "SMSLogClient";
$Input = $SMSLogClientBinPath."/".$Bin." $Day $Phone $Carrier";
exec( $Input,$Output,$Ret );
if( $Debug ){
echo "Exec : ".trim($Input)."<BR>";
echo "Ret : ".$Ret."<BR>";
echo( "Out Line : ".trim($Output[0])."<BR>" );
exit();
}
return StrToArray($Output[0]);
}
//문자열을 Array로 변형하는 function
function StrToArray($str,$sep1=";",$sep2="="){
$Out = array();
$tok = explode($sep1,$str);
for( $i=0;$i<count($tok);$i++ )
{
$tmp = explode( $sep2,$tok[$i] );
$name = trim($tmp[0]);
$value = trim($tmp[1]);
for( $j=2;$j<count($tmp);$j++ )
$value .= $sep2.trim($tmp[$j]);
$Out[$name] = urldecode($value);
}
return $Out;
}
/**********************************************************
* *
* JSON을 Array로 만들 때 쓰는 Function *
* 해당 Function은 서버가 euc-kr일 경우 사용. *
* 만약 서버가 UTF-8인 경우 php version 5.2.1 이상이면 *
* 지원하는 함수가 있음 *
* *
***********************************************************/
//JSON Decode, Encode euc-kr용
function ToEucKr( $val ){
return iconv("UTF-8","euc-kr//IGNORE",$val );
}
function ToUTF8( $val ){
return iconv("euc-kr","UTF-8",$val );
}
//euc-kr용
function jsonencode($val) {
$tmp = obj_change_charset($val, 'utf-8', true);
$tmp = json_encode( $tmp );
return $tmp;
}
//euc-kr용
function jsondecode($val) {
$tmp = obj_change_charset($val, 'utf-8', true);
$tmp = json_decode( $tmp );
obj_change_charset( $tmp, 'euc-kr' );
return $tmp;
}
function obj_change_charset( &$obj, $tocharset='utf-8', $clone=false ) {
$obj_tmp = NULL;
if ($clone) {
$obj_tmp = is_object($obj) ? clone $obj : $obj;
}else{
$obj_tmp =& $obj;
}
switch ( gettype($obj_tmp) ) {
case 'string' :
if ('euc-kr'==$tocharset) {
$obj_tmp = ToEucKr($obj_tmp);
}else{
$obj_tmp = ToUTF8($obj_tmp);
}
break;
case 'array':
foreach ($obj_tmp as &$val) {
$val = obj_change_charset( $val, $tocharset, $clone );
}
break;
case 'object':
$object_vars = get_object_vars( $obj_tmp );
foreach ($object_vars as $key=>$val) {
$obj_tmp->$key = obj_change_charset( $val, $tocharset, $clone );
}
break;
}
return $obj_tmp;
}
///////////////////////////////////////////////////////////////////////////
/**************************************************************
* *
* objectToArray : *
* stdClass Type의 배열을 Array배열로 Convert 하는 함수 *
* *
* arrayToObject : *
* Array 배열을 stdClass Type 배열로 Convert 하는 함수 *
* *
***************************************************************/
/*
개발을 하다보면 배열을 자주 다루게 되는데 ..
배열이 아닌것이 배열처럼 보여서 작업할때 헥갈리는 경우가 있다.
그게 바로 stdClass 때문인데..
stdClass = 문자열인덱스 배열 구조라고 한다. (자세한건 잘 모르겠음 ㅡㅡ;)
예) a -> val = "value";
이렇게 선언하면 a 는 stdClass 타입의 클래스가 된다고 함.
---------------------------------------------------------------------------
stdClass 는 Json 을 사용할때도 사용 되기도 한다.
스크립트에서 ajax 사용시 넘기는 데이터 타입을 json 으로 지정하면
넘어가는 데이터가 stdClass로 넘어간다.
이럴경우 일반 배열로 다시 변환 하고 싶다면...
json_decode($aa,true); 로 선언하면 된다.
*/
// stdClass -> Array Convert
function objectToArray($d) {
if (is_object($d)) {
// Gets the properties of the given object
// with get_object_vars function
$d = get_object_vars($d);
}
if (is_array($d)) {
/*
* Return array converted to object
* Using __FUNCTION__ (Magic constant)
* for recursive call
*/
return array_map(__FUNCTION__, $d);
}
else {
// Return array
return $d;
}
}
function arrayToObject($d) {
if (is_array($d)) {
/*
* Return array converted to object
* Using __FUNCTION__ (Magic constant)
* for recursive call
*/
return (object) array_map(__FUNCTION__, $d);
}
else {
// Return object
return $d;
}
}
?>
==================================Common.js==================================
자바스크립트를 모아놓은 js 파일이다.
여기에는 여러가지 함수를 정의해 놓았다.
- calendar : 현재 날짜를 가져와 Select box를 셋팅하는 함수
(현재 일에서 미래는 select box에 나타나지 않음) - changeDate : select box의 데이터를 change하였을 때 월이 바뀔 경우
Date의 리스트를 변경하기 위한 Select box - IsNumKey : 숫자 데이터를 입력받기 위해 eventCode를 체크하는 함수
- getInstance : 비동기 통신을 하기위한 객체 생성
- getData : 비동기 통신을 하는 Function
- handleStateChange : 비동기 통신을 하여 받은 XML데이터를 가져와
index.php page에 데이터를 뿌려주는 Function
function calendar(tYear,tMonth,tDay){
var nowDate = new Date(); //오늘 날짜 객체 선언
var nYear = nowDate.getFullYear(); //오늘의 년도
var nMonth = nowDate.getMonth(); //오늘의 월 ※ 0월부터 시작
var nDate = nowDate.getDate(); //오늘의 날
var endDay=new Array(31,28,31,30,31,30,31,31,30,31,30,31); //각달의 마지막 날짜
if (tYear==null) //null 일경우, 처음 페이지가 로드 될때의 년도는
{tYear=nYear;} // 현재 년도를 가져오고
if (tMonth==null) //null 일경우, 처음 페이지가 로드 될때의 월은
{tMonth=nMonth;}//현재 월을 가져오고
if (tDay==null) //null 일경우, 처음 페이지가 로드 될때의 일은
{tDay=nDate;} //현재 일을 가져오고
eDate= new Date(); // 변경된 날짜 객체 선언
eDate.setFullYear(tYear);// 변경된 년도 세팅
eDate.setMonth(tMonth); // 변경된 월 세팅
eDate.setDate(1); // 날짜는 1일로 설정해서
var fNumday=eDate.getDay(); // 첫번째 날짜 1일의 숫자 요일
var lastDay=endDay[eDate.getMonth()]; //변경된 월의 마지막 날짜
if ((eDate.getMonth()==1)&&(((eDate.getYear()%4==0)&&(eDate.getYear() %100 !=0))||eDate.getYear() % 400 ==0 ))
{lastDay=29;} // 0월 부터 시작하므로 1는 2월임. 윤달 계산 4년마다 29일 , 100년는 28일, 400년 째는 29일
viewStr = "<select name='Syear' id='Syear' onchange='javascript:changeDate();'>";
for( i=nYear ; i >= nYear-2 ; i--){
viewStr += "<option value=\""+i+"\"";
if(i == tYear){
viewStr += " selected";
}
viewStr += ">"+i+"</option>";
}
viewStr += "</select>년 ";
viewStr += "<select name='Smonth' id='Smonth' onchange='javascript:changeDate();'>";
for( j= 1 ; j <= 12 ; j++){
viewStr += "<option value=\""+j+"\"";
if(j == tMonth+1){
viewStr += " selected";
}
viewStr += ">"+j+"</option>";
if( nYear == tYear && j > nMonth){
break;
}
}
viewStr += "</select>월 ";
viewStr += "<select name='Sday'>";
for( k=1 ; k <= lastDay ; k++){
viewStr += "<option value=\""+k+"\"";
if(k == tDay){
viewStr += " selected";
}
viewStr += ">"+k+"</option>";
if( nYear == tYear && nMonth == tMonth && k >= nDate){
break;
}
}
viewStr += "</select>일";
document.getElementById('SelectView').innerHTML = viewStr;
}
function changeDate(){
var tYear = document.search.Syear.value;
var tMonth = document.search.Smonth.value;
var tDay = document.search.Sday.value;
calendar(tYear,tMonth-1,tDay);
}
function IsNumKey(c) {
if ( c.keyCode < 48 || c.keyCode > 57){
event.returnValue = false;
return false;
}
return true;
}
var httpReq = null;
function getInstance() {
if (window.ActiveXObject) {
try {
httpReq = new ActiveXObject("Msxml2.XMLHTTP");
} catch(e) {
try {
httpReq = new ActiveXObject("Microsoft.XMLHTTP");
} catch(e1) { return null; }
}
} else if (window.XMLHttpRequest) {
httpReq= new XMLHttpRequest();
} else {
httpReq= null;
}
return httpReq;
}
function getData(){
var Syear = document.search.Syear.value;
var Smonth = document.search.Smonth.value;
var Sday = document.search.Sday.value;
var Carrier = document.search.Carrier.value;
var phoneNum = document.search.phoneNum.value;
if(isNaN(phoneNum) == true){
alert('휴대폰 번호를 다시 확인해 주십시요.');
document.search.phoneNum.value="";
return;
}
if(phoneNum.length < 10 || phoneNum.length > 11){
alert('휴대폰 번호를 다시 확인해 주십시요.');
return;
}
var CreateTable = "<table border=\"0\" bgcolor=\"#eeeeee\" id=\"listTable\">";
CreateTable += "<tr>";
CreateTable += "<td colspan=\"4\" align=\"center\"><img src='./images/loading.gif'/></td>";
CreateTable += "</tr>";
CreateTable += "</table>";
document.getElementById('listDiv').innerHTML = CreateTable;
xmlHttp = getInstance();
xmlHttp.onreadystatechange = handleStateChange;
var postString = "Syear="+Syear+"&Smonth="+Smonth+"&Sday="+Sday+"&Carrier="+Carrier+"&phoneNum="+phoneNum;
xmlHttp.open("POST", "process.php", true);
xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xmlHttp.send(postString);
}
function handleStateChange(){
if(httpReq.readyState==4){
var xmlDocument = httpReq.responseXML;
var logList = xmlDocument.getElementsByTagName("smslog")[0];
var rs = logList.getElementsByTagName("result")[0].childNodes[0].nodeValue;
if(rs == "0"){
var TotalCount = logList.getElementsByTagName("TotalCount")[0].childNodes[0].nodeValue;
var IsResaller = logList.getElementsByTagName("IsResaller")[0].childNodes[0].nodeValue;
var WriteInnerHTML = "<div align=\"left\"><h5>타입(일반/기업) : "+decodeURIComponent(IsResaller)+"</h5></div><div align=\"right\"><h5>검색된 건 수 : "+TotalCount+" 건</h5></div>";
WriteInnerHTML += "<table border=\"1\" bgcolor=\"#eeeeee\" id=\"listTable\">";
WriteInnerHTML += "<tr class=\"ResultHeader\">";
WriteInnerHTML += "<td width=\"140px\">휴대폰 번호</td>";
WriteInnerHTML += "<td width=\"120px\">보낸 시간</td>";
WriteInnerHTML += "<td width=\"700px\">문자 내용</td>";
WriteInnerHTML += "<td width=\"140px\">CallBack</td>";
WriteInnerHTML += "</tr>";
if(logList.childNodes.length <= 3){
WriteInnerHTML += "<tr>";
WriteInnerHTML += "<td colspan=\"4\" align=\"center\">검색된 데이터가 없습니다.</td>";
WriteInnerHTML += "</tr>";
WriteInnerHTML += "</table>";
document.getElementById('listDiv').innerHTML = WriteInnerHTML;
}else if(logList.childNodes.length > 3){
WriteInnerHTML += "</table>";
document.getElementById('listDiv').innerHTML = WriteInnerHTML;
var memberTBL = document.getElementById("listTable");
var tbody = memberTBL.getElementsByTagName("tbody")[0];
for(b = 3; b < logList.childNodes.length; b++){
smsLog = logList.childNodes[b];
var trElement = document.createElement("tr");
var tdElement1 = document.createElement("td");
var tdElement2 = document.createElement("td");
var tdElement3 = document.createElement("td");
var tdElement4 = document.createElement("td");
var txtElement1 = document.createTextNode(smsLog.getElementsByTagName("number")[0].childNodes[0].nodeValue);
var txtElement2 = document.createTextNode(smsLog.getElementsByTagName("date")[0].childNodes[0].nodeValue);
var txtElement3 = document.createTextNode(decodeURIComponent(smsLog.getElementsByTagName("text")[0].childNodes[0].nodeValue));
var txtElement4 = document.createTextNode(smsLog.getElementsByTagName("callback")[0].childNodes[0].nodeValue);
tdElement1.appendChild(txtElement1);
tdElement2.appendChild(txtElement2);
tdElement3.appendChild(txtElement3);
tdElement4.appendChild(txtElement4);
trElement.appendChild(tdElement1);
trElement.appendChild(tdElement2);
trElement.appendChild(tdElement3);
trElement.appendChild(tdElement4);
tbody.appendChild(trElement);
memberTBL.appendChild(tbody);
}
}
}else{
var WriteInnerHTML = "<table border=\"1\" bgcolor=\"#eeeeee\" id=\"listTable\">";
WriteInnerHTML += "<tr class=\"ResultHeader\">";
WriteInnerHTML += "<td width=\"140px\" align=\"center\">휴대폰 번호</td>";
WriteInnerHTML += "<td width=\"120px\" align=\"center\">보낸 시간</td>";
WriteInnerHTML += "<td width=\"700px\" align=\"center\">문자 내용</td>";
WriteInnerHTML += "<td width=\"140px\" align=\"center\">CallBack</td>";
WriteInnerHTML += "</tr>";
WriteInnerHTML += "<tr>";
WriteInnerHTML += "<td colspan=\"4\" width=\"1100px\" align=\"center\">"+decodeURIComponent(logList.getElementsByTagName("log")[0].childNodes[0].childNodes[0].nodeValue)+"</td>";
WriteInnerHTML += "</tr>";
WriteInnerHTML += "</table>";
document.getElementById('listDiv').innerHTML = WriteInnerHTML;
}
}
}
이상으로 EUC-KR환경에 PHP에서 AJAX를 사용하는 포스팅을 마치도록 하겠다.
'Web > PHP' 카테고리의 다른 글
[PHP]Form action Charset (0) | 2012.11.23 |
---|---|
[PHP - JSON] PHP-JSON 사용시 한글 encode-decode 구현하기 (0) | 2012.11.07 |
[PHP-JSON]PHP JSON 파싱 (0) | 2012.10.23 |