새로나온 에디터인 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 실행파일 패스를 입력한다.
Friday, May 20, 2016
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등 여러가지 에디터를 변경하면서 생긴 문제이다. 항상 기존의 코드와인코딩이 맞는지를 항상 확인하자.
Wednesday, May 18, 2016
Node.js 최신버전 업데이트
sudo npm cache clean -f
sudo npm install -g n
sudo n stable
sudo npm update npm -g
sudo npm install -g n
sudo n stable
sudo npm update npm -g
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, May 5, 2016
Java 하위 폴더 모든 소스 컴파일 빌드
다음과 같이 build.sh를 만들면 src폴더 하위에 있는 모든 java파일을 컴파일 할수 있다.
java파일과 같은 폴더내에 class파일이 만들어진다.
cd src
javac -cp . -d . $(find . -name *.java)
java파일과 같은 폴더내에 class파일이 만들어진다.
cd src
javac -cp . -d . $(find . -name *.java)
Subscribe to:
Posts (Atom)
