if (!function_exists('getallheaders')) {
/**
* Get all HTTP header key/values as an associative array for the current request.
*
* @return string[string] The HTTP header key/value pairs.
*/
function getallheaders()
{
$headers = array();
$copy_server = array(
'CONTENT_TYPE' => 'Content-Type',
'CONTENT_LENGTH' => 'Content-Length',
'CONTENT_MD5' => 'Content-Md5',
);
foreach ($_SERVER as $key => $value) {
if (substr($key, 0, 5) === 'HTTP_') {
$key = substr($key, 5);
if (!isset($copy_server[$key]) || !isset($_SERVER[$key])) {
$key = str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', $key))));
$headers[$key] = $value;
}
} elseif (isset($copy_server[$key])) {
$headers[$copy_server[$key]] = $value;
}
}
if (!isset($headers['Authorization'])) {
if (isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION'])) {
$headers['Authorization'] = $_SERVER['REDIRECT_HTTP_AUTHORIZATION'];
} elseif (isset($_SERVER['PHP_AUTH_USER'])) {
$basic_pass = isset($_SERVER['PHP_AUTH_PW']) ? $_SERVER['PHP_AUTH_PW'] : '';
$headers['Authorization'] = 'Basic ' . base64_encode($_SERVER['PHP_AUTH_USER'] . ':' . $basic_pa
ss);
} elseif (isset($_SERVER['PHP_AUTH_DIGEST'])) {
$headers['Authorization'] = $_SERVER['PHP_AUTH_DIGEST'];
}
}
return $headers;
}
}
Showing posts with label PHP. Show all posts
Showing posts with label PHP. Show all posts
Wednesday, May 25, 2016
Friday, May 20, 2016
Android PHP 인앱 구매 영수증 서버 검증
이전에 iOS와 PHP로도 인앱 구매 영수증 서버 검증을 진행했는데 이번에는 Android에도 적용해 보자.
일단 플레이스토어에 가면 다음과 같이 [서비스 및 API] > [라이센스 및 인앱 결제] 항목에 Base64 인코딩된 RSA 공개키가 있다.
이것을 .pem형식으로 다음과 같이 저장한다.
물론 PHP의 chunk_split함수를 이용해도 된다.
단, 설명문에 RSA 공개키라고 하더라도 반드시 그냥 PUBLIC KEY라고 입력해야 한다.
-----BEGIN PUBLIC KEY-----
한 줄에 64바이트씩 잘라서 입력
-----END PUBLIC KEY-----
다음은 안드로이드에서 구매후 $signature와 $data를 보내줘야 한다.
주의할 사항은 $data는 original json을 그대로 보내면 된다.
params.put("signature", info.getSignature());
params.put("data", info.getOriginalJson());
검증 PHP는 다음과 같이 구성한다.
openssl_verify가 1을 리턴하면 검증이 성공한 것이다.
function verify_android($signature) {
// key 파일을 읽음
$public_key_path="./play.pem";
$public_key = file_get_contents($public_key_path);
$public_key_id = openssl_get_publickey ($public_key);
$decoded_signature = base64_decode($signature);
$data="";
if(isset($_POST['data'])) {
$data = $_POST['data'];
}
$result = (int)openssl_verify($data, $decoded_signature, $public_key_id);
if($result == 1) {
return true;
}
else {
return false;
}
}
일단 플레이스토어에 가면 다음과 같이 [서비스 및 API] > [라이센스 및 인앱 결제] 항목에 Base64 인코딩된 RSA 공개키가 있다.
이것을 .pem형식으로 다음과 같이 저장한다.
물론 PHP의 chunk_split함수를 이용해도 된다.
단, 설명문에 RSA 공개키라고 하더라도 반드시 그냥 PUBLIC KEY라고 입력해야 한다.
-----BEGIN PUBLIC KEY-----
한 줄에 64바이트씩 잘라서 입력
-----END PUBLIC KEY-----
다음은 안드로이드에서 구매후 $signature와 $data를 보내줘야 한다.
주의할 사항은 $data는 original json을 그대로 보내면 된다.
params.put("signature", info.getSignature());
params.put("data", info.getOriginalJson());
검증 PHP는 다음과 같이 구성한다.
openssl_verify가 1을 리턴하면 검증이 성공한 것이다.
function verify_android($signature) {
// key 파일을 읽음
$public_key_path="./play.pem";
$public_key = file_get_contents($public_key_path);
$public_key_id = openssl_get_publickey ($public_key);
$decoded_signature = base64_decode($signature);
$data="";
if(isset($_POST['data'])) {
$data = $_POST['data'];
}
$result = (int)openssl_verify($data, $decoded_signature, $public_key_id);
if($result == 1) {
return true;
}
else {
return false;
}
}
PHP Visual Studio Code에서 패스설정하기
새로나온 에디터인 Visual Studio Code에서 다음과 같이 PHP파일을 편집하다 보면 에러 메세지가 나올 때가 있다.
Cannot validate the php file. The php program was not found. Use the 'php.validate.executablePath' setting to configure the location of 'php'
그럴 때는 파일 > 기본설정 > 사용자 설정 에서 다음과 같이 PHP 실행파일 패스를 입력한다.
Cannot validate the php file. The php program was not found. Use the 'php.validate.executablePath' setting to configure the location of 'php'
그럴 때는 파일 > 기본설정 > 사용자 설정 에서 다음과 같이 PHP 실행파일 패스를 입력한다.
PHP json_encode 후에 앞에 이상한 문자가 추가되는 현상(strange character)
PHP로 json_encode하여서 클라이언트에서 응답을 받았는데, android studio 화면상에 보이는 문자와 실제의 문자열의 길이가 달랐다. 그리고 JSONObject의 parse가 자꾸 실패를 하게 되었다.
이렇게 되는 원인을 찾았는데 PHP 소스파일의 인코딩이 UTF-8 with BOM으로 되어 있었다. 이것을 UTF-8로 변경해주면 문제 없이 동작한다.
최근에 atom, vscode등 여러가지 에디터를 변경하면서 생긴 문제이다. 항상 기존의 코드와인코딩이 맞는지를 항상 확인하자.
이렇게 되는 원인을 찾았는데 PHP 소스파일의 인코딩이 UTF-8 with BOM으로 되어 있었다. 이것을 UTF-8로 변경해주면 문제 없이 동작한다.
최근에 atom, vscode등 여러가지 에디터를 변경하면서 생긴 문제이다. 항상 기존의 코드와인코딩이 맞는지를 항상 확인하자.
Monday, May 16, 2016
iOS PHP 인앱 구매 영수증 서버 검증
//iOS -(void)serverVerfication:(SKPaymentTransaction*)transaction andRestore:(BOOL)isRestore
{
NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
NSString *user_id = [userDefault objectForKey:@"uid"];
NSString *item_id = transaction.payment.productIdentifier;
// 추가된 order_id(구글과 맞추기 위해서 용어를 변경하였다.)
NSString *order_id;
int restore = 0;
if(isRestore == YES) {
order_id = transaction.originalTransaction.transactionIdentifier;
restore = 1;
}
else {
order_id = transaction.transactionIdentifier;
}
// Load the receipt from the app bundle.
NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
NSData *receipt = [NSData dataWithContentsOfURL:receiptURL];
// Create the JSON object that describes the request
NSError *error;
NSDictionary *requestContents = @{
@"receipt-data": [receipt base64EncodedStringWithOptions:0],
@"platform": @"ios",
@"item_id": item_id,
@"order_id": order_id,
@"user_id": user_id,
@"restore": [NSNumber numberWithInt:restore],
@"sandbox": [NSNumber numberWithInt:0]
};
NSData *requestData = [NSJSONSerialization dataWithJSONObject:requestContents
options:0
error:&error];
// Create a POST request with the receipt data.
// NSURL *storeURL = [NSURL URLWithString:@"https://sandbox.itunes.apple.com/verifyReceipt"];
//검증하려고 하는 자체 서버
NSURL *storeURL = [NSURL URLWithString:[URLManager getPaymentLog]];
NSMutableURLRequest *storeRequest = [NSMutableURLRequest requestWithURL:storeURL];
[storeRequest setHTTPMethod:@"POST"];
[storeRequest setHTTPBody:requestData];
// Make a connection to the iTunes Store on a background queue.
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[NSURLConnection sendAsynchronousRequest:storeRequest queue:queue
completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
if (connectionError) {
/* ... Handle error ... */
} else {
NSError *error;
NSString *jsonData = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
NSDictionary *jsonResponse = [NSJSONSerialization JSONObjectWithData:[jsonData dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingAllowFragments error:&error];
if (!jsonResponse) { /* ... Handle error ...*/
}
/* ... Send a response back to the device ... */
NSNumber *result = [jsonResponse objectForKey:@"result"];
if(result == nil) {
NSLog(@"구매 인증 실패");
handleSendBuyEvent(-1, 0);// M_E_ERROR = -1
}
else {
if([result longValue] == 0) {
NSLog(@"구매 인증 성공");
[self provideContent: transaction.payment.productIdentifier];
}
else {
NSLog(@"구매 인증 실패 %d", [result longValue]);
handleSendBuyEvent(-1, 0);// M_E_ERROR = -1
}
}
}
}];
}
//PHP
//JSON데이터를 $_POST에 넣어준다
$postdata = file_get_contents("php://input");
$_POST = json_decode($postdata, true);
function verify($sandbox, $receipt) {
// Environment sandbox인지 체크
// 영수증을 애플 서버에 보내자
$endpoint = "";
// 샌드박스일 경우
if($sandbox == 1) {
$endpoint = 'https://sandbox.itunes.apple.com/verifyReceipt';
}
else {// 실결제일 경우
$endpoint = 'https://buy.itunes.apple.com/verifyReceipt';
}
error_log("endpoint=$endpoint");
$postData = json_encode(array('receipt-data' => $receipt));
// curl로 요청하자
$ch = curl_init($endpoint);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION , true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
$response = curl_exec($ch);
$errno = curl_errno($ch);
$errmsg = curl_error($ch);
curl_close($ch);
error_log("response=$response");
if($errno)
error_log("errno=$errno");
if($errmsg)
error_log("errmsg=$errmsg");
error_log("response ok");
$data = json_decode($response);
error_log("data=".print_r($data, true));
if(!is_object($data)) {
return false;
}
if(!isset($data->status) || $data->status != 0) {
return false;
}
return true;
}
// 2. 애플 영수증 검증
// 실결제를 먼저하고, 샌드박스 결제를 검증해야 한다.
// 왜냐하면 애플 심사과정에서는 샌드박스로 테스트를 하기 때문이다.
if(strlen($receipt) > 0) {
if(!verify(0, $receipt)) {// 실결제 테스트
if(!verify(1, $receipt)) {// 샌드박스 테스트
// 실결제, 샌드박스 둘다 실패하면 에러다
$ret = array("result" => 5, "error" => "receipt error");
echo json_encode($ret);
exit;
}
}
}
// 문제없이 exit가 안되었다면 검증이 성공한 것이다.
{
NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
NSString *user_id = [userDefault objectForKey:@"uid"];
NSString *item_id = transaction.payment.productIdentifier;
// 추가된 order_id(구글과 맞추기 위해서 용어를 변경하였다.)
NSString *order_id;
int restore = 0;
if(isRestore == YES) {
order_id = transaction.originalTransaction.transactionIdentifier;
restore = 1;
}
else {
order_id = transaction.transactionIdentifier;
}
// Load the receipt from the app bundle.
NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
NSData *receipt = [NSData dataWithContentsOfURL:receiptURL];
// Create the JSON object that describes the request
NSError *error;
NSDictionary *requestContents = @{
@"receipt-data": [receipt base64EncodedStringWithOptions:0],
@"platform": @"ios",
@"item_id": item_id,
@"order_id": order_id,
@"user_id": user_id,
@"restore": [NSNumber numberWithInt:restore],
@"sandbox": [NSNumber numberWithInt:0]
};
NSData *requestData = [NSJSONSerialization dataWithJSONObject:requestContents
options:0
error:&error];
// Create a POST request with the receipt data.
// NSURL *storeURL = [NSURL URLWithString:@"https://sandbox.itunes.apple.com/verifyReceipt"];
//검증하려고 하는 자체 서버
NSURL *storeURL = [NSURL URLWithString:[URLManager getPaymentLog]];
NSMutableURLRequest *storeRequest = [NSMutableURLRequest requestWithURL:storeURL];
[storeRequest setHTTPMethod:@"POST"];
[storeRequest setHTTPBody:requestData];
// Make a connection to the iTunes Store on a background queue.
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[NSURLConnection sendAsynchronousRequest:storeRequest queue:queue
completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
if (connectionError) {
/* ... Handle error ... */
} else {
NSError *error;
NSString *jsonData = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
NSDictionary *jsonResponse = [NSJSONSerialization JSONObjectWithData:[jsonData dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingAllowFragments error:&error];
if (!jsonResponse) { /* ... Handle error ...*/
}
/* ... Send a response back to the device ... */
NSNumber *result = [jsonResponse objectForKey:@"result"];
if(result == nil) {
NSLog(@"구매 인증 실패");
handleSendBuyEvent(-1, 0);// M_E_ERROR = -1
}
else {
if([result longValue] == 0) {
NSLog(@"구매 인증 성공");
[self provideContent: transaction.payment.productIdentifier];
}
else {
NSLog(@"구매 인증 실패 %d", [result longValue]);
handleSendBuyEvent(-1, 0);// M_E_ERROR = -1
}
}
}
}];
}
//PHP
//JSON데이터를 $_POST에 넣어준다
$postdata = file_get_contents("php://input");
$_POST = json_decode($postdata, true);
function verify($sandbox, $receipt) {
// Environment sandbox인지 체크
// 영수증을 애플 서버에 보내자
$endpoint = "";
// 샌드박스일 경우
if($sandbox == 1) {
$endpoint = 'https://sandbox.itunes.apple.com/verifyReceipt';
}
else {// 실결제일 경우
$endpoint = 'https://buy.itunes.apple.com/verifyReceipt';
}
error_log("endpoint=$endpoint");
$postData = json_encode(array('receipt-data' => $receipt));
// curl로 요청하자
$ch = curl_init($endpoint);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION , true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
$response = curl_exec($ch);
$errno = curl_errno($ch);
$errmsg = curl_error($ch);
curl_close($ch);
error_log("response=$response");
if($errno)
error_log("errno=$errno");
if($errmsg)
error_log("errmsg=$errmsg");
error_log("response ok");
$data = json_decode($response);
error_log("data=".print_r($data, true));
if(!is_object($data)) {
return false;
}
if(!isset($data->status) || $data->status != 0) {
return false;
}
return true;
}
// 2. 애플 영수증 검증
// 실결제를 먼저하고, 샌드박스 결제를 검증해야 한다.
// 왜냐하면 애플 심사과정에서는 샌드박스로 테스트를 하기 때문이다.
if(strlen($receipt) > 0) {
if(!verify(0, $receipt)) {// 실결제 테스트
if(!verify(1, $receipt)) {// 샌드박스 테스트
// 실결제, 샌드박스 둘다 실패하면 에러다
$ret = array("result" => 5, "error" => "receipt error");
echo json_encode($ret);
exit;
}
}
}
// 문제없이 exit가 안되었다면 검증이 성공한 것이다.
Thursday, April 28, 2016
Tuesday, December 15, 2015
Mac 기본 웹서버 apache root 폴더
/Library/WebServer/Documents
/etc/apache2/httpd.conf
sudo /usr/sbin/apachectl restart
/etc/apache2/httpd.conf
sudo /usr/sbin/apachectl restart
Sunday, December 13, 2015
Ubuntu The mcrypt extension is missing. PHP
php5-fpm과 nginx환경에서 phpmyadmin을 실행과정에서 다음과 같은 에러가 발생했다.
The mcrypt extension is missing. Please check your PHP configuration.
해결방법은 다음과 같다.
sudo apt-get install php5-mcrypt
sudo php5enmod mcrypt
sudo service php5-fpm restart
sudo service nginx restart
The mcrypt extension is missing. Please check your PHP configuration.
해결방법은 다음과 같다.
sudo apt-get install php5-mcrypt
sudo php5enmod mcrypt
sudo service php5-fpm restart
sudo service nginx restart
CentOS nginx phpMyAdmin 설치
# 확장 패키지(EPEL)가 있는지 확인
rpm -qa epel-release
# 확장 패키지 설치
yum install epel-release
# phpMyAdmin 설치
yum install phpMyAdmin
# 설치폴더
/usr/share/phpMyAdmin
# 폴더 심볼릭 링크 생성
cd /usr/share/nginx/html
ln -s /usr/share/phpMyAdmin phpMyAdmin
Tuesday, December 1, 2015
PHP CDKEY Coupon Number Generation Source
<?php
//Returns a random number with a specified number of digits, up to 10. If 4, a random number between 1000 and 9999.
function get_rand_number($len=4) {
$len = abs((int)$len);
if ($len < 1) $len = 1;
else if ($len > 10) $len = 10;
return rand(pow(10, $len - 1), (pow(10, $len) - 1));
}
//Converts the passed three-digit number to hexadecimal and returns it. Used only through preg_match_callback.
function get_simple_36($m){
$str = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
$div = floor($m[0] / 36);
$rest = $m[0] % 36;
return $str[$div] . $str[$rest];
}
//Returns an array of all the prime numbers that exist in the specified number of digits. max len = 5
function get_simple_prime_number($len=5){
$len = abs((int)$len);
if ($len < 1) $len = 1;
else if ($len > 5) $len = 5;
$prime_1 = Array(1, 2, 3, 5, 7);
if ($len == 1) return $prime_1;
$start = pow(10, ($len - 1)) + 1;//101
$end = pow(10, $len) - 1;//999
$prime = $prime_1;
unset($prime[0]);//Remove 1
unset($prime[1]);//Remove 2
$array = Array();
for($i = 11; $i <= $end; $i+=2){//There are no even prime numbers greater than 10.
$max = floor(sqrt($i));
foreach($prime as $j) {
if ($j > $max) break;
if ($i % $j == 0) continue 2;
}
$prime[] = $i;
if ($i >= $start) $array[] = $i;
}
return $array;
}
//Returns a serial with a specified number of digits. If you don't want to include -, $cut must be greater than or equal to $len. max len = 36
function get_serial($len=16, $cut=4, $hipen='-'){
$len = abs((int)$len);
if ($len < 1) $len = 16;
else if ($len > 36) $len = 36;
$cut = abs((int)$cut);
if ($cut < 1) $cut = 4;
else if ($cut > $len) $cut = $len;
list($usec, $sec) = explode(' ', microtime());
$base_number = (string)$sec . str_replace('0.', '', (string)$usec);
$base_number .= (string)get_rand_number(10) . (string)get_rand_number(8);//36 digit unique numeric string
$prime = get_simple_prime_number(5);//5 digit decimal array
shuffle($prime);
$prime = $prime[0];//random 5 digit prime number
$serial = bcmul(substr($base_number, 0, $len), $prime);
$serial_length = strlen($serial);
$sub = $len - $serial_length;
if ($sub > 0) $serial .= (string)get_rand_number($sub);
else if ($sub < 0) $serial = substr($serial, 0, $len);
return preg_replace("`(.{" . $cut . "})`", "$1" . $hipen, $serial, floor(($len-1) / $cut));
}
//Returns a serial with a number and an English letter with a specified number of digits. If you don't want to include -, $cut must be greater than or equal to $len. max len = 24
function get_serial_mix($len=16, $cut=4, $hipen='-'){
$len = abs((int)$len);
if ($len < 1) $len = 16;
else if ($len > 24) $len = 24;
$cut = abs((int)$cut);
if ($cut < 1) $cut = 4;
else if ($cut > $len) $cut = $len;
$len2 = (int)($len * 3 / 2);
if ($len2 % 2 == 1) $len2 += 1;
$serial = get_serial($len2, $len2, $hipen);
$serial = substr(preg_replace_callback("`.{3}`", "get_simple_36", $serial), 0, $len);
return preg_replace("`(.{" . $cut . "})`", "$1" . $hipen, $serial, floor(($len-1) / $cut));
}
echo get_serial_mix(36, 4, '-');
?>
Monday, April 27, 2015
PHP extension 로딩 확인
PHP 프로그래밍을 할때 특정 extension이 올라와 있는지 확인해야 될 때가 있다. 이럴땐 다음과 같이 하면 정확하게 알 수가 있다.
그러나 유의해야 할 점이 php.ini의 패스 우선순위대로 가장 높은 우선순위의 php.ini를 기준으로 한다는 점이다. 여러군데에 php.ini가 있으면, 현재 패스의 php.ini가 가장 높은 우선순위를 갖는다. 그래서 테스트 하기전에 php.ini를 현재 패스로 복사한 후에 테스트 하면 가장 정확하다.
php -m
그러나 유의해야 할 점이 php.ini의 패스 우선순위대로 가장 높은 우선순위의 php.ini를 기준으로 한다는 점이다. 여러군데에 php.ini가 있으면, 현재 패스의 php.ini가 가장 높은 우선순위를 갖는다. 그래서 테스트 하기전에 php.ini를 현재 패스로 복사한 후에 테스트 하면 가장 정확하다.
php -m
PHP 소스파일 터미널에서 테스트
PHP 단일 파일을 웹브라우저를 띄우지 않고 터미널에서 간단하게 테스트 할수있다.
다음과 같이 하면 test.php의 결과 내용이 터미널에 출력된다.
php -f test.php
다음과 같이 하면 test.php의 결과 내용이 터미널에 출력된다.
php -f test.php
PHP version 확인
PHP는 extension dll이나 so를 개발할 때나 여러가지 이유로 PHP version을 확인해야할 필요가 있다.
다음과 같이 입력하면 간단하게 확인할 수가 있다.
php -v
다음과 같이 입력하면 간단하게 확인할 수가 있다.
php -v
Monday, April 6, 2015
PHP 4.0 SOAP
PHP로 SOAP을 구현하려면 PHP5가 있어야 된다.
PHP5에만 SOAP이 내장되어 있다.
그러나 PHP4에서 구현을 하려면 NuSOAP을 사용하면 된다.
그리고 PHP5도 동일한 방법을 사용하면 되기 때문에 NuSOAP으로 하는것이 편하다.
nusoap-0.7.3.zip
nusoap-docs-0.7.3.zip
Mail_Mime-1.4.0.gz
세개의 파일이 필요한데
Mime은 NuSOAP 0.7.3에서 바이너리를 SOAP으로 보낼때 쓴다.
첨부된 nusoap.zip을 받고
htdocs폴더에다 lib에 풀고
// NuSOAP설정
include_once('lib/nusoap.php');
include_once('lib/nusoapmime.php');
// WSDL설정
$wsdl = 'http://url/WebService/Service?wsdl';
// NuSOAP설정
$client = new nusoap_client($wsdl, 'wsdl');
$client->setEndpoint("'http://url/WebService/Service");
위와 같이 하면 함수를 호출할 수 있다.
반드시 endPoint를 설정해야 한다.
다운로드
PHP5에만 SOAP이 내장되어 있다.
그러나 PHP4에서 구현을 하려면 NuSOAP을 사용하면 된다.
그리고 PHP5도 동일한 방법을 사용하면 되기 때문에 NuSOAP으로 하는것이 편하다.
nusoap-0.7.3.zip
nusoap-docs-0.7.3.zip
Mail_Mime-1.4.0.gz
세개의 파일이 필요한데
Mime은 NuSOAP 0.7.3에서 바이너리를 SOAP으로 보낼때 쓴다.
첨부된 nusoap.zip을 받고
htdocs폴더에다 lib에 풀고
// NuSOAP설정
include_once('lib/nusoap.php');
include_once('lib/nusoapmime.php');
// WSDL설정
$wsdl = 'http://url/WebService/Service?wsdl';
// NuSOAP설정
$client = new nusoap_client($wsdl, 'wsdl');
$client->setEndpoint("'http://url/WebService/Service");
위와 같이 하면 함수를 호출할 수 있다.
반드시 endPoint를 설정해야 한다.
다운로드
Thursday, April 2, 2015
PHP 추천 이유
저는 돈많은 업체가 아니라면 PHP를 권합니다.
PHP의 장점은 오픈소스이고 C를 다 몰라도 사용할 수 있을만큼 학습곡선이 가파르고 공개되어 있는 함수, OOP 클래스가 무궁무진하다는 것이죠. (것도 소스까지 공개되어서)
그리고, 어떤 언어든지 그 확장성은 꼭 언어 자체에만 있지 않습니다.
PHP로 작성한 사이트도 웹서버와 HA 오픈소스 프로젝트와 연계하면 얼마든지 확장성을 갖습니다.
결국 시스템 소프트웨어와 함께 통합했을 때 빛을 발합니다.
하지만, 오픈소스의 장점이 우리나라 IT 시장에선 껌팔이 소년 취급을 받고 있다는 것이 문제이긴 하지요.
(저는 이러한 문화적 현상을 농공행상을 무시했던 양반문화 잔재와 무관치 않다고 생각합니다)
ASP는 다양한 유료 컴포넌트를 사용해 보고 싶다면 도전해 보세요.
그 고유한 패쇄성과 답답한 인터페이스를 파고 들 시간이면 다른 언어를 하나 더 배우는 게 낫습니다.
자바, JSP를 보자면, 그 구조 자체가 상대적으로 복잡합니다. (현업에 계신 분들이라면 다들 인정하시겠죠?)
개인적으로 JSP -> Servlet java -> Java class로 이어지는 자바 아키텍처가 좀 억지라고 생각합니다.
(그냥 고집스럽게 서블릿으로 다 하지 왜 그랬어?라는 생각이 절로 드네요.)
결정적으로, 자바는 "플랫폼 독립적"이라는 달콤한 주장으로 시장을 먹어댔죠.
(저는 자바가 "플랫폼 독립적"이라는 주장에 대해 "그건 개한테나 가져다 주어라"고 말합니다.
이것은 자바 개발자들의 머리 속에나 존재하는 망상이지, 현실은 꼭 그렇지 않습니다.
물론 C나 다른 언어의 불편한 점을 개선한 부분도 있지만 그게 교과서나 여러 책자에 나오는 것처럼 완벽하지가 않고 완벽할 수도 없습니다.
차라리 Java가 platform less-dependent라고 주장한다면 저는 동의할 수 있습니다.)
그건 그렇고, 현실적으로 우리나라 공공기관, 공기업 대부분은 자바와 JSP가 아니면 명함을 내밀수 없습니다.
저도 처음엔 왜 그럴까 고민했죠.
그런데 공공기관 프로젝트 몇 건을 해보니 그 이유를 알겠더군요.
공공기관 프로젝트의 주요 고문 내지 소위 전문가 인력풀의 다수가 누군지 아십니까?
바로 대학교수들입니다.
자기들이 학교에서는 "교수님, 교수님" 소리 들어가면서 학생들에게 존경과 추앙을 받는지는 모르겠습다만
도대체 서비스와 관련된 실제 코딩은 얼마나 해봤는지 묻고 싶을 정도로 어이없는 질문과 지적을 받아본 저로서는
대학무용론을 주장하고 싶을 정도입니다.
어쨌든 이야기 하고자 하는 것은 이 샌님들 머리 속에는 온통 ideal solution으로 패러다임이 꽉 차있다는 것입니다.
Java가 학부 커리큘럼의 상당부분을 차지하고 있는 것 역시 이런 이런 패러다임의 산물입니다.
특히 유학을 통해 학위를 취득한 교수들은 자신들이 수학했던 학교에서 오라클의 자바와 관련한 수많은 소프트웨어를 접합니다.
(우리나라의 현실은 아닙니다만 미국, 영연방의 쓸만한 대학들은 오라클의 지원을 받습니다. 쉽게 말해 소프트웨어를 다 거저 줍니다. 학교로선 돈이 안드니 좋을 수 밖에요.)
그들이 배운 교과서에는 자바가 거의 완벽한 플랫폼 독립적인 언어이고 때문에 architecture neutral에 가장 가깝다고 생각하는 모양입니다. 게다가 OOP죠.
소위 시대적 패러다임을 적절히 갖춘 언어가 자바라고 스스로 깨닫기 보다는 책을 통해 배우고 그렇게 수년간이나 훈련 받게 됩니다.
이런 사람들이 XX위원, 감리, 고문을 지내고 있는 현실에서 Java, JSP로 공공기관 사이트가 도배되다시피 하는 현상은 전혀 이상해 보이지 않는다 하겠죠.
즉, 배운 거 풀어먹기 좋게 시장을 조절하는 것입니다.
단순히 자바가 더 좋고 PHP가 꼬지다고 비교할 게재가 아닙니다.
세상에서 누가 더 큰 소릴 내고 있느냐는 아주 드러운 현실의 문제죠.
PHP의 장점은 오픈소스이고 C를 다 몰라도 사용할 수 있을만큼 학습곡선이 가파르고 공개되어 있는 함수, OOP 클래스가 무궁무진하다는 것이죠. (것도 소스까지 공개되어서)
그리고, 어떤 언어든지 그 확장성은 꼭 언어 자체에만 있지 않습니다.
PHP로 작성한 사이트도 웹서버와 HA 오픈소스 프로젝트와 연계하면 얼마든지 확장성을 갖습니다.
결국 시스템 소프트웨어와 함께 통합했을 때 빛을 발합니다.
하지만, 오픈소스의 장점이 우리나라 IT 시장에선 껌팔이 소년 취급을 받고 있다는 것이 문제이긴 하지요.
(저는 이러한 문화적 현상을 농공행상을 무시했던 양반문화 잔재와 무관치 않다고 생각합니다)
ASP는 다양한 유료 컴포넌트를 사용해 보고 싶다면 도전해 보세요.
그 고유한 패쇄성과 답답한 인터페이스를 파고 들 시간이면 다른 언어를 하나 더 배우는 게 낫습니다.
자바, JSP를 보자면, 그 구조 자체가 상대적으로 복잡합니다. (현업에 계신 분들이라면 다들 인정하시겠죠?)
개인적으로 JSP -> Servlet java -> Java class로 이어지는 자바 아키텍처가 좀 억지라고 생각합니다.
(그냥 고집스럽게 서블릿으로 다 하지 왜 그랬어?라는 생각이 절로 드네요.)
결정적으로, 자바는 "플랫폼 독립적"이라는 달콤한 주장으로 시장을 먹어댔죠.
(저는 자바가 "플랫폼 독립적"이라는 주장에 대해 "그건 개한테나 가져다 주어라"고 말합니다.
이것은 자바 개발자들의 머리 속에나 존재하는 망상이지, 현실은 꼭 그렇지 않습니다.
물론 C나 다른 언어의 불편한 점을 개선한 부분도 있지만 그게 교과서나 여러 책자에 나오는 것처럼 완벽하지가 않고 완벽할 수도 없습니다.
차라리 Java가 platform less-dependent라고 주장한다면 저는 동의할 수 있습니다.)
그건 그렇고, 현실적으로 우리나라 공공기관, 공기업 대부분은 자바와 JSP가 아니면 명함을 내밀수 없습니다.
저도 처음엔 왜 그럴까 고민했죠.
그런데 공공기관 프로젝트 몇 건을 해보니 그 이유를 알겠더군요.
공공기관 프로젝트의 주요 고문 내지 소위 전문가 인력풀의 다수가 누군지 아십니까?
바로 대학교수들입니다.
자기들이 학교에서는 "교수님, 교수님" 소리 들어가면서 학생들에게 존경과 추앙을 받는지는 모르겠습다만
도대체 서비스와 관련된 실제 코딩은 얼마나 해봤는지 묻고 싶을 정도로 어이없는 질문과 지적을 받아본 저로서는
대학무용론을 주장하고 싶을 정도입니다.
어쨌든 이야기 하고자 하는 것은 이 샌님들 머리 속에는 온통 ideal solution으로 패러다임이 꽉 차있다는 것입니다.
Java가 학부 커리큘럼의 상당부분을 차지하고 있는 것 역시 이런 이런 패러다임의 산물입니다.
특히 유학을 통해 학위를 취득한 교수들은 자신들이 수학했던 학교에서 오라클의 자바와 관련한 수많은 소프트웨어를 접합니다.
(우리나라의 현실은 아닙니다만 미국, 영연방의 쓸만한 대학들은 오라클의 지원을 받습니다. 쉽게 말해 소프트웨어를 다 거저 줍니다. 학교로선 돈이 안드니 좋을 수 밖에요.)
그들이 배운 교과서에는 자바가 거의 완벽한 플랫폼 독립적인 언어이고 때문에 architecture neutral에 가장 가깝다고 생각하는 모양입니다. 게다가 OOP죠.
소위 시대적 패러다임을 적절히 갖춘 언어가 자바라고 스스로 깨닫기 보다는 책을 통해 배우고 그렇게 수년간이나 훈련 받게 됩니다.
이런 사람들이 XX위원, 감리, 고문을 지내고 있는 현실에서 Java, JSP로 공공기관 사이트가 도배되다시피 하는 현상은 전혀 이상해 보이지 않는다 하겠죠.
즉, 배운 거 풀어먹기 좋게 시장을 조절하는 것입니다.
단순히 자바가 더 좋고 PHP가 꼬지다고 비교할 게재가 아닙니다.
세상에서 누가 더 큰 소릴 내고 있느냐는 아주 드러운 현실의 문제죠.
Thursday, December 11, 2014
PHP json_decode후 데이터 접근하기
다음과 같이 데이터를 json_decode한 후에 그 내용을 접근하려면 다음과 같이 한다.
$json_result = json_decode($rawPost);
$serviceId = $json_result->{'serviceId'};
문제는 배열 접근하듯이 []가 아니라 {}라는 점이다. 예전 버전에는 그냥 $json_result->serviceId 이렇게 하면 되었었는데 지금은 그게 안되는 것 같다.
$json_result = json_decode($rawPost);
$serviceId = $json_result->{'serviceId'};
문제는 배열 접근하듯이 []가 아니라 {}라는 점이다. 예전 버전에는 그냥 $json_result->serviceId 이렇게 하면 되었었는데 지금은 그게 안되는 것 같다.
PHP 에러메세지 표시하기
요즘 PHP버전은 에러메세지가 표시하지 않게 되어 있다. 그래서 다음과 같이 PHP문 처음에명시하면 모든 에러메세지를 받을 수 있다.
error_reporting(E_ALL);
ini_set("display_errors", 1);
error_reporting(E_ALL);
ini_set("display_errors", 1);
Wednesday, December 10, 2014
PHP JSON POST data stream 받기
http://stackoverflow.com/questions/4369759/how-to-recieve-post-data-sent-using-application-octet-stream-in-php
같이 일하는 회사에서 JSON 포맷을 data stream 형태로 POST 방식으로 보내준다고 하였다. 그런데 PHP를 한지 하도 오래되어서 몰랐는데 이런 것이 있었다. 정식 명칭은 application/octet-stream이다.
$rawPost = file_get_contents('php://input');
같이 일하는 회사에서 JSON 포맷을 data stream 형태로 POST 방식으로 보내준다고 하였다. 그런데 PHP를 한지 하도 오래되어서 몰랐는데 이런 것이 있었다. 정식 명칭은 application/octet-stream이다.
$rawPost = file_get_contents('php://input');
Thursday, September 11, 2014
XAMPP를 설치후에 localhost가 제대로 안나올때
XAMPP를 설치후에 localhost를 입력하면 localhost/xampp/로 이동한다.
이렇게 동작하는 이유는 index.php안에 다음과 같이 redirect 명령이 들어 있기 때문이다.
<?php
if (!empty($_SERVER['HTTPS']) && ('on' == $_SERVER['HTTPS'])) {
$uri = 'https://';
} else {
$uri = 'http://';
}
$uri .= $_SERVER['HTTP_HOST'];
header('Location: '.$uri.'/xampp/');
exit;
?>
Something is wrong with the XAMPP installation :-(
이렇게 동작하는 이유는 index.php안에 다음과 같이 redirect 명령이 들어 있기 때문이다.
<?php
if (!empty($_SERVER['HTTPS']) && ('on' == $_SERVER['HTTPS'])) {
$uri = 'https://';
} else {
$uri = 'http://';
}
$uri .= $_SERVER['HTTP_HOST'];
header('Location: '.$uri.'/xampp/');
exit;
?>
Something is wrong with the XAMPP installation :-(
그래서 c:\xampp\htdocs\index.php를 이름만 index1.php로 변경하면 index.html이 정상적으로 로딩된다.
PHP SOAP 구현
PHP로 SOAP을 구현하려면 PHP5가 있어야 된다.
PHP5에만 SOAP이 내장되어 있다.
그러나 PHP4에서 구현을 하려면 NuSOAP을 사용하면 된다.
그리고 PHP5도 동일한 방법을 사용하면 되기 때문에 NuSOAP으로 하는것이 편하다.
nusoap-0.7.3.zip
nusoap-docs-0.7.3.zip
Mail_Mime-1.4.0.gz
세개의 파일이 필요한데
Mime은 NuSOAP 0.7.3에서 바이너리를 SOAP으로 보낼때 쓴다.
첨부된 nusoap.zip을 받고
htdocs폴더에다 lib에 풀고
반드시 endPoint를 설정해야 한다.
PHP5에만 SOAP이 내장되어 있다.
그러나 PHP4에서 구현을 하려면 NuSOAP을 사용하면 된다.
그리고 PHP5도 동일한 방법을 사용하면 되기 때문에 NuSOAP으로 하는것이 편하다.
nusoap-0.7.3.zip
nusoap-docs-0.7.3.zip
Mail_Mime-1.4.0.gz
세개의 파일이 필요한데
Mime은 NuSOAP 0.7.3에서 바이너리를 SOAP으로 보낼때 쓴다.
첨부된 nusoap.zip을 받고
htdocs폴더에다 lib에 풀고
// NuSOAP설정위와 같이 하면 함수를 호출할 수 있다.
include_once('lib/nusoap.php');
include_once('lib/nusoapmime.php');
// WSDL설정
$wsdl = 'http://url/WebService/Service?wsdl';
// NuSOAP설정
$client = new nusoap_client($wsdl, 'wsdl');
$client->setEndpoint("'http://url/WebService/Service");
반드시 endPoint를 설정해야 한다.
Subscribe to:
Posts (Atom)