728x90

PDO에서 NULL 값을 반환하는 것이 Legacy PHP 와 약간 달라서 주의가 필요해서 적어둔다.

 

<?php
class adminClass extends DBDataClass {
 
    function BldTypeNMFromID($codeID){
        $sql = "select codeNM from bldingTypeNM where codeID=?";
        $params = array($codeID);
        $stmt = $this->db->prepare($sql);
        $stmt->execute($params);
        if($row = $stmt->fetch()){
            return $row[0];
        }
    }
 
    function BldTypeIDFromNM($codeNM){
        if(strlen($codeNM< 1return 2// 값이 없으면, 2번 코드 반환
        $sql = "select codeID from bldingTypeNM where codeNM=?";
        $params = array($codeNM);
        $stmt = $this->db->prepare($sql);
        $stmt->execute($params);
        if($row = $stmt->fetch()){
            return $row[0];
        } else { // NULL 인 경우, 신규 추가 및 신규 추가한 코드 반환
            $this->putBldTypeIDFromNM($codeNM);
            return $this->maxBldTypeID();
        }
    }
 
    function putBldTypeIDFromNM($codeNM) {
        if($this->isBldTypeID($codeNM== 0){
            $sort = $this->maxBldTypeID();
            $sort = (int)$sort + 1;
            $sql = "INSERT INTO bldingTypeNM (codeID, codeNM, sort) VALUES (?,?,?)";
            $params = array($sort,$codeNM,$sort);
            $stmt = $this->db->prepare($sql);
            $stmt->execute($params);
        } 
 
    }
 
    function maxBldTypeID(){
        $sql = "select max(codeID) FROM bldingTypeNM";
        $stmt = $this->db->prepare($sql);
        $stmt->execute();
        if($row = $stmt->fetch()){
            return $row[0];
        }
    }
 
    function isBldTypeID($codeNM){ 
        $sql = "select count(*) FROM bldingTypeNM WHERE codeNM=?";
        $params = array($codeNM);
        $stmt = $this->db->prepare($sql);
        $stmt->execute($params);
        if($row = $stmt->fetch()){
            return $row[0];
        } else {
            return 0;
        }
    }
 
    function BldTypeMNArray(){
        $sql="SELECT * from bldingTypeNM order by sort ASC";
        $stmt = $this->db->prepare($sql);
        $stmt->execute();
        while($row = $stmt->fetch()){
            $charge[$row[0]]=$row[1];
        }
        return $charge;
    }
}
 
?>

 

테이블 구조

CREATE TABLE `bldingTypeNM` (
  `codeID` int(10UNSIGNED NOT NULL DEFAULT 0,
  `codeNM` varchar(40DEFAULT NULL,
  `sort` int(3NOT NULL DEFAULT 1
ENGINE=MyISAM DEFAULT CHARSET=utf8;
 
ALTER TABLE `bldingTypeNM`
  ADD PRIMARY KEY (`codeID`);
 

 

블로그 이미지

Link2Me

,
728x90

PHP 함수를 구현한 코드에 버그가 있다고는 생각도 못했다.

그런데 입력값이 공백인 경우와 입력값이 0인 경우 동일한 결과를 처리하고 있다는 걸 알고 깜짝 놀랐다.

 

<?php
ini_set("display_startup_errors"1);
ini_set("display_errors"1);
error_reporting(E_ALL);
 
$aaa = "";
$bbb = 0;
 
if(empty($aaa&& empty($bbb)){
    echo 'aaa, bbb 둘다 값없슴<br/>';
else {
    echo 'aaa : '.$aaa.', bbb : '.$bbb.'<br/>';
}
 
echo 'aaa : '.Filter($aaa).'<br/>';
echo 'bbb : '.Filter($bbb).'<br/>';
 
function Filter($data){
    if(empty(trim($data))) {
        if($data === 0return 0;
        return '';
    }
    // 이하 함수 내용은 생략
}
?>

 

if문에서 둘다 입력값이 없는 경우를 체크하기 위한 함수를 구현하고, 0이 입력된 값을 체크했는데 원하지 않는 결과가 나왔다.

그래서 Filter 함수에서 data가 정확하게 0 을 입력한 경우에는 0을 반환하도록 코드를 보완했다.

 

if($keyword) {

 

}

를 할때에도 값이 0이 들어오면 false 로 인식되어 실제 값을 인식하지 못하는 현상이 발생한다.

그러므로 if(strlen($keyword)<1) 로 길이를 체크하여 길이가 없는 경우를 입력 값이 없는 경우로 간주하도록 구현하여 오류 발생을 방지하는 것도 방법이다.

 

 

 

블로그 이미지

Link2Me

,
728x90

WebStorm 에서 수정한 소스를 실시간 미리보기 하기 위한 방법이다.

변경된 사항을 확인할때 F5(새로고침) 버튼 누름없이 자동으로 리프레쉬시키는  모듈을 설치하는 방법이라고 보면 된다.

 

Live Server 설치 방법

왼쪽 하단에 있는 버튼을 눌러서 Terminal 을 선택하거나 Alt + F12 키를 누른다.

 

 

이제 live-server 를 입력한다.

 

위와 같은 에러 메시지가 나오면서 제대로 동작되지 않는다.

 

Digital Sign이 되지 않은 PowerShell 스크립트를 실행하는 방법.
Windows – R 키를 눌러 실행을 연다.
powershell.exe -noexit -executionpolicy unrestricted

위와 같이 해주었는데도 불구하고 WebStorm 에서는 동작되지 않는다.

 

Set-ExecutionPolicy -Scope CurrentUser
unrestricted
를 해주고 live-server 를 입력해주면 된다.

 

8080 포트를 다른 곳에서 사용하고 있다고 자동으로 다른 포트를 자동할당하더라.

Web 브라우저 상에서는 WebStorm 에서 작성한 코드를 저장하면 자동으로 변경되는 걸 확인할 수 있어 매우 편리하다.

 

Live Server 종료시키는 방법

Ctrl + C 를 눌러주면 Live Server 모드에서 자동 해제된다.

 

블로그 이미지

Link2Me

,
728x90

ASCII Characters (Printable)

문자 Entity Name Entity Number Description
( )     Parenthesis(퍼렌서시스, 소괄호)
{ }     Brace(브레이스, 중괄호)
[ ]     Bracket(브래킷, 대괄호)
< >     Angle Bracket(앵글 브래킷, 꺽쇠괄호)
    &#32; Space (스페이스, 공백)
!   &#33; Exclamation mark (엑스클러메이션 마크, 느낌표)
"   &#34; Quotation mark (쿼테이션 마크, 쌍따옴표)
#   &#35; Number sign (넘버 사인, 샵)
$   &#36; Dollar sign
%   &#37; Percent sign
& &amp; &#38; Ampersand
'   &#39; Apostrophe
(   &#40; Opening/Left Parenthesis
)   &#41; Closing/Right Parenthesis
*   &#42; Asterisk (애스터리스크)
+   &#43; Plus sign
,   &#44; Comma (콤마)
-   &#45; Hyphen (하이픈)
.   &#46; Period (피리어드)
/   &#47; Slash (슬래쉬)
0   &#48; Digit 0
1   &#49; Digit 1
2   &#50; Digit 2
3   &#51; Digit 3
4   &#52; Digit 4
5   &#53; Digit 5
6   &#54; Digit 6
7   &#55; Digit 7
8   &#56; Digit 8
9   &#57; Digit 9
:   &#58; Colon (콜론)
;   &#59; Semicolon (세미콜론)
< &lt; &#60; Less-than
=   &#61; Equals sign
> &gt; &#62; Greater than
?   &#63; Question mark (쿼스쳔 마크)
@   &#64; At sign (앳 사인)
A   &#65; Uppercase A
B   &#66; Uppercase B
C   &#67; Uppercase C
D   &#68; Uppercase D
E   &#69; Uppercase E
F   &#70; Uppercase F
G   &#71; Uppercase G
H   &#72; Uppercase H
I   &#73; Uppercase I
J   &#74; Uppercase J
K   &#75; Uppercase K
L   &#76; Uppercase L
M   &#77; Uppercase M
N   &#78; Uppercase N
O   &#79; Uppercase O
P   &#80; Uppercase P
Q   &#81; Uppercase Q
R   &#82; Uppercase R
S   &#83; Uppercase S
T   &#84; Uppercase T
U   &#85; Uppercase U
V   &#86; Uppercase V
W   &#87; Uppercase W
X   &#88; Uppercase X
Y   &#89; Uppercase Y
Z   &#90; Uppercase Z
[   &#91; Opening/Left square bracket
\   &#92; Backslash (백슬래쉬)
]   &#93; Closing/Right square bracket
^   &#94; Caret (캐럿)
_   &#95; Underscore (언더스코어)
`   &#96; Grave accent (그레이드 액센트)
a   &#97; Lowercase a
b   &#98; Lowercase b
c   &#99; Lowercase c
d   &#100; Lowercase d
e   &#101; Lowercase e
f   &#102; Lowercase f
g   &#103; Lowercase g
h   &#104; Lowercase h
i   &#105; Lowercase i
j   &#106; Lowercase j
k   &#107; Lowercase k
l   &#108; Lowercase l
m   &#109; Lowercase m
n   &#110; Lowercase n
o   &#111; Lowercase o
p   &#112; Lowercase p
q   &#113; Lowercase q
r   &#114; Lowercase r
s   &#115; Lowercase s
t   &#116; Lowercase t
u   &#117; Lowercase u
v   &#118; Lowercase v
w   &#119; Lowercase w
x   &#120; Lowercase x
y   &#121; Lowercase y
z   &#122; Lowercase z
{   &#123; Opening/Left curly brace
|   &#124; Vertical bar (버티컬 바)
}   &#125; Closing/Right curly brace
~   &#126; Tilde (틸드)

 

'Web 프로그램 > PHP 문법' 카테고리의 다른 글

[PHP] PHP 문자열 찾기  (0) 2017.11.14
[PHP] 배열에만 동작하는 foreach 문  (0) 2017.01.26
PHP Class 개념 이해 ★★  (0) 2017.01.10
PHP isset 과 empty 설명  (1) 2016.04.27
PHP 대체 문법  (0) 2016.04.05
블로그 이미지

Link2Me

,
728x90

자바스크립트 Ajax 로 받은 결과에 문제가 발생한 경우 디버깅하려고 하면 애로사항이 생겨 어려움을 겪을 수 있다.

이를 해결할 방법으로 시도해 본 사항을 적어둔다.

POST 변수로 넘기는 변수가 30개 이상된다고 하고, 파일 B에서 변수를 받아서 체크하고 함수를 이용하여 결과를 도출하는 경우에 어디에서 에러가 발생했는지 찾기가 어려워서 아래 코드를 활용하여 해결했다.

 

$('#panel_content').load(link, function() {
 
    $('#checkdone-submit').on('click',function(e){
        e.preventDefault(); // a 링크, submit 실행 방지
        var params = $('#baseChkRegister').serialize();
        $.post('baseChkRst.php',params,function(msg){
            //alert(msg);
            console.log(msg);
            var uri = $('#urlPath').attr('url-path');
            if(msg == 1){
                alert('등록되었습니다.');
            } else if(msg == 2){
                alert('수정했습니다.');
            } else {
                alert('정보 변경에 실패했습니다.');
            }
        });
    });
 
});
 

 

위와 같이 ajax 결과로 문제 해결이 되면 Good 이지만 그렇지 못한 경우에는 baseChRst.php 파일에서 넘겨받은 POST변수를 직접 코드의 INPUT 을 기록하고 코드를 한줄 한줄 검증하는 것으로 해결해야 할 수도 있다.

 

baseChkRst.php 파일 예시

파일 A에서 파일 B(baseChrRst.php)로 값을 전송하여 var_dump($_POST) 로 출력하면 console.log 에서 확인할 수 있다.

확인한 결과를 $test 에 복사하여 붙여넣기 한 이후에 실제 파일 A에서 값을 넘겼다고 가정하고 파일 B에서 에러가 발생한 코드를 echo 문으로 검증하는 과정을 거치면 문제가 된 코드를 찾아낼 수 있다.

$_POST 로 넘기는 변수의 개수가 30개 이상인 경우라서 에러를 찾기 힘들어서 찾아서 해결한 방법이다.

<?php
ini_set("display_startup_errors"1);
ini_set("display_errors"1);
error_reporting(E_ALL);
 
// javascript console.log 로 찍어서 확인한 메시지가 아래와 같다.
// 이 메시지를 배열로 저장해서 값이 넘어온 것을 가지고 디버깅을 할 목적이다.
$test = 'array(4) {
  ["uid"]=>
  string(1) "0"
  ["userID"]=>
  string(7) "hgd1806"
  ["userNM"]=>
  string(9) "홍길동"
  ["memo"]=>
  string(13) "이상없슴."
}';
 
var_export(unvar_dump($test)); // 화면 출력으로 결과 확인시
 
$_POST = unvar_dump($test); // 실제 변수로 넘어온 데이터라고 가정하고 코드 검증
extract($_POST); // 변수명만 추출하여 데이터 검증처리시 사용
 
// 실제 하단에 사용할 코드는 생략
 
// var_dump($_POST) 로 결과를 받아서 console.log 메시지를 다시 배열로 만들어 주기 위한 함수
function unvar_dump($str) {
    if (strpos($str"\n"=== false) {
        //Add new lines:
        $regex = array(
            '#(\[.*?\]=>)#',
            '#(string\(|int\(|float\(|array\(|NULL|object\(|})#',
        );
        $str = preg_replace($regex"\n\1"$str);
        $str = trim($str);
    }
    $regex = array(
        '#^\040*NULL\040*$#m',
        '#^\s*array\((.*?)\)\s*{\s*$#m',
        '#^\s*string\((.*?)\)\s*(.*?)$#m',
        '#^\s*int\((.*?)\)\s*$#m',
        '#^\s*bool\(true\)\s*$#m',
        '#^\s*bool\(false\)\s*$#m',
        '#^\s*float\((.*?)\)\s*$#m',
        '#^\s*\[(\d+)\]\s*=>\s*$#m',
        '#\s*?\r?\n\s*#m',
    );
    $replace = array(
        'N',
        'a:\1:{',
        's:\1:\2',
        'i:\1',
        'b:1',
        'b:0',
        'd:\1',
        'i:\1',
        ';'
    );
    $serialized = preg_replace($regex$replace$str);
    $func = function($match) {
        return 's:'.strlen($match[1]).':"'.$match[1].'"';
    };
    $serialized = preg_replace_callback(
        '#\s*\["(.*?)"\]\s*=>#'
        $func,
        $serialized
    );
    $func = function($match) {
        return 'O:'.strlen($match[1]).':"'.$match[1].'":'.$match[2].':{';
    };
    $serialized = preg_replace_callback(
        '#object\((.*?)\).*?\((\d+)\)\s*{\s*;#'
        $func
        $serialized
    );
    $serialized = preg_replace(
        array('#};#''#{;#'), 
        array('}''{'), 
        $serialized
    );
 
    return unserialize($serialized);
}
?>
 

 

unvar_dump 함수 코드 출처 : https://stackoverflow.com/questions/3531857/convert-var-dump-of-array-back-to-array-variable

 

Convert var_dump of array back to array variable

I have never really thought about this until today, but after searching the web I didn't really find anything. Maybe I wasn't wording it right in the search. Given an array (of multiple dimensions...

stackoverflow.com

 

 

 

블로그 이미지

Link2Me

,
728x90

It is important to remember that create must be triggered on the parent container and not on the individual element that needs to be enhanced.

 

$('selector').trigger('선택할 이벤트');

// 트리거를 create로 변경해주면 된다.
$("타겟").append("추가할 html").trigger("create");

 

아래 예제는 http://jsbin.com/umatel/1/edit?html,js,output 를 참조하여 일부 헤더 정보 추가하고 테스트했다.

 

<!DOCTYPE html>
<html lang="en">
<head>
  <title>Bootstrap Trigger Example</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
  <link href="https://code.jquery.com/mobile/1.3.2/jquery.mobile-1.3.2.css" rel="stylesheet" type="text/css" />
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
  <script src="https://code.jquery.com/jquery-1.3.2.min.js"></script>
  <style>
    body {
      margin-top: 10px;
      margin-left: 10px;
    }
  </style>
</head>
<body>
  <div data-role="page" id="first">
    <button>Button element</button>  
  </div>
 
<script>
$("button").click(function() {
  $('<table data-role="table" id="movie-table" data-mode="reflow" class="ui-responsive table-stroke"><thead><tr><th data-priority="1">Rank</th><th data-priority="persist">Movie Title</th><th data-priority="2">Year</th><th data-priority="3"><abbr title="Rotten Tomato Rating">Rating</abbr></th><th data-priority="4">Reviews</th></tr></thead><tbody><tr><th>1</th><td><a href="http://en.wikipedia.org/wiki/Citizen_Kane" data-rel="external">Citizen Kane</a></td><td>1941</td><td>100%</td><td>74</td></tr><tr><th>2</th><td><a href="http://en.wikipedia.org/wiki/Casablanca_(film)" data-rel="external">Casablanca</a></td><td>1942</td><td>97%</td><td>64</td></tr><tr><th>3</th><td><a href="http://en.wikipedia.org/wiki/The_Godfather" data-rel="external">The Godfather</a></td><td>1972</td><td>97%</td><td>87</td></tr><tr><th>4</th><td><a href="http://en.wikipedia.org/wiki/Gone_with_the_Wind_(film)" data-rel="external">Gone with the Wind</a></td><td>1939</td><td>96%</td><td>87</td></tr><tr><th>5</th><td><a href="http://en.wikipedia.org/wiki/Lawrence_of_Arabia_(film)" data-rel="external">Lawrence of Arabia</a></td><td>1962</td><td>94%</td><td>87</td></tr></tbody></table>').appendTo("#first");
 
  $("#first").trigger("create");
});
</script>
</body>
</html>

 

$('<table data-role="table" id="movie-table" data-mode="reflow" class="ui-responsive table-stroke"><thead><tr><th data-priority="1">Rank</th><th data-priority="persist">Movie Title</th><th data-priority="2">Year</th><th data-priority="3"><abbr title="Rotten Tomato Rating">Rating</abbr></th><th data-priority="4">Reviews</th></tr></thead><tbody><tr><th>1</th><td><a href="http://en.wikipedia.org/wiki/Citizen_Kane" data-rel="external">Citizen Kane</a></td><td>1941</td><td>100%</td><td>74</td></tr><tr><th>2</th><td><a href="http://en.wikipedia.org/wiki/Casablanca_(film)" data-rel="external">Casablanca</a></td><td>1942</td><td>97%</td><td>64</td></tr><tr><th>3</th><td><a href="http://en.wikipedia.org/wiki/The_Godfather" data-rel="external">The Godfather</a></td><td>1972</td><td>97%</td><td>87</td></tr><tr><th>4</th><td><a href="http://en.wikipedia.org/wiki/Gone_with_the_Wind_(film)" data-rel="external">Gone with the Wind</a></td><td>1939</td><td>96%</td><td>87</td></tr><tr><th>5</th><td><a href="http://en.wikipedia.org/wiki/Lawrence_of_Arabia_(film)" data-rel="external">Lawrence of Arabia</a></td><td>1962</td><td>94%</td><td>87</td></tr></tbody></table>').appendTo("#first");

 

실행결과

 

클릭전

 

클릭후

블로그 이미지

Link2Me

,
728x90

// jQuery prototype
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script>
$.fn.changeColor = function(){
    $(this).css('color', "red");

    return this; // 생략 가능
};

</script>

<script>
$('#abc').changeColor();
</script>

 

jQuery Selector를 이용하는 메소드를 추가하려면 $.fn.메소드명 을 통해 추가한다.

this 키워드는 $("selector") 를 통해 들어온 jQuery Object를 의미한다.

chaining을 지원하기 위해 this를 return한다.

 

https://learn.jquery.com/plugins/basic-plugin-creation/ 를 참고하면 더 많은 내용을 확인할 수 있다.

 

 

<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
 <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
 <!-- jQuery prototype -->
 <script>
$.fn.changeColor = function(){
    $(this).css('color'"red");
};
 
$.fn.blueBorder = function(){
    this.each(function(){
        $(this).css("border","solid blue 1px");
    });
    return this;
};
$.fn.redText = function(){
    this.each(function(){
        $(this).css("color","red");
    });
    return this;
};
 
</script>
 
</head>
<body>
<div id="abc">
    글자색 변환
</div>
<br>
<input id="b" type="button" value="Apply" /><br />
<div class="blue">1</div>
<div class="blue">2</div>
<div class="blue">3</div>
 
<script>
$('#abc').changeColor();
 
$("#b").click(function(){
    $('.blue').blueBorder().redText();
});
</script>
 
</body>
</html>

 

 

VSCode 에서 HTML, Javascript 개발 환경 구축하여 테스트 해보는 방법

Code Runner 를 설치하고 나서 VSCode 우측 상단의 ▷ 를 누르면 하단 콘솔창에 실행결과가 나온다.

 

open in browser 를 설치하여 Web 브라우저 상에서 확인해보자.

VSCode 를 종료한 다음 다시 실행한 다음 VSCode 왼쪽 하단에 있는 설정 아이콘을 클릭한다.

검색창에서 open-in-browser.default 를 입력하고 chrome 이라고 입력해 준다.

 

아래와 같이 VSCode 창에서 ALT + B 를 누르면 크롬브라우저가 팝업되면서 결과가 화면에 출력된다.

블로그 이미지

Link2Me

,
728x90

PHP 와 Query를 이용하여 테이블의 칼럼을 누루면 해당 칼럼 순으로 정렬하는 기능을 구현하고 싶을 때가 있다.

핵심 기능에 필요한 것만 발췌하여 적어둔다.

<?php
ini_set("display_startup_errors"1);
ini_set("display_errors"1);
error_reporting(E_ALL);
 
$link_url = "MemberList.php"// 현재 실행중인 파일명 가져오기
 
$sort = isset($_GET['sortby']) ? $a->XSSFilter($_GET['sortby']): '';
$bidx = isset($_GET['bidx']) ? $a->XSSFilter($_GET['bidx']) :'';
switch($bidx){
    case 1:
        $xorderby"userNM ";
        $sortby = ($sort == "userNMDESC") ? "ASC" : "DESC";
        $xorderby.= $sortby;
        break;
    case 2:
        $xorderby"userID ";
        $sortby = ($sort == "userIDDESC") ? "ASC" : "DESC";
        $xorderby.= $sortby;
        break;
    default:
        $xorderby"idx DESC";
        $sortby = "DESC";
        break;
}
?>
 
<th scope="col" class="bldSort" data-bidx="1" style="cursor:pointer">성명</th>
<th scope="col" class="bldSort" data-bidx="2" style="cursor:pointer">아이디</th>
 
<div class='form-group'>
    <form name="ListForm" class="form-inline" action="<?php echo $link_url;?>">
        <input type="hidden" name="m" value="<?php echo $m;?>" />
        <input type="hidden" name="orderby" id="xorderby" value="<?php echo $xorderby;?>" />
        <!-- 일부 코드 생략 -->
</div>
<div id="urlPath" url-path="<?php echo $link_url;?>"></div>
 
<script>
$('.bldSort').click(function(e) {
    e.preventDefault();
    var bidx = $(this).attr('data-bidx');
    var uri = $('#urlPath').attr('url-path');
    var sort = document.getElementById('xorderby').value.replace(/(\s*)/g,"");
    MemberListTable(where,keyword,curPage,uri,bidx,sort);
});
</script>

 

 

블로그 이미지

Link2Me

,
728x90

AES256 암호화/복호화에 대한 예제이다.

Java 에서 AES256 암호화/복호화시에는 key를 16바이트 키를 사용해도 문제가 되지 않는다.

Java 에서 암호화 한 것을 PHP에서 복호화할 때에는 16바이트 키를 사용한 것은 엉뚱한 결과를 반환하더라.

key 길이가 다르면 PHP 복호화시 문제가 된다는 걸 잊지마시길 !!

 

Java 에서 암호화/복호화 하는 경우와 Android 에서 사용하는 경우 import 문이 달라서인지 코드가 약간 다르다.

 

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.AlgorithmParameterSpec;
import java.util.Base64;
 
public class AES256Cipher {
    private static String key = "testggisuitken1959imy91jb7076jas"// AES 암호화  키
//    private static String key = "cde0123456789abf"; // 16 바이트키
    public static byte[] ivBytes = { 0x000x000x000x000x000x000x000x000x000x000x000x000x000x000x000x00 };
 
    public static String AES_Encode(String str, String key)    throws UnsupportedEncodingException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
 
        byte[] textBytes = str.getBytes("UTF-8");
        AlgorithmParameterSpec ivSpec = new IvParameterSpec(ivBytes);
        SecretKeySpec newKey = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
        Cipher cipher = null;
        cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, newKey, ivSpec);
 
        Base64.Encoder encoder = Base64.getEncoder();
        return encoder.encodeToString(cipher.doFinal(textBytes));
    }
 
    public static String AES_Decode(String str, String key)    throws UnsupportedEncodingException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
 
        Base64.Decoder decoder = Base64.getDecoder();
        byte[] textBytes =decoder.decode(str);
        AlgorithmParameterSpec ivSpec = new IvParameterSpec(ivBytes);
        SecretKeySpec newKey = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, newKey, ivSpec);
        return new String(cipher.doFinal(textBytes), "UTF-8");
    }
 
    // 암호화
    public static String encrypt(String data) {
        try {
            data = AES_Encode(data, AES256Cipher.key);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (InvalidAlgorithmParameterException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        }
        return data;
    }
 
    // 복호화
    public static String decrypt(String data) {
        try {
            data = AES_Decode(data, AES256Cipher.key);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (InvalidAlgorithmParameterException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        }
        return data;
    }
}
 

 

 

PHP 코드

<?php
ini_set("display_startup_errors"1);
ini_set("display_errors"1);
error_reporting(E_ALL);
 
$key = "testggisuitken1959imy91jb7076jas";
//$key = "cde0123456789abf";
 
$encypted_text = "t7VJP1+3mcZlcJsh9nChPSUYOZSw+QIl2UFJlvkis8Y=";
$text = "암호화 예제";
 
echo '평문 : '.$text.'<br/>';
echo 'PHP 암호화  : '.AES_encrypt($text).'<br/>';
echo 'Java 암호문 : '.$encypted_text.'<br/>';
echo 'PHP  복호화 : '.AES_decrypt($encypted_text).'<br/>';
 
// AES 암호화
function AES_encrypt($plain_text){
    global $key;
    $encryptedMessage = openssl_encrypt($plain_text"aes-256-cbc"$keytrue,str_repeat(chr(0), 16));
    return base64_encode($encryptedMessage);
}
 
// AES 복호화
function AES_decrypt($base64_text){
    global $key;
    $decryptedMessage = openssl_decrypt(base64_decode($base64_text), "aes-256-cbc"$keytrue, str_repeat(chr(0), 16));
    return $decryptedMessage;
}
 
?>
 

 

Java 에서 암호화하고 PHP 에서 복호화하는 것 뿐만 아니라

PHP 에서 암호화하고 Java 에서 복호화하는 것도 문제없이 잘 된다.

 

블로그 이미지

Link2Me

,
728x90

논리 연산자를 효율적으로 사용하는 방법이라고 보면 된다.

 

console.log(true && "hello"); // 'hello'
console.log(null && undefined); // null
console.log(undefined && "hello"); // undefined
console.log("hello" && null); // null
console.log("hello" && "bye"); // bye
console.log(null && "hello"); // null
console.log(undefined && "hello"); // undefined
console.log('' && 'hello'); // ''
console.log(0 && 'hello'); // 0
console.log(1 && 'hello'); // hello
console.log(1 && 1); // 1

&& 연산자는 첫번째가 true 이면 뒤에 있는 hello 를 반환한다.

첫번째가 false 이면 첫번째를 반환한다.

 

&& 연산자로 코드 단축시키기

const seaFood = {
  name"쭈꾸미"
}
 
function getName(fish) {
  // && 논리 연산자가 truly 하면 fish.name 을 반환한다.
  return fish && fish.name
}
 
const name = getName(seaFood);
console.log(name); // '쭈꾸미'

fish 도 Truthy 하고 fish.name 또한 Truthy 하다면 오른쪽의 값을 return 한다.

 

|| 연산자로 코드 단축시키기

A || B 는 만약 A 가 Truthy 할경우 결과는 A 가 됩니다. 반면, A 가 Falsy 하다면 결과는 B 가 된다.

const seaFood = {
  name"박달대게"
};
 
function getName(fish) {
  // fish 가 Truthy 하면 왼쪽 값인 fish 를 return 
  // fish 가 Falsy 하면 오른쪽 값인 '이름없음' 을 return
  return fish || '이름없음'
}
 
const name = getName(seaFood)
console.log(name// {name : 박달대게}
 
const name2 = getName()
console.log(name2) // '이름없음'
 

 

 

블로그 이미지

Link2Me

,
728x90

프로그래밍 학습이나 교육에 활용하면 좋은 온라인 코드 에디터 CodeSnadbox 를 이용하는 방법이다.

 

https://codesandbox.io/ 에 접속한다.

JS를 선택한다.

 

 

 

 

 

 

 

 

 

로그인을 한 다음에 사용하면 된다.

 

https://learnjs.vlpt.us/basics/01-hello-javascript.html 에 좋은 강좌 내용이 있으니 참고하면 좋다.

 

function biggerThanThree(numbers) {
  /* 구현해보세요 */
  const arr = [];
  for (let i = 0; i < numbers.length; i++) {
    if (i < 3continue;
    arr.push(numbers[i]);
  }
  return arr;
}
 
const numbers = [1234567];
console.log(biggerThanThree(numbers)); // [4, 5, 6, 7]
 
export default biggerThanThree;
 
 

 

블로그 이미지

Link2Me

,
728x90
// 사업자 번호 체크
function BizNOChk(b1,b2,b3){
    // 사업자 등록번호는 000-00-00000 의 구조
    // 123 : 국세청과 세무서별 코드
    // 45 : 개인, 법인 구분
    // 6789 : 과세사업자나 면세사업자 또는 법인사업자별로 등록 또는 지정일자를 일련번호로 나타낸 것
    // 0 : 맨끝 자리 수는 전산시스템으로 오류를 검증하기 위해 부여되는 검증번호
    // bizID는 숫자만 10자리로 해서 문자열로 넘긴다. 
    var checkID = new Array(1371371351); 
    var tmpBizID, i, chkSum=0, c2, remander; 
    var bizID = b1+b2+b3; 
 
    if (trim(bizID)==""return false;
    for (i=0; i<=7; i++) chkSum += checkID[i] * bizID.charAt(i); 
    c2 = "0" + (checkID[8* bizID.charAt(8)); 
    c2 = c2.substring(c2.length - 2, c2.length); 
    chkSum += Math.floor(c2.charAt(0)) + Math.floor(c2.charAt(1)); 
    remander = (10 - (chkSum % 10)) % 10 ; 
 
    if (Math.floor(bizID.charAt(9)) == remander) 
        return true ; // OK! 
    else
        return false
}
 
 
// 법인번호 검사
function isRegNo(sRegNo) {
    var re = /-/g;
    sRegNo = sRegNo.replace('-','');
 
    if (sRegNo.length != 13){
        return false;
    }
 
    var arr_regno  = sRegNo.split("");
    var arr_wt   = new Array(1,2,1,2,1,2,1,2,1,2,1,2);
    var iSum_regno  = 0;
    var iCheck_digit = 0;
 
    for (i = 0; i < 12; i++){
        iSum_regno +=  eval(arr_regno[i]) * eval(arr_wt[i]);
    }
 
    iCheck_digit = 10 - (iSum_regno % 10);
 
    iCheck_digit = iCheck_digit % 10;
 
    if (iCheck_digit != arr_regno[12]){
        return false;
    }
    return true;
}
 
 
//주민등록번호 체크
//111111-1111118
function chkJumin(jumin) {
    if(jumin.match(/^\d{2}[0-1]\d[0-3]\d-[1-4]\d{6}$/== null) {
        return false;
    }
 
    var chk = 0;
    var i;
    var last_num = jumin.substring(1314);
    var chk_num = '234567-892345';
 
    for(i = 0; i < 13; i++) {
        if(jumin.charAt(i) != '-')
            chk += ( parseInt(chk_num.charAt(i)) * parseInt(jumin.charAt(i)) );
    }
 
    chk = (11 - (chk % 11)) % 10;
 
    if (chk != last_num) return false;
    return true;
}
 
 
// 숫자만 입력 체크
// 사용법 : <input type=text name=id onKeyPress="return IsNumChk()">
function IsNumChk(objWord) {
    var InputValue = objWord.value;
    for(var i=0; i<InputValue.length; i++) {
        if(isNaN(InputValue.charAt(i))) {
            window.alert("숫자만 입력하세요!");
            objWord.vlaue = "";
            for(var j=0; j < i; j++) {
                objWord.vale += InputValue.charAt(j);
            }
            return;
        }
    }
}
 
// 숫자만 입력
$(document).on("keyup""input:text[numberOnly]"function() {
    $(this).val($(this).val().replace(/[^0-9]/gi,"") );
});
 

 

 

블로그 이미지

Link2Me

,
728x90

맥북에서 node.js 설치하는 방법을 적어둔다.

 

https://nodejs.org/en/download/ 에서 pkg 버전을 열면 바로 설치 화면창이 나오고 계속 진행하면 설치된다.

 

설치하고 나서 터미널 창을 연다.

sudo npm install -g n

sudo npm cache clean -f

sudo n stable

 

javascript 실행 코드를 node.js 에서 실행하면 동작한다.

 

실행 화면

 

결과가 codesandbox 에서 만큼 정확하지 않아서 사용을 계속할지는 의문이 든다.

블로그 이미지

Link2Me

,
728x90

VSCode(Visual Studio Code)에서 자바 스크립트 코드를 작성하고 실행하는 방법을 테스트하고 적어둔다.

 

1. 윈도우용 node.js 설치 파일을 받아서 설치한다.

   https://nodejs.org/ko/download/ 에서 윈도우용 64비트 설치파일을 받아서 설치한다.

 

2. node.js 를 기본으로 설치한 다음에...

   콘솔창에서

   $node -v

   $npm -v

   최신버전 npm 설치는

   $npm install -g npm@latest  

 

 

자바스크립트 파일을 실행하려면 node 명령어 뒤에 파일명을 입력한다. 파일 확장자 .js는 생략할 수 있다.

 

 

VSCode 에서 직접 실행하기 위해서 Code Runner extension 을 설치하면 된다고 해서 설치하고 CTRL + ALT +  N 을 눌러서 실행하면 글자가 깨져보여서 ....

그냥 node.js 에서 실행하기로 했다.

 

VSCode 터미널 창에서 node 파일명.js 를 했더니 잘된다.

 

const a = 1;
if( a + 1 == 2){
    const a = 2;
    console.log('if문 안의 a 값은 ' + a);
}
console.log('if문 밖의 a 값은 ' + a); 

 

블로그 이미지

Link2Me

,
728x90

PHP 에서 특정 날짜를 구하는 예제이다.

<?php
ini_set("display_startup_errors", 1);
ini_set("display_errors", 1);
error_reporting(E_ALL);

$today = date("Y-m-d");
$end_date = date('Y-m-d', strtotime('-1 day'));

echo $today.'<br/>';
echo $end_date.'<br/>';

date("Y-m-d H:i:s", strtotime("-1 day")); // 어제 
date("Y-m-d H:i:s", strtotime("now")); // 현재 
date("Y-m-d H:i:s", strtotime("+1 day")); // 내일 
date("Y-m-d H:i:s", strtotime("+1 week")); // 일주일 후 
date("Y-m-d H:i:s", strtotime("-1 month")); // 한달 전 
date("Y-m-d H:i:s", strtotime("+1 month")); // 다음달 
date("Y-m-d H:i:s", strtotime("+1 week 2 days 3 hours 4 seconds")); // 1주 2일 3시간 4초 후 
date("Y-m-d H:i:s", strtotime("next Thursday")); // 다음주 목요일 
date("Y-m-d H:i:s", strtotime("last Monday")); // 지난 월요일

$date = "2021-04-01";
$today = date('Y-m-d', strtotime($date));
$end_date = date('Y-m-d', strtotime($date.' -1 day'));
$c_date =  date("Y-m-d H:i:s", strtotime($date. ' + 3 days'));

echo $today.'<br/>';
echo $end_date.'<br/>';
echo $c_date;
?>
블로그 이미지

Link2Me

,
728x90

PHP 3 Tier 환경에서 WAS 서버에서 원격 접속하는 클라이언트(Web Browser, APP)의 IP주소를 알아낼 목적으로 $_SERVER['REMOTE_ADDR'] 를 사용하면 맞을까?

사이트 접속한 사용자 IP주소를 알려주는 것인데 앞단의 Web 서버의 IP주소를 반환하고 있다면??

DB 테이블에 Web Server 의 IP주소를 기록하고 있더라.

 

구글링에서 찾은 이 함수를 사용하면 접속단말의 IP주소를 가져온다.

function getClientIP() {
	if (isset($_SERVER)) {
		if (isset($_SERVER["HTTP_X_FORWARDED_FOR"]))
			return $_SERVER["HTTP_X_FORWARDED_FOR"];

		if (isset($_SERVER["HTTP_CLIENT_IP"]))
			return $_SERVER["HTTP_CLIENT_IP"];

		return $_SERVER["REMOTE_ADDR"];
	}

	if (getenv('HTTP_X_FORWARDED_FOR'))
		return getenv('HTTP_X_FORWARDED_FOR');

	if (getenv('HTTP_CLIENT_IP'))
		return getenv('HTTP_CLIENT_IP');

	return getenv('REMOTE_ADDR');
}

참고로 알아두면 좋은 사항

$_SERVER['DOCUMENT_ROOT'] = 현재 사이트가 위치한 서버상의 위치 => /htdocs/

$_SERVER['HTTP_ACCEPT_ENCODING'] = 인코딩 방식 => gzip, deflate

$_SERVER['HTTP_ACCEPT_LANGUAGE'] = 언어 => ko

$_SERVER['HTTP_USER_AGENT'] = 사이트 접속한 사용자 환경 => Mozilla/5.0

$_SERVER['REMOTE_ADDR'] = 사이트 접속한 사용자 IP => xxx.xxx.xxx.xxx

$_SERVER['SCRIPT_FILENAME'] = 실행되고 있는 위치와 파일명 => htdocs/index.php

$_SERVER['SERVER_NAME'] = 사이트 도메인 => www.abc.com

$_SERVER['SERVER_PORT'] = 사이트가 사용하는 포트 => 80

$_SERVER['SERVER_SOFTWARE'] = 서버의 소프트웨어 환경 => Apache/2.4.6 (Unix) PHP/7.3.27 

$_SERVER['SERVER_PROTOCOL'] = 사용된 서버 프로토콜 => HTTP/1.1

$_SERVER['REQUEST_URI'] = 현재페이지의 주소에서 도메인 제외 =>  /index.php?user=???&name=???

$_SERVER['PHP_SELF'] = 현재페이지의 주소에서 도메인과 넘겨지는 값 제외 =/ index.php

'Web 프로그램 > Web Security' 카테고리의 다른 글

CentOS 7 서버 보안  (0) 2023.03.03
HTML Purifier 사용법 예시  (0) 2023.02.28
파일 다운로드 공격 방지  (0) 2019.07.05
파일 업로드 공격 방지  (0) 2019.06.21
Cross-Site Scripting (XSS) 방지  (0) 2019.06.20
블로그 이미지

Link2Me

,
728x90

통상적으로 쉽고 간단하게 하기 위해 positional placeholders 를 이용한 방법을 사용한다.

$sql = "UPDATE users SET name=?, surname=?, sex=? WHERE id=?";
$params = array($name, $surname, $sex, $id);
$stmt= $pdo->prepare($sql);
$stmt->execute($params);

 

UPDATE query with named placeholders

$data = array('name' => $name,'surname' => $surname,'sex' => $sex,'id' => $id);
$sql = "UPDATE users SET name=:name, surname=:surname, sex=:sex WHERE id=:id";
$stmt= $pdo->prepare($sql);
$stmt->execute($data);

 

 

비밀번호 변경하는 간단 예제이다.

<?php
$idx = 15;
$passwd = "new1234!"// 비밀번호
 
require_once 'path.php';// root 폴더를 기준으로 상대적인 경로 자동 구하기
require_once $g['path_config'].'config.php';
require_once $g['path_class'].'dbconnect.php';
require_once $g['path_class'].'loginClass.php';
$d = new LoginClass;
 
$hash = $d->hashSSHA($passwd);
$encrypted_pw = $hash['encrypted']; // encrypted password
$salt = $hash['salt']; // salt
 
$QKEY = "passwd=?,salt=?";
$params = array($encrypted_pw,$salt,$idx);
$d->getDbUpdate('members',$QKEY,$params,'idx=?');
 
echo '변경완료'
 
?>
 
<?php
class LoginClass {
    // 패스워드 해쉬함수 : 20자 SALT + SHA256 암호화
    function hashSSHA($password) {
        $salt = sha1(rand());
        $salt = substr($salt020);
        $encrypted = base64_encode(hash('sha256'$salt.$passwordtrue) . $salt);
        $hash = array("salt" => $salt"encrypted" => $encrypted);
        return $hash;
    }
 
    function getDbUpdate($table$set$params$where) {
        $sql = "update " . $table . " set " . $set . ($where ? ' where ' . $where : '');
        try {
            $this->db->beginTransaction();
            $stmt = $this->db->prepare($sql);
            $status = $stmt->execute($params);
            $this->db->commit();
            return 1;
        } catch (PDOException $pex) {
            $this->db->rollBack();
            echo "에러 : " . $pex->getMessage();
            return -1
        }
    }
}
?>
 

 

 

기본적인 Insert, Update, Delete, 검색에 대한 샘플이다.

 
<?php
    require_once('dbCon.php');
    $pdo = dbConnect();
    
    //입력처리
    if(isset($_POST['action']) && $_POST['action'== 'insert'){
        try{
            $pdo->beginTransaction();
            $sql = "INSERT INTO member (name, age, email) VALUES(:name, :age, :email)";
            $stmt = $pdo->prepare($sql);
            $stmt->bindValue(':name',$_POST['name'],PDO::PARAM_STR);
            $stmt->bindValue(':age',$_POST['age'],PDO::PARAM_INT);
            $stmt->bindValue(':email'$_POST['email'], PDO::PARAM_STR);
            $stmt->execute();
            $pdo->commit();
            print "데이터 입력 처리 하였습니다.<br/><br/>";
        } catch (PDOException $pex) {
            $pdo->rollBack();
            print "에러 : ".$pex->getMessage();
        }
    }
    
    //수정처리
    if(isset($_POST['action']) && $_POST['action']=='update'){
        //세션 변수를 이용하여 id값을 획득한다.
        $id = $_SESSION['id'];
        try{
            $pdo->beginTransaction();
            $sql = "UPDATE member SET name = :name, age=:age, email = :email WHERE id = :id";
            $stmt = $pdo->prepare($sql);
            $stmt->bindValue(':name'$_POST['name'], PDO::PARAM_STR);
            $stmt->bindValue(':age'$_POST['age'],PDO::PARAM_INT);
            $stmt->bindValue(':email'$_POST['email'], PDO::PARAM_STR);
            $stmt->bindValue(':id',$id,PDO::PARAM_INT);
            
            $stmt->execute();
            $pdo->commit();
            print "데이터를 수정 처리하였습니다.<br/>";
        } catch (PDOException $pex) {
            $pdo->rollBack();
            print "에러 : ".$pex->getMessage();
        }
        // 사용한 세션 변수를 삭제한다.
        unset($_SESSION['id']);
    }
    
    //삭제 처리
    if(isset($_GET['action']) && $_GET['action']=='delete' && $_GET['id'> 0){
        try{
            $pdo->beginTransaction();
            $id = $_GET['id'];
            $sql = "DELETE FROM member WHERE id = :id";
            $stmt = $pdo->prepare($sql);
            $stmt->bindValue(':id'$id, PDO::PARAM_INT);
            $stmt->execute();
            $pdo->commit();
            print "데이터를 삭제 처리하였습니다...<br/><br/>";
        } catch (PDOException $pex) {
            $pdo->rollBack();
            print "에러 : ".$pex->getMessage();
        }
    }
    
    //검색 처리
    try{
        if(isset($_POST['searchWord']) && $_POST['searchWord'!= ""){
            $searchWord = '%'.$_POST['searchWord'].'%';
            $sql = "SELECT * FROM member WHERE name LIKE :name";
            $stmt=$pdo->prepare($sql);
            $stmt->bindValue(':name',$searchWord,PDO::PARAM_STR);
 
            $stmt->execute();
        }else{
            //현재 DB에 있는 회원리스트를 모두 출력한다.
            $sql = "SELECT * FROM member";
            $stmt = $pdo->query($sql);
        }
        
        $cnt = $stmt->rowCount();
    }catch(PDOException $pex){
        print "에러 : ".$pex->getMessage();
    }    
    if($cnt < 1){
        print "검색 결과가 없습니다!!<br/>";
    }
?>

 

블로그 이미지

Link2Me

,
728x90

코드이그나이터 .htaccess 환경 설정 방법이다.



CodeIgniter 가 설치된 web root 폴더에서 .htaccess 파일을 생성한다.

vi .htaccess

RewriteEngine On
RewriteCond $1 !^(index\.php|assets|images|js|css|uploads|favicon.png)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]


:wq

로 저장하고 나온다.


Apache httpd.conf 파일에서


<Directory "/home/httpd/codeig/www/htdocs">
    AllowOverride all
    Require all granted
</Directory>

로 변경해준다.


https://codeig.abc.com/index.php/welcome

로 해서 동작되던 것을


https://codeig.abc.com/welcome

로 index.php 을 없애도 동작되도록 한다.


htdocs/application/config 폴더에서 config.php 파일 수정사항



블로그 이미지

Link2Me

,
728x90

https://newsapi.org/v2/top-headlines?country=kr&category=science&apiKey=a30a7298cf91404494ce049edc3d0e5a 에 있는 자료를 안드로이드에서 가져와서 Recyclerview 로 처리하는 걸 하고 싶은데 안된다는 내용이다.


안드로이드 앱에서는 아래와 같은 에러가 발생한다.


분명히 Web에서 직접 URL을 입력하면 결과를 출력하고 있다.

직접 API 를 신청하는 것도 해봤다.




해결하는 방법은 PHP CURL 을 이용하면 된다.

<?php
// PHP cURL 모듈은 다양한 종류의 프로토콜을 사용하여 서버와 통신할 수 있도록 도와주는 모듈로 외부 사이트의 정보를 취득할 수 있다.
// 서버에 PHP CURL 모듈이 설치되어 있어야 한다.
$url = "https://newsapi.org/v2/top-headlines?country=kr&category=science&apiKey=a30a7298cf91404494ce049edc3d0e5a";
// curl이 설치 되었는지 확인
if (function_exists('curl_init')) {
    
    $ch = curl_init(); // curl 리소스 초기화
    curl_setopt($ch, CURLOPT_URL, $url); // url 설정    
    curl_setopt($ch, CURLOPT_HEADER, 0); // 헤더는 제외하고 content 만 받음    
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // 응답 값을 브라우저에 표시하지 말고 값을 리턴

    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept: application/json', 'Content-Type: application/json'));
    curl_setopt($ch, CURLOPT_VERBOSE, true);

    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); //true로 설정시 일부 https 사이트는 안 열림
    curl_setopt($ch, CURLOPT_SSLVERSION,1); //ssl 셋팅

    $content = curl_exec($ch);    
    curl_close($ch); // 리소스 해제

    $R = json_decode($content,TRUE); // JSON to Array
    echo json_encode($R); // JSON

} else {
    // curl 라이브러리가 설치 되지 않음. 다른 방법 알아볼 것
    echo "This website not installed PHP's curl function.";
}
?>


서버에 올려진 이 URL 을 호출하면 원하는 News API 자료를 가져올 수 있다.

앱 출력 결과




블로그 이미지

Link2Me

,
728x90

테이블을 JQuery 로 다루는 걸 간략하게 작성해둔다.

보통은 row 단위로 테이블의 마우스 포인트를 처리하고, row 의 값만 추출한다.

만약, 특정한 셀을 눌렀을 때의 값을 추출하거나, 함수 처리를 하고 싶을 때가 있다.

이때에는 기준점이 td 이므로 td 에 클래스명을 부여시 서로 다르게 부여한다.

 

 

위와 같은 테이블의 PHP 소스코드가 아래와 같다고 가정하자.

 

<tr id="<?php echo $R['uid']; ?>">
    <td class="BoardView"><?php echo $no;?></td>
    <td class="BoardView"><?php echo $R['subject'];?></td>
    <td class="BoardView"><?php echo $R['writer'];?></td>
    <td class="Excelpdf"><?php echo $R['regdate'];?></td>
    <td class="BoardView"><?php echo $R['hit'];?></td>
</tr>

 

 

 

관련 jQuery 코드가 아래와 같이 처리한다.

테이블에서 계속 변경되는 테이블의 row 는 클래스로 부여하고, 현재 셀은 $(this) 이고, 상위의 값은 $(this).parent().attr('id') 로 부여한 요소값을 추출한다.

인접한 셀의 값을 가져오기 위해서 $(this).parent().find("td:eq(3)").text() 로 처리한다.

 

$('.BoardView').click(function() {
    var idx = $(this).parent().attr('id');
    var date = $(this).parent().find("td:eq(3)").text();
    uri = "excelpdf.php?do="+idx+"&date="+date;
    window.location.href = uri;
});

 

 

parents() 메소드 : 자신부터 document root 까지 검색을 하기 때문에 검색 결과가 1개 이상일 수 있다는 점
  문서의 root 요소부터 DOM Tree를 탐색하여 각 부모요소들로 임시 집합을 구성하고
  제공된 선택자에 의해 임시 집합에서 추출

closest() 메소드 : 선택된 요소의 최초의 부모 요소를 얻을 수 있다.
  현 시점의 요소에서 시작하여 DOM 트리의 마지막 부분까지 조회한다.
  없거나 하나의 요소를 포함한 jQuery 객체를 반환
  자기 자신부터 찾기 시작하여 부모 요소 탐색을 하다가 해당 아이템에서 탐색을 멈춤

 

var age = $(this).find('[name=age]').val();
// name으로 접근시 $("tag_name[name=name]") 
$("input[name=search_value]")

아래 3개는 모두 동일한 결과를 보여준다.

var idx = $('#FloorForm').find('[name=bidx]').val();
var idx = $('input[name=bidx]',document.FloorForm).val();
var idx = $(document.FloorForm).find('[name=bidx]').val();

<div class='form-group'>
	<form name="FloorForm" id="FloorForm" class="form-inline" action="<?php echo $link_url;?>">
		<input type="hidden" name="bidx" value="<?php echo $bidx;?>" />

		<div class="input-group mb-3">
			<select name="where" class="browser-default custom-select">
				<option value="floor">층</option>
				<option value="all">전체</option>
			</select>
		</div>
		<div class="input-group mb-3">
		  <input type="text" name="keyword" class="form-control" id="FloorSearchKeyword">
		  <div class="input-group-append">
			<button class="btn btn-outline-default" type="button" id="FloorSearch">검색</button>
			<button class="btn btn-outline-default" type="button" id="FloorHome">Home</button>
		  </div>
		</div>
	</form>
</div>

$('#FloorSearchKeyword').on('keypress', function(event){
	var agent = navigator.userAgent.toLowerCase();
	var keycode = (event.keyCode ? event.keyCode : event.which);
	if(keycode == 13){ // 엔터키가 입력될 때까지는 어떤 것도 하지 않는다.
		event.preventDefault(); // 엔터키가 입력되면 현재 이벤트의 기본 동작을 중단한다.
		//event.stopPropagation(); // 현재 이벤트가 상위로 전파되지 않도록 중단한다.
		var where = $('#FloorForm').find('[name=where]').val();
		var keyword = $('#FloorForm').find('[name=keyword]').val();
		FloorSearch(where,keyword);
	}
});

$('#FloorSearch').click(function(e){
	var where = $('#FloorForm').find('[name=where]').val();
	var keyword = $('#FloorForm').find('[name=keyword]').val();
	FloorSearch(where,keyword);
});

function FloorSearch(where,keyword){
	var uri = $('#urlPath').attr('url-path');
	var idx = $('#FloorForm').find('[name=bidx]').val();

	keyword= keyword.replace(/\s/g,""); // 문자열내의 모든 공백 제거
	var regExp = /[\{\}\[\]\/?.,;:|\)*~`!^\-_+<>@\#$%&\\\=\(\'\"]/gi; // 특수문자 제거
	keyword = keyword.replace(regExp,"");
	if(keyword.length == 0){
		alert('검색어를 입력하세요');
		$('input[name=keyword]').focus();
		return false;
	}
	MemberListTable(where,keyword,1,uri,idx);
}

라디오버튼의 value 가져오기
$("#FloorForm").find("[name=chk_confirm]:checked").val();

 

select박스
* 선택된값 가져오기 : $("#FloorForm>[name=cate]>option:selected").val() );
* 값 선택하기 :  $("#FloorForm").find("[name=cate]>option@[value=BLOG]").attr('selected','true');

 

<form id="frm" name="frm">
   <input type="text" name="price" value="100" />
   <input type="text" name="price" value="200" />
   <input type="text" name="price" value="300" />
   <input type="text" name="price" value="400" />
</form>

var Price = $("#frm input[name='price']").eq(2).val();
블로그 이미지

Link2Me

,