MySQL DB와의 연동하여 통계 그래프를 작성하는 방법이다.

바로 앞 게시물(http://link2me.tistory.com/1132)과 비교해서 달라진 부분이 어떤 것인지만 비교해보면 된다.

색깔을 표시한 부분을 주의깊게 살펴보면 답은 의외로 간단하다.


<?php
//require_once 'connect.php'; // db접속 성공
//require_once 'phpclass/boardClass.php'; // 게시판 클래스
$line1 ="4,6,2,5";  // DB와 연동한 결과로 문자열을 생성했다고 가정한다.
?>
<!DOCTYPE html>
<head>
<meta charset=UTF-8" />
<meta name="robots" content="noindex,nofollow"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no"/>
<meta http-equiv="X-UA Compatible" control="IE=edge,chrome=1" />
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<!-- http://www.jqplot.com 제공 자바스크립트 include -->
<script type="text/javascript" src="./plugin/jqplot/jquery.jqplot.js"></script>
<script type="text/javascript" src="./plugin/jqplot/plugins/jqplot.barRenderer.js"></script>
<script type="text/javascript" src="./plugin/jqplot/plugins/jqplot.pointLabels.js"></script>
<script type="text/javascript" src="./plugin/jqplot/plugins/jqplot.categoryAxisRenderer.js"></script>
<link rel="stylesheet" type="text/css" href="./plugin/jqplot/jquery.jqplot.css" />
<script type="text/javascript">
$(document).ready(function(){
    var line1 = [<?php echo $line1;?>];
    var line2 = [10, 8, 22, 15, 10];
    var ticks = ['닛산', '포르쉐', 'KIA', '현대', '벤츠'];
 
    $('#chart1').jqplot([line1,line2], {
        title:'막대그래프 예제',
        seriesDefaults:{
            renderer:$.jqplot.BarRenderer, // 막대 그래프
            rendererOptions: { barWidth: 25 }, // bar의 너비 수동으로 설정
            pointLabels: { show: true, formatString: '%d' } // 레이블 값
        },
        axes:{
            xaxis:{
                renderer: $.jqplot.CategoryAxisRenderer,
                ticks: ticks // X축 값
            }
        }
    });
});
</script>

</head>
<body>
<div id="chart1" style="height:300px;width:600px; "></div>
</body>
</html>


다음 기회에 월을 선택하면 일별 막대그래프를 자동으로 그려주는 통계에 대한 PHP코드를 작성해볼 생각이다.

로직은 년월에 대한 값을 DB에서 자동으로 선택해서 selectbox에 표시하고 선택한 년월 정보로 통계그래프가 표시되도록 하면 된다.

- DB에서 년월에 대한 값을 중복없이 뽑아낸다.

- 년월을 선택하면 마지막 일자의 값을 자동으로 추출해서 문자열을 생성한다.

- jQuery change 로 해당 값이 변동되면 그래프를 그리도록 한다.

728x90
블로그 이미지

Link2Me

,

시각적으로 통계 결과를 화면에 보여주는 걸 구현할 때 jqplot 플러그인을 이용하면 쉽게 챠트를 그릴 수 있다.


위와 같은 막대 그래프로 통계 결과를 보여주고자 한다면 어떻게 해야 할까?


1. http://www.jqplot.com 사이트에서 플러그인 파일을 다운로드하여 서버에 설치한다.

   현재 기준 최신버전은 jquery.jqplot.1.0.9.d96a669.zip 이다.

   이 사이트를 알게 된 것은 2년전에 전문 개발자를 통해 알았는데 jQuery를 배우니 쉽게 활용이 가능하다.


2. 다운로드한 파일에 usage.txt 파일에 사용법이 나온다.

    그리고 웹사이트 Examples 에도 다양한 형태의 예제 파일이 있다.

    하지만 설명이 잘 이해되지 않을 수도 있다.


3. 간략하게 예제를 살펴보자.

    예제는 DB와의 연동까지는 고려하지 않은 1단계라고 보면 된다.

    필요한 플러그인 js 파일이 있는 경로명을 제대로 표시해주어야 그래프가 그려진다.

    - 변수 line1 과 line2 두개를 표시하고자 할 경우이며, 1개만 표시하고 싶으면 line1 만 적어준다.

    - 변수 ticks 는 X 좌표에 해당되는 값을 표시

    - title : 상단 제목


<!DOCTYPE html>
<head>
<meta charset=UTF-8" />
<meta name="robots" content="noindex,nofollow"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no"/>
<meta http-equiv="X-UA Compatible" control="IE=edge,chrome=1" />
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<!-- http://www.jqplot.com 제공 자바스크립트 include -->
<script type="text/javascript" src="./plugin/jqplot/jquery.jqplot.js"></script>
<script type="text/javascript" src="./plugin/jqplot/plugins/jqplot.barRenderer.js"></script>
<script type="text/javascript" src="./plugin/jqplot/plugins/jqplot.pointLabels.js"></script>
<script type="text/javascript" src="./plugin/jqplot/plugins/jqplot.categoryAxisRenderer.js"></script>
<link rel="stylesheet" type="text/css" href="./plugin/jqplot/jquery.jqplot.css" />
<script type="text/javascript">
$(document).ready(function(){
    var line1 = [4, 6, 2, 5];
    var line2 = [10, 8, 22, 15, 10];
    var ticks = ['닛산', '포르쉐', 'KIA', '현대', '벤츠'];
 
    $('#chart1').jqplot([line1,line2], {
        title:'막대그래프 예제',
        seriesDefaults:{
            renderer:$.jqplot.BarRenderer,
            rendererOptions: { barWidth: 25 },
            pointLabels: { show: true, formatString: '%d' }
        },
        axes:{
            xaxis:{
                renderer: $.jqplot.CategoryAxisRenderer,
                ticks: ticks
            }
        }
    });
});
</script>

</head>
<body>
<div id="chart1" style="height:300px;width:600px; "></div>
</body>
</html>


보는 바와 같이 코드는 정말 심플하다.


변수 값을 PHP 와 연동하여 처리하는 것은 다음에 기술할 예정이다.

통계 그래프에 직접 변수를 지정해주는 경우는 거의 없을 것이고, DB와 연동하여 실시간처리가 되도록 해야 의미가 있을 것이다.


설명이 잘된 사이트가 있어서 링크를 걸어둔다.

http://wickedmagic.tistory.com/525


jqplot.com 사이트에서 영문으로 된 자료를 가지고 약간만 테스트를 하면서 본인이 원하는 스타일로 구현하면 된다. 그리고 좀 더 세부적인 내용을 알고자 한다면 구글에서 jqplot bar width example 와 같은 검색어를 입력하면 원하는 자료를 쉽게 찾을 수 있다.

http://www.jqplot.com/docs/files/plugins/jqplot-barRenderer-js.html 에도 옵션에 대한 설명이 나온다.

728x90
블로그 이미지

Link2Me

,

MP3 Player jQuery 화면 만들기 예제를 적어둔다.

실제 사용은 안하고 있으나, 화면 생성에 대한 사항을 사용할 일이 있을때 참고하려고 적어둔다.

좋은 MP3 플레이어 jQuery 는 http://www.wimpyplayer.com/ 다.


<div id="mp3playerdiv"></div>
<!--플레이어-->
<div class="player">
<div class="player_bg"><!--tmp--></div>
<div class="player_area" id="tubeplayer"></div>
</div>
<!--플레이어-->

<script type="text/javascript">
//<![CDATA[
   //플레이어
   $('.simbol a').click(function(e) {
   e.preventDefault();
   $(".player").fadeIn();
  
     $("#tubeplayer").append('<iframe width="400" height="80" src="<?php echo $g['dir_module_skin']?>movie/demo/movie.php?file='+this.id+'" frameborder="0" scrolling="no" allowfullscreen></iframe>');
  
      var temp = $('.player_area');
   
       if (temp.outerHeight() < $(document).height() ) temp.css('margin-top', '-'+temp.outerHeight()/2+'px');
       else temp.css('top', '0px');
       if (temp.outerWidth() < $(document).width() ) temp.css('margin-left', '-'+temp.outerWidth()/2+'px');
       else temp.css('left', '0px');

      $(".player .player_bg").on("click", function() {
      $(".player").fadeOut();
      $("#tubeplayer iframe").remove();
    });
           
      //키보드 esc
      $(document).bind('keydown', function(e) {
        if (e.which == 27) {
        $(".player").fadeOut();
        $("#tubeplayer iframe").remove();
        }
      });

    });
    //플레이어

//]]>
</script>

728x90
블로그 이미지

Link2Me

,

PHP를 배울 때 가장 먼저 알아야 할 사항이 디버깅 요령인데 독학으로 배워 게시글 기록을 보면 순서없이 중구난방이다.

최근에서야 디버깅을 이렇게 하면 도움이 되겠다 싶은 걸 적어본다.

 

변수지정 기초지식 : http://link2me.tistory.com/523 참조

 

파일 A에서 파일 B로 데이터를 넘길 때 파일 B에서 확인하는 방법이다. (의미를 모르면 http://link2me.tistory.com/1110 부터 읽어라)

 

파일A에서 form 으로 넘긴 변수(method="post")가 제대로 잘 넘어오는지 확인하는 방법

- 파일 A란?  PHP Form, Android, C# 등 값을 POST (또는 GET) 방식으로 넘기는 코드를 의미함.

 

<?php
var_dump($_POST); // var_dump 또는 print_r 둘 중에 하나를 선택해서 확인하라.

echo '<pre>';print_r($_POST);echo '</pre>';

출처: https://link2me.tistory.com/1130 [소소한 일상 및 업무TIP 다루기]

echo '<pre>';print_r($_POST);echo '</pre>'; // 가독성이 좋게 하려면 print_r 과 pre 태그를 사용하면 된다.

exit; // 이 명령어 다음에 적힌 코드들은 실행하지 말고 빠져나가라.

       // 변수가 넘어오는지 테스트 목적이므로 아래 코드 실행 방지 목적
?>

로 하면 배열로 넘어온 값을 확인할 수 있다.

print_r() : 변수 정보를 알기 쉬운 형식으로 출력한다.

var_dump() : 기본적으로 print_r()함수와 같지만 데이터 유형 등 출력되는 정보가 많다.

var_export() : 그대로 PHP 스크립트로서 해석할 수 있는 형식으로 출력한다.

 

직접 테스트해 보고자 한다면 로그인 폼 전송예제 http://link2me.tistory.com/1479 에서 파일을 받으면 된다.

 

코드 작성시 체크 포인트

<?php
// 에러 메시지를 찾고자 할 때 추가할 코드 (개발 시에는 반드시 아래 3줄을 추가해서 하라)

ini_set("display_startup_errors", 1);
ini_set("display_errors", 1);
error_reporting(E_ALL);

// 운용 모드에서는

// error_reporting(0); // 모든 오류를 표시하지 않는다.
if(isset($_POST) && $_SERVER['REQUEST_METHOD'] == "POST"){ // 반드시 이 한줄을 넣어라.

    // 보안에 안전하려면
    // POST 방식으로 보낸 데이터가 있는지 체크
    echo '<pre>';print_r($_POST);echo '</pre>';
}

?>



<?php
// 보안을 고려한 코드 작성시 (보통은 php.ini 에 해당항목을 수정한다)

ini_set('error_reporting', E_ALL | E_STRICT);
ini_set('display_startup_errors', 'Off');
ini_set('display_errors', 'Off');

ini_set('log_errors', 'On');
?>
Notice: Undefined index: 라고 경고메시지가 뜨는 것이 싫을 경우에는

코드 상단에 error_reporting(E_ALL ^ E_NOTICE); 를 추가해주면 된다.
error_reporting(0); // 모든 오류를 표시하지 않는다. (운용환경에서는 이걸 사용하라)

하지만 개발을 할 때에는 경고 메시지도 모두 출력되도록 하여 에러를 완전히 잡는 것이 중요하다.
 //페이지 변수 설정
$page = isset($_GET['page'])? trim($_GET['page']) : 1;
파일 B에서 코드 구현시 파일 A에서 값이 넘어오지 않을 때에도 동작되도록 코드를 구현해야 할 경우가 있다.
이런 상황에서 삼항연산자로 간단하게 했더니 경고 메시지가 출력된다.
Notice: Undefined variable:

$ym=$_GET['ym'] ? $_GET['ym'] : date("Ym"); //현재 년월
 
이걸 정확하게
if(isset($_GET['ym'])){
    $ym = $_GET['ym'];
} else {
    $ym = date("Ym");
}
로 수정해줘야 경고메시지가 없어진다는 걸 확인했다.

 
결국 isset 으로 변수 설정 유무 검사를 추가해야만 경고 메시지가 없어진다.

$ym=isset($_GET['ym']) ? $_GET['ym'] : date("Ym"); //현재 년월
잘 만들어진 빌더를 분석하다보면 isset 처리를 하지 않아 경고메시지가 출력되는 걸 종종 발견하게 된다.

기존 코드를 유지보수 하다가 수정한 것이 있어서 http://link2me.tistory.com/1085 에 적어둔게 있다.

 

경고메시지를 php.ini 파일을 수정해서 나오지 않도록 하는 방법을 알아보자.

error_reporting 키워드를 검색어로 찾아서 아래와 같이 수정한다.

 

error_reporting = E_ALL & ~E_DEPRECATED & ~E_NOTICE
- E_DEPRECATED : 향후 PHP 버전에서 동작을 하지 않을 수도 있는 코드에 대해서 로그를 발생 시킨다
- E_NOTICE : 초기화 되지 않은 변수를 사용했을 때 에러 로그를 생성한다.

 

php.ini 파일을 수정했으면 아파치를 재시작하면 변경한 내용으로 적용된다.

php.ini 에 추가하면 에러 버그를 못잡을 수도 있으니 해당 파일 상단에 아래와 같이 처리하는 걸 권장한다.

 

완벽하게 코드를 만드는 습관을 들이는게 중요하다.
사소한 것을 하나씩 무시하다보면 중요한 곳에서 버그가 생길 수 있다.

mysqli_query 에 에러가 발생할 경우 아래와 같이 원인을 찾을 수 있게 코딩하는 것도 좋다.

 

<?php
$sql = "SQL statement here";
$result = mysqli_query($dbconn,$sql) or trigger_error("SQL: $sql - Error: ".mysqli_error(), E_USER_ERROR);
?>

 

SQL 문이 정상적으로 잘 생성되었는지 여부를 확인할 수 있게 echo 문으로 출력해보는 것도 필요하다.

결국 PHP구문을 통해서 생성한 SQL 문이 DB에 저장되도록 하는 것이기 때문이다.

echo $sql; 로 생성된 SQL 구문을 직접 DB에 넣었을 때 에러없이 잘 들어가면 SQL문은 에러가 없다는 뜻이다.

SQL문에서 에러가 생기는 경우도 종종있다. 문법이 잘못되었거나, 오타가 있거나 등등...

//DB데이터 ARRAY -> 테이블에 출력할 데이터 배열
function getDbArray($table,$where,$flddata,$orderby,$rowsPage,$curPage){
    $sql = 'select '.$flddata.' from '.$table.($where?' where '.$this->getSqlFilter($where):'').($orderby?' order by '.$orderby:'').($rowsPage?' limit '.(($curPage-1)*$rowsPage).', '.$rowsPage:'');
    echo $sql; // SQL 문이 정상적으로 실행되는지 여부 파악 목적
    if($result = mysqli_query($this->db,$sql)){
        return $result;
    }
}
 

echo $sql; 출력으로 웹 브라우저 화면상에서 나온 SQL 문을 직접 DB에서 쿼리해보는 것이 가장 좋은 해결 방법이다.

link2me.tistory.com/1917 은 phpMyAdmin 인데 phpMyAdmin 은 잘 다루면 엄청 편리하고, 보안을 신경써야 한다.

 

 

MySQLi 절치지향 방식으로 만든 함수를 PDO 함수로 컨버팅하면서 함수 이상 유무를 확인하는 과정에서 아래와 같이 테스트를 했다.

함수의 결과가 배열일 수도 있고 그냥 String 일 수도 있어서 in_array 함수를 이용하여 배열과 문자열을 구분하여 출력하도록 하면 원하는 결과를 깔끔하게 확인할 수 있다.

 <?php
require_once 'path.php';
require_once $g['path_class'].'dbconnect.php';
require_once $g['path_class'].'adminClass.php';
$a = new adminClass;

$codeID = 4;
$rs = $a->StaffPositionMNCount($codeID);
if(is_array($rst)){
    echo '<pre>';print_r($rs);echo '</pre>';
} else {
    echo $rs;
}
?>

 

 

ajax, jQuery 등을 사용하는 경우 메시지 분석이 어려울 때가 있다.

그래서 echo '<script type="text/javascript">alert("'.$errline.'");</script>'; 로 에러를 확인하지만 문제는 복사가 안된다.

 

echo '<script type="text/javascript">window.prompt("메세지를 복사해주세요", "'.$sql.'");</script>';

로 하면 메시지 복사가 가능해진다.

대부분 에러가 발생하는 원인을 찾으려면 SQL 문을 직접 DB에 입력해보면 에러 메시지가 뭔지 쉽게 확인할 수 있다.

 

 

이제 파일 B 코드 구현 사항이 문제가 없는지 확인하는 방법이다.

즉, Android 와 통신하는데 PHP 코드에는 문제가 없는지 확인하는 방법이라고 봐도 된다.

아래 코드는 로그인 처리하는 파일 B(a.loginChk.php) 코드 예제이다.

초보자의 코드라면 loginClass.php 없이

보통은 여기에서

$sql = "select * from tableName where 조건";

$result=mysqli_query($db,$sql);

$row=mysqli_fetch_array($result);

와 같은 처리를 하는데, 이걸 loginClass Class에 함수로 만들어서 모아둔 것이라고 보면 된다.

 

== 정상적인 코드
<?php
// 파일을 직접 실행하는 비정상적 동작을 방지 하기 위한 목적
if(isset($_POST) && $_SERVER['REQUEST_METHOD'] == "POST"){
    @extract($_POST); // $_POST['loginID'] 라고 쓰지 않고, $loginID 라고 써도 인식되게 함
    if(isset($userID) && !empty($userID) && isset($password) && !empty($password)) {
        include_once 'dbController.php';
        require_once 'loginClass.php';
        $c = new LoginClass();
        $user = $c->getUser($userID, $password);
        if ($user != false) {
            $_SESSION['userID'] = $user['userID'];
            $_SESSION['userNM'] = $user['userNM'];
            $_SESSION['admin'] = $user['admin'];
            echo json_encode(array('result' => '1'));
        } else {
            echo json_encode(array('result' => '0'));
        }
    }else {// 입력받은 데이터에 문제가 있을 경우
        echo json_encode(array('result' => '-2'));
    }
} else { // 비정상적인 접속인 경우
    echo 0; // a.loginChk.php 파일을 직접 실행할 경우에는 화면에 0을 찍어준다.
    exit;
}
?>
== 디버깅 코드
<?php
//if(isset($_POST) && $_SERVER['REQUEST_METHOD'] == "POST"){
    @extract($_POST); // $_POST['loginID'] 라고 쓰지 않고, $loginID 라고 써도 인식되게 함
    // $_POST 변수로 넘어온 값이 라고 가정하고 변수에 값을 직접 넣어서 결과가 정상 반환되는지 확인한다.
    $userID = "jsk005";
    $password = "abc1234";
    if(isset($userID) && !empty($userID) && isset($password) && !empty($password)) {
        include_once 'dbController.php';
        require_once 'loginClass.php';
        $c = new LoginClass();
        $user = $c->getUser($userID, $password);
        if ($user != false) {
            $_SESSION['userID'] = $user['userID'];
            $_SESSION['userNM'] = $user['userNM'];
            $_SESSION['admin'] = $user['admin'];
            echo json_encode(array('result' => '1'));
        } else {
            echo json_encode(array('result' => '0'));
        }
    }else {// 입력받은 데이터에 문제가 있을 경우
        echo json_encode(array('result' => '-2'));
    }
/*
} else { // 비정상적인 접속인 경우
    echo 0; // a.loginChk.php 파일을 직접 실행할 경우에는 화면에 0을 찍어준다.
    exit;
}
*/
?>

 

변수가 많을 때에는 직접 변수를 넘겨서 var_dump 로 출력시키고 console.log 로 출력된 메시지를 복사해서 처리하는 방법이 유용할 수 있다.

참조 : https://link2me.tistory.com/2070

 

도움이 되셨다면 00 클릭해 주세요.

728x90
블로그 이미지

Link2Me

,

자바스크립트의 변수를 PHP 에서 읽을 수 있는 방법

"<script>document.write(p1);</script>"; 를 사용하면 된다.

자바스크립트는 별다른 표시가 없으면 윗줄에서 아래줄로 순차적으로 해석한다.


<script>
var p1 = "success";
</script>

<?php
echo "<script>document.write(p1);</script>";
?>

배열도 1차원으로 나열하더라.

   육안(화면)으로 보이는 것과 웹브라우저 소스보기로 보는 거랑은 결과가 다를 수 있음을 확인해야 한다.


PHP 변수 값을 자바스크립트/jQuery 로 전달하는 방법

전제조건 : 자바스크립트는 순차적으로 읽어들이므로 PHP 코드가 자바스크립트보다 위에 나와야 한다.

<script>
var str = '<?php echo $str;?>';
</script>


※ 자바스크립트에서 PHP 로 변수 넘기기 알아야 할 사항

    - 위에서부터 순차적으로 실행되는 구조하에서 javascript 변수를 PHP에서 읽어내는 것은 가능하다.
      하지만 자바스크립트 함수내에서 PHP 변수로 넘기는 것은 안된다.

    - 자바스크립트에서 결과값으로 얻은 변수를 PHP 다른 파일로 넘기는 것은 ajax를 사용하면 된다.

      하지만, ajax 결과를 다시 PHP 변수로 넘긴다?? 안된다는 걸 명심하자.

      ajax 결과를 가지고 클라이언트 HTML 파일을 업데이트할 수는 있다.

   

내가 제대로 이해 못할 수도 있으니 https://opentutorials.org/module/532/6508 게시글 참조하면 도움 될 수도....



PHP 배열 변수를 자바스크립트 배열로 전달하는 방법

JSON(JavaScript Object Notation)은 인터넷에서 자료를 주고 받을 때 그 자료를 표현하는 방법이다.

자료의 종류에 큰 제한은 없으며, 특히 컴퓨터 프로그램의 변수값을 표현하는 데 가장 적합하다.
왜냐하면 JSON은 문자열 뿐만 아니라 배열(Array), 오브젝트(Object) 등 컴퓨터의 모든 변수 형태를 문자열로 표현할 수 있기 때문이다.
JSON에서 표현할 수 있는 데이터 형식으로는 다음과 같은 것들이 있다.
- String (문자열): 큰 따옴표로 묶어 표현, ex) "link2me"
- Number (숫자): 숫자 표현, ex) 1234
- Array (배열): 대괄호로 묶어 표현, ex) [ 'a', 'b', 'c' ]
- Object (객체): 중괄호로 묶어 표현, ex) { key:'value',key2:'value2' }
- Boolean (참/거짓): TRUE 또는 FALSE, ex) true, false
- Null

json_encode 함수를 사용하면 1차원 배열이든 2차원 배열이든 간단하게 자바스크립트 배열로 만들어 준다.
json 은 UTF-8 로 인코딩되어야 인식된다는 걸 명심하자.

파일 Encoding 이 ANSI 로 되어 있으면 결과값이 출력되지 않는다.


<?php

$_POST = array('1','2','3');

echo json_encode($_POST, JSON_FORCE_OBJECT);

?>

<SCRIPT type="text/javascript">

var aa = <?php echo json_encode($_POST);?>;
alert(aa.subject);
// 연관배열에서 key로 값을 찾아준다. 한글도 잘 인식되더라.
</SCRIPT>


<script type='text/javascript'>
<?php
$php_array = array('aaa','bbb','ccc');
$js_array = json_encode($php_array);
echo "var javascript_array = ". $js_array . ";\n";
?>
</script>


다른 방법은 PHP 배열(1차원)을 문자열로 변환한 다음에 new Array()에 넣으면 1차원 배열은 해결된다.

단순한 값들의 나열이라면 배열 타입으로도 충분하다.

<?php

$_POST = array('1','2','3');

?>

<SCRIPT type="text/javascript">
var aa = new Array("<?=implode("\",\"" , $_POST);?>"); // 배열의 값만 문자열로 저장
</SCRIPT>



String to Array

string(문자열)을 구분자로 구분하여 배열로 저장하여 값을 출력
<?php

$flddata ="uid,ItemName,Price,Quantity";
$data = array();
$data = explode(",", $flddata); // 문자열을 배열로 저장

for($i=0; $i < count($data); $i++) {
      echo $data[$i].'<br />';
}
?>


Array to String

배열(array)을 구분자로 구분하여 문자열(string)로 저장

<?php
$arr = array('Hello','World!','Beautiful','Day!');
echo implode(" ",$arr); // 배열을 문자열로 저장
?>



Array 출력

checkbox 에서 선택한 값을 배열로 담아서 ajax 로 넘길 경우 코드와 PHP 파일을 값을 받아서 처리하는 과정이다.

배열을 분리하여 값을 추출하고자 할 경우에 foreach 문을 사용하면 된다.

$('.chkbox:checked').each(function()  // chkbox 라는 클래스명을 준 경우

$('input:checkbox[name="uid[]"]:checked').each(function()  // inputbox name 을 직접 준 경우


$('.btnbox1').click(function(){
    var chkdata = new Array();
    $("input:checked").each(function() {
        chkdata.push($(this).val());
    });
    if(chkdata.length != 0){
        alert(chkdata);
        $.post('ajax.php',{data:chkdata}, function(response) {
            //alert(response);
        });
    } else {
        alert('선택한 항목이 없습니다.');
    }
});


<?php
if(isset($_POST['data'])){
    foreach($_POST['data'] as $column => $value) {
        echo $value;

        // $value 를 가지고 MySQL DB Delete 수행하는 로직 처리

    }
}
?>



728x90
블로그 이미지

Link2Me

,

테이블에서 체크박스를 전체 선택/해제 그리고 체크박스 선택된 것만 특정 액션을 취하도록 하고 싶은 경우가 있다.

이걸 고려한 HTML5 및 JQuery 를 작성해봤다.

프로그램은 테스트를 통해서 몸으로 느끼고 내것으로 만들어야만 하는 작업이라는 걸 계속 체험하고 있다.



전체선택 박스 만들기

<th class="header" width="30"><input type="checkbox" id="checkall" /></th>



선택삭제 박스 만들기

<td colspan="5" style="text-align:left;"><span class="btnbox1">선택삭제</span></td>


.btnbox1 {
    background-color:#BFD7E9;
    border: none;
    padding: 10px 10px;
    text-align: center;
    text-decoration: none;
    display: inline-block;
    font-size: 12px;
    margin: 4px 2px;
    cursor: pointer;
    }


체크 박스 나오게하는 테이블 만들기

=== boardClass.php 파일의 일부 ===

// column 개수, 게시물 총개수 만큼 자동으로 화면 출력
function tablelistView_checkbox($result){
    global $DB_CONNECT;
    if(is_object($DB_CONNECT)  && get_class($DB_CONNECT)=='mysqli'){
        while($row = mysqli_fetch_array($result, MYSQLI_ASSOC)) {
            $view='<tr class="tr1">';
            foreach($row as $column => $value) {
                if($column== 'uid'){
                    $view.='<td><input type="checkbox" class="chkbox" name="uid[]" value="'.$value.'" /></td>';
                }
                $view.='<td class="td2">'.$value.'</td>';
            }
            $view.='</tr>';
            echo $view;
        }
    } else {
        while($row = mysql_fetch_array($result, MYSQL_ASSOC)) {
            $view='<tr class="tr1">';
            foreach($row as $column => $value) {
                if($column== 'uid'){
                    $view.='<td><input type="checkbox" class="chkbox" name="uid[]" value="'.$value.'" /></td>';
                }
                $view.='<td class="td2">'.$value.'</td>';
            }
            $view.='</tr>';
            echo $view;
        }
    }
}


==== display.js ====

$(function(){
    // class td1 중에서 짝수번째 요소만 선택해서 배경색을 지정색으로 표시
    $(".tr1:odd").css("background-color","#F4F9FF");

    $('.tr1').click(function() {
        var idx=$(this).attr('id');
    }).mouseover(function() {
        $(this).children('.td2').css({'backgroundColor':'#DCDCDC','cursor':'pointer'});
    }).mouseout(function() {
        $(this).children('.td2').css({'backgroundColor':'#FFFFFF','cursor':'default'});
    });

    // 전체 선택, 전체 해제
    $("#checkall").change(function () {
        $("input:checkbox").prop('checked', $(this).prop("checked"));
    });

    $('.btnbox1').click(function(){
        var chkdata = new Array();
        // 헤더에 있는 체크박스는 제외
        //$('.chkbox:checked').each(function() {
        $('input:checkbox[name="uid[]"]:checked').each(function() {
            chkdata.push($(this).val());
            //alert($(this).val());
        });
        if(chkdata.length != 0){
            alert(chkdata);
            $.post('ajax.php',{chkdata:chkdata}, function(response) {
                alert(response);
            });
        } else {
            alert('선택한 항목이 없습니다.');
        }
    });

});


==== ajax.PHP ===

값이 POST 방식으로 전달되는 것만 알 수 있게 연습한 파일이다.

실제로는 MySQL DB와 연동하여 수행처리하는 로직을 만들면 된다.


<?php
if(isset($_POST['chkdata'])){
    /*
    foreach($_POST['chkdata'] as $column => $value) {
        echo $value;
        // MySQL 함수와 연동하여 DB Delete 수행 처리
    }
    */
    $response = implode(" , ",$_POST['chkdata']); // 배열을 문자열로 저장
    echo $response;

    if($response) {

       $sql = "delete from tablename where uid in (".$response.")";

        mysqli_query($dbconn,$sql);

    }

}
?>


=== 테이블을 출력하는 파일 전체 ===

http://link2me.tistory.com/1127 와 비교하여 달라진 부분이 뭔지 보면 알 것이다.


<?php
require_once 'dbconnect.php'; // db접속 성공
require_once 'phpclass/dbClass.php';
require_once 'phpclass/boardClass.php';

$c = new MySQLiDbClass();

$link_url = $_SERVER['PHP_SELF']; // 현재 실행중인 파일명 가져오기
$rowsPage = 12;

// 화면에 출력할 칼럼 발췌

$flddata ="uid,ItemName,Price,Quantity";
$where ="";
$curPage = isset($_GET['p']) ? $_GET['p'] : 1;
$result = $c->getDbArray('items',$where,$flddata,'',$rowsPage,$curPage);
$totalcnt = $c->getDbRows('items',$where);

$d = new boardClass();
?>
<!DOCTYPE html>
<head>
<meta charset=UTF-8" />
<meta name="robots" content="noindex,nofollow"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no"/>
<meta http-equiv="X-UA Compatible" control="IE=edge,chrome=1" />
<link rel="stylesheet" type="text/css" href="../css/table.css" />
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<script type="text/javascript" src="../js/display.js"></script>
</head>
<body>
<div class="container">
    <table class="table" width="800">
        <thead>
            <tr>
                <th class="header" width="30"><input type="checkbox" id="checkall" /></th>
                <th class="header" width="100">No</th>
                <th class="header" width="250">아이템</th>
                <th class="header" width="250">가격</th>
                <th class="header" width="200">수량</th>
            </tr>
        </thead>
        <?php
            // 테이블 리스트
            $d->tablelistView_checkbox($result);
        ?>
        <td colspan="5" style="text-align:left;"><span class="btnbox1">선택삭제</span></td>
    </table>
</div>
<?php $d->PageLinkView($link_url,$totalcnt,$rowsPage,$curPage);?>
</body>
</html>

728x90
블로그 이미지

Link2Me

,

HTML5 기반으로 MySQL 과 연동하여 테이블을 구성하는 것 연습삼아 작성해봤다.

테이블은 Csharp 연동시 샘플 테이블을 가지고 작성했다.

AutoSet9 은 MySQLi 방식으로 연동된다.

dbconnect.php 파일을 통해서 MySQLi DB와 연동하고 dbClass.php 파일을 연결하여 dbClass 함수를 호출하여 코드를 간결하게 작성했으며, 게시판 Class(boardClass) 에서 만든 코드를 이용하여 실제 코드는 몇줄 안되는 것처럼 보인다.


<?php
require_once 'dbconnect.php'; // db접속 성공
require_once 'phpclass/dbClass.php';
require_once 'phpclass/boardClass.php';

$c = new MySQLiDbClass();

$link_url = $_SERVER['PHP_SELF']; // 현재 실행중인 파일명 가져오기
$rowsPage = 12;


// 화면에 출력할 칼럼 발췌

$flddata ="uid,ItemName,Price,Quantity";
$where ="";
$curPage = isset($_GET['p']) ? $_GET['p'] : 1;
$result = $c->getDbArray('items',$where,$flddata,'',$rowsPage,$curPage);
$totalcnt = $c->getDbRows('items',$where);

$d = new boardClass();
?>
<!DOCTYPE html>
<head>
<meta charset=UTF-8" />
<meta name="robots" content="noindex,nofollow"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no"/>
<meta http-equiv="X-UA Compatible" control="IE=edge,chrome=1" />
<link rel="stylesheet" type="text/css" href="../css/table.css" />
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<script type="text/javascript" src="../js/display.js"></script>
</head>
<body>
<div class="container">
    <table class="table" width="800">
        <thead>
            <tr>
                <th class="header" width="100">No</th>
                <th class="header" width="250">아이템</th>
                <th class="header" width="250">가격</th>
                <th class="header" width="200">수량</th>
            </tr>
        </thead>
        <?php
            // 테이블 리스트
            $d->tablelistView($result);
        ?>
    </table>
</div>
<?php $d->PageLinkView($link_url,$totalcnt,$rowsPage,$curPage);?>
</body>
</html>


아래 코드는 위의 HTML 파일과 연관된 내용을 작성한다.


=== dbinfo.php ===

<?php
$db['host'] = "localhost";
$db['name'] = "csharp";
$db['user'] = "root";  // 원래는 root 사용자를 사용하면 안되는데 연습용인지라...
$db['pass'] = "autoset";
$db['port'] = "3306";
?>


=== dbconnect.php ===

<?php
include_once 'phpclass/dbinfo.php';
$DB_CONNECT = isConnectDb($db);

function isConnectDb($db)
{
    $conn = mysqli_connect($db['host'],$db['user'],$db['pass'],$db['name'],$db['port']);
    mysqli_set_charset($conn, "utf8");  // DB설정이 잘못되어 euc-kr 로 되어 있으면 문제가 됨
    if (mysqli_connect_errno()) {
        echo "Failed to connect to MySQL: " . mysqli_connect_error();
        exit;
    } else {
        return $conn;   
    }
}
?>


=== dbClass.php ===

이 파일은 일부만 발췌하여 적는다.

본 코드에 사용된 함수는 http://link2me.tistory.com/1110 게시글에 올린 첨부파일을 받으면 된다.


class MySQLiDbClass {


    //DB데이터 ARRAY -> 테이블에 출력할 데이터 배열
    function getDbArray($table,$where,$flddata,$orderby,$rowsPage,$curPage){
        global $DB_CONNECT;
        $sql = 'select '.$flddata.' from '.$table.($where?' where '.$this->getSqlFilter($where):'').($orderby?' order by '.$orderby:'').($rowsPage?' limit '.(($curPage-1)*$rowsPage).', '.$rowsPage:'');
        if($result = mysqli_query($DB_CONNECT,$sql)){
            return $result;
        }
    }

    //DB데이터 레코드 총 개수
    function getDbRows($table,$where){
        global $DB_CONNECT;
        $sql = 'select count(*) from '.$table.($where?' where '.$this->getSqlFilter($where):'');
        if($result = mysqli_query($DB_CONNECT,$sql)){
            $rows = mysqli_fetch_row($result);
            return $rows[0] ? $rows[0] : 0;
        }
    }


    //SQL필터링
    function getSqlFilter($sql)
    {
        return $sql;
    }

}


=== boardClass.php ===

테이블 리스트를 보여주는 함수는 MySQL 접속인지, MySQLi 접속인지 자동으로 판단하는 함수 로직을 구현하여 코드의 확장성을 고려했다.

게시판에 주로 사용되는 사항을 함수화하여 코드를 간략화하였으나, 개발자 취향에 따라 코드를 함수화해서 사용하든 전부 나열식으로 코딩하든 개발자의 몫이다.

아울러 페이지 링크 부분은 세심하게 테스트까지 마친 코드이다.


class boardClass {

    // column 개수, 게시물 총개수 만큼 자동으로 화면 출력
    function tablelistView($result){
        global $DB_CONNECT;
        if(is_object($DB_CONNECT)  && get_class($DB_CONNECT)=='mysqli'){
            while($row = mysqli_fetch_array($result, MYSQLI_ASSOC)) {
                $view='<tr class="tr1">';
                foreach($row as $column => $value) {
                    $view.='<td class="td2">'.$value.'</td>';
                }
                $view.='</tr>';
                echo $view;
            }
        } else {
            while($row = mysql_fetch_array($result, MYSQL_ASSOC)) {
                $view='<tr class="tr1">';
                foreach($row as $column => $value) {
                    $view.='<td class="td2">'.$value.'</td>';
                }
                $view.='</tr>';
                echo $view;
            }
        }
    }

    function PageLinkView($link_url,$totalcnt,$rowsPage,$curPage){
        echo '<div style="position:relative;vertical-align:top;padding-top:0;margin-top:0">';
            echo "<span style='position:absolute;top:10px;'>[총 자료수:".$totalcnt."]</span>";
            echo '<div class="pagelink">';
                $Info = $this->PageList($totalcnt,$rowsPage,$curPage,'');
                if($Info['current_block'] > 2){
                    echo "<a href='".$link_url."?p=1'>◀</a> ";
                }
                if($Info['current_block'] > 1){
                    echo "<a href='".$link_url."?p=".$Info['prev']."'>◁</a> ";
                }
                foreach($Info['current'] as $w) {
                    if($curPage == $w){
                        echo "<a href='".$link_url."?p=".$w."'><span style='color:red;font-size:22pt'>".$w."</span></a> ";
                    } else {
                        echo "<a href='".$link_url."?p=".$w."'>".$w."</a> ";
                    }
                }
                if($Info['current_block'] < ($Info['total_block'])){
                    echo "<a href='".$link_url."?p=".$Info['next']."'>▷</a> ";
                }
                if($Info['current_block'] < ($Info['total_block']-1)){
                    echo "<a href='".$link_url."?p=".$Info['totalPage']."'>▶</a> ";
                }
            echo '</div>';
        echo '</div>';
    }


    // $curPage : 현재 페이지, $totalcnt : 총 게시물수
    // $block_limit : 한 화면에 뿌려질 게시글 개수
    function PageList($totalcnt,$rowsPage,$curPage,$block_limit) {
        $block_limit = $block_limit ? $block_limit : 10;  // 한 화면에 보여줄 개수 기본 10으로 설정

        // 총 페이지수 구하기
        $totalPage = ceil($totalcnt/$rowsPage); 
        if($totalPage == 0) {
            ++$totalPage;
        }
        $total_block = ceil($totalPage / $block_limit); //전체 블록 갯수
       
        $curPage = $curPage ? $curPage : 1; // 현재 페이지

        // 현재 블럭 : 화면에 표시될 페이지 리스트
        $current_block=ceil($curPage/$block_limit);
        // 현재 블럭에서 시작페이지
        $fstPage = (((ceil($curPage/$block_limit)-1)*$block_limit)+1);
        // 현재 블럭에서 마지막 페이지
        $endPage = $fstPage + $block_limit -1;
        if($totalPage < $endPage) {
            $endPage = $totalPage;
        }

        // 시작 바로 전 페이지
        $prev_page = $fstPage - 1;
        // 마지막 다음 페이지
        $next_page = $endPage + 1;

        foreach(range($fstPage, $endPage) as $val) {
            $row[] = $val;
        }
        // 배열로 결과를 돌려준다.
        return array(
            'total_block' => $total_block,
            'current_block' => $current_block,
            'totalPage' => $totalPage,
            'fstPage' => $fstPage,
            'endPage' => $endPage,
            'prev' => $prev_page,
            'next' => $next_page,
            'current' => $row
        );
    }

}

728x90
블로그 이미지

Link2Me

,

년도와 월을 선택하면 해당월의 마지막 날짜가 자동으로 변경되는 jQuery 를 작성했다.


PHP 와 jQuery 값을 전달하는 방법을 잘 몰라 고생 좀 했다.


jQuery Ajax 를 이용해서 파일 A 에서 전달한 값을 가지고 파일 B(get_LastDay.php)에서 결과를 계산하고 그 결과를 받아서 다시 파일 A에 PHP 변수로는 전달할 수가 없더라. (방법이 있는데 못찾은 것인지는 모름)


년도는 선택하지 않고 월만 선택하는 것도 고려하다보니, 자바스크립트 함수를 사용하지 않고 Ajax 로 전달해서 PHP 함수식을 이용하여 계산된 결과를 받도록 처리했다.


function getLastDay(year, month){
    if(month==4 || month==6 || month==9 || month==11)
        return 30;
    else if(month==2){ //2월
        if(year%4 == 0) // 2월, 윤년일 때
            return 29;
        else    // 2월, 윤년이 아닐 때
            return 28
    } else {
        return 31;
    }
}


Ajax 로 전달받은 결과는 HTML 을 갱신할 수는 있다.

이 방법을 이용해서 코드를 작성했다.


참고로, 년도와 월을 모두 선택한다면 Ajax 사용하지 않고 위 함수를 이용하여 처리해도 된다.

var year = $("#year option:selected").val();
var month = $("#month option:selected").val();
var lastDate = getLastDay(year, month);

$("#day > option").remove(); // remove all items from list
for(i=1; i<=lastDate; i++){
    $("#day").append("<option value='"+ i +"'>"+ i +"</option>");
}


=== 파일 A ===

<?php
date_default_timezone_set('Asia/Seoul');
$YEAR_LAST = date("Y");
$cur_year = $YEAR_LAST;
$cur_month = date("m");
// 현재 월의 마지막 날짜를 일단 선택하도록 처리하고, 년/월을 선택하면 자동으로 변경
$last_day = date("t", mktime(0, 0, 1, $cur_month, 1, $cur_year));
?>

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
$(document).ready(function(){ // html 문서를 다 읽어들인 후
    var year;
    var month;
    $('#year').on('change', function(){
        if($("#year option:selected").val() !== ""){
            year = $(this).find(":selected").val();
            month = $("#month option:selected").val();
            if($("#month option:selected").val() !== ""){
                $.post('get_LastDay.php',{year:year,month:month}, function(data) {
                    //alert(data);
                    $("#day > option").remove(); // remove all items from list
                    for(i=1; i<=data; i++){
                        $("#day").append("<option value='"+ i +"'>"+ i +"</option>");
                    }
                });
            }
        }
    });


    $('#month').on('change', function(){
        if($("#month option:selected").val() !== ""){
            year = $("#year option:selected").val();
            month = $(this).find(":selected").val();
            $.post('get_LastDay.php',{year:year,month:month}, function(data) {
                $("#day > option").remove(); // remove all items from list
                for(i=1; i<=data; i++){
                    $("#day").append("<option value='"+ i +"'>"+ i +"</option>");
                }
            });
        }
    });

});
</script>
<body>
<label>년도: </label>
<select id="year">
    <option value=''>년도</option>
    <?php for($i=2010; $i <= $YEAR_LAST; $i++){
        echo("<option value='$i'>$i 년</option>");
        } ?>
</select>

<select id="month">
<option value=''> 월 </option>
<?php for($i=1; $i <= 12; $i++){
    echo("<option value='$i'>$i</option>");
    } ?>
</select>

<select id="day">
<option value=''> 일 </option>
<?php for($i=1; $i <= $last_day; $i++){
    echo("<option value='$i'>$i</option>");
    } ?>
</select>

</body>
</html>


=== 파일 B : get_LastDay.php ===

<?php
$select_year = $_POST['year'];
$select_month = $_POST['month'];

$month_day = Array(31,29,31,30,31,30,31,31,30,31,30,31);

if(isset($select_year) && !empty($select_year) && isset($select_month) && !empty($select_month) ){
    // "t"는 두 번째 인자로 넘어온 해당 연,월에 대한 총 일수를 구하기 위한 파라미터
    $last_day = date("t", mktime(0, 0, 1, $select_month, 1, $select_year));
} else if(isset($select_month) && !empty($select_month)) {
    // 월만 선택한 경우에는 2월의 최대값이 28일지, 29일지 알 수 없으므로 최대 29를 선택하도록 처리
    $last_day = $month_day[$select_month-1];
}
echo $last_day;
?>



728x90
블로그 이미지

Link2Me

,

select 박스를 선택한 값을 jQuery 로 해서 Ajax 로 전송한 결과값을 다시 받은 코드를 구현해봤다.

이 코드를 보면 Ajax 로 값을 어떻게 전달하고, 결과를 다시 어떻게 받은지 알 수 있다.

ajaxPHP.php 파일에서 ehco 의 결과값을 받는다는 걸 알면 응용하는 것은 쉽다.

form 으로 넘기지 않아도 데이터를 전달하고 결과를 받을 수 있다는 걸 알 수 있다.


=== selected html ===

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
$(document).ready(function(){ // html 문서를 다 읽어들인 후
    $('#selectID').on('change', function(){
        if(this.value !== ""){
            var optVal = $(this).find(":selected").val();
            //alert(optVal);
            $.post('ajaxPHP.php',{optVal:optVal}, function(data) {
                alert(data);  // data는 ajaxPHP.php 파일에서 ehco 문의 결과 값             
            });

        }
    });
});
</script>
<body>
<label>select option: </label>
<select id="selectID">
    <option value="">구분</option>
    <option value="1">Option 1</option>
    <option value="2">Option 2</option>
    <option value="3">Option 3</option>
    <option value="4">Option 4</option>
</select>
</body>
</html>


=== ajaxPHP.php ===

<?php
$ajax = $_REQUEST['optVal'];
if($ajax == 1) {
    echo '첫번째';
} else if($ajax == 2) {
    echo '두번째';
} else if($ajax == 3) {
    echo '세번째';
} else if($ajax == 4) {
    echo '네번째';
}
?>


테스트 해보고 싶으신 분은 코드를 복사해서 테스트 해보세요. 100% 동작되는 코드입니다.


728x90
블로그 이미지

Link2Me

,

select 박스에서 선택한 값을 읽어오는 jQuery 코드 예제다.

selected 된 값을 표현하는 방법은 아래 3가지 모두 가능하다.

this.value;
$("#selectID option:selected").val();

$(this).find(":selected").val();


라디오버튼에서 선택할 경우

$(this).find(":checked").val();


=== 샘플 ===

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
$(document).ready(function(){ // html 문서를 다 읽어들인 후
    $('#selectID').on('change', function(){
        if(this.value !== ""){
            //var optVal = $("#selectID option:selected").val();
            var optVal = $(this).find(":selected").val();
            alert(optVal);
        }
    });
});
</script>
<body>
<label>select option: </label>
<select id="selectID">
    <option value="">구분</option>
    <option value="1">Option 1</option>
    <option value="2">Option 2</option>
    <option value="3">Option 3</option>
    <option value="4">Option 4</option>
</select>
</body>
</html>

728x90
블로그 이미지

Link2Me

,

일일 통계 생성을 위한 테이블 구조 및 테이블에 데이터를 저장하기 위한 코드를 작성했다.

가장 간단하게 userID 별 접속횟수, 날짜별 접속횟수만 기록되게 구현했다.


테이블 구조

CREATE TABLE IF NOT EXISTS Access_Stats (
  uid int(11) NOT NULL AUTO_INCREMENT,
  date char(8) NOT NULL,
  YM char(6) NOT NULL,
  day char(2) NOT NULL,
  IDCnt int(11) NOT NULL DEFAULT '0',
  dailyCnt int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (uid),
  KEY date (date)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;


=== 일일단위 통계 생성을 위한 코드 ===

<?php
require_once "dbconnect.php";
require_once "phpclass/statsClass.php";
$a=new statsClass();

// 일일 통계 기록
date_default_timezone_set('Asia/Seoul');
$date = date("Ymd", mktime(0,0,0,date("m"), date("d")-1, date("Y"))); // 어제
$YM = substr($date,0,6);
$day = substr($date,6,2);

if($a->Access_Stats($date) == '0'){ // 해당 날짜에 기록된 정보가 없으면
    $sql = "INSERT INTO Access_Stats (date,YM,day,IDCnt,dailyCnt) (select ".$date.",".$YM.",".$day.",count(distinct LogID),sum(hit) from AccessLog where date='".$date."')";
    @mysql_query($sql);
} else {
    $row = $a->AccessLogCnt($date); // 배열로 가져옴
    $sql = "Update Access_Stats SET IDCnt='".$row[0]."',dailyCnt='".$row[1]."' where date='".$date."'";
    @mysql_query($sql);
}

echo "Work done";
exit;
?>


=== statsClass.php ===

<?php
class statsClass {

    function Access_Stats($date){
        global $db;
        $sql ="select count(date) from Access_Stats where date='".$date."'"; // 기록된 데이터 있는지 조회
        $result=mysql_query($sql);
        if($row=mysql_fetch_row($result)){
            return $row[0];
        }
    }

    function AccessLogCnt($date){
        global $db;
        $sql ="select count(distinct userID),sum(hit) from AccessLog where date='".$date."'";
        $result=mysql_query($sql);
        if($row=mysql_fetch_row($result)){
            return $row; // 배열을 반환
        }
    }

}
?>


매일 일정한 시간에 테이블에 데이터를 자동으로 저장하기 위해서는 crontab 을 이용해야 한다.

crontab 을 이용하기 위한 코드는 아래와 같이 하면 된다.

=== accessLog.php ===

!#/usr/local/php/bin/php -q
<?php
// cron 방식 DB 접속
require_once "/usr/local/apache/htdocs/dbconnect.php";
require_once "/usr/local/apache/htdocs/phpclass/statsClass.php";
$a=new statsClass();

// 일일 통계 기록
date_default_timezone_set('Asia/Seoul');
$date = date("Ymd", mktime(0,0,0,date("m"), date("d")-1, date("Y"))); // 어제
$YM = substr($date,0,6);
$day = substr($date,6,2);
if($a->Access_Stats($date) == '0'){
    $sql = "INSERT INTO Access_Stats (date,YM,day,IDCnt,dailyCnt) (select ".$date.",".$YM.",".$day.",count(distinct LogID),sum(hit) from AccessLog where date='".$date."')";
    @mysql_query($sql);
} else {
    $row = $a->AccessLogCnt($date);
    $sql = "Update Access_Stats SET IDCnt='".$row[0]."',dailyCnt='".$row[1]."' where date='".$date."'";
    @mysql_query($sql);
}

echo "
Work done";
exit;
?>


=== crontab 파일내에 코드 추가 ===

crontab 사용법은 http://link2me.tistory.com/990 참조

PHP 와 crontab 에 대한 사항을 좀 더 알고 싶다면 http://link2me.tistory.com/1013 참조


먼저 php 가 설치된 경로를 찾아야 한다.

// PHP 경로 찾기
whereis php


crontab 에 추가할 내용

// 매일 2시 0분에 실행
0 2 * * * /usr/local/php/bin/php /usr/local/apache/htdocs/stats/accessLog.php

// 매 5분마다 실행 ==> 실제 제대로 저장되는지 여부를 테스트
*/5 * * * * /usr/local/php/bin/php /usr/local/apache/htdocs/
stats/accessLog.php

728x90
블로그 이미지

Link2Me

,

HTML, javaScript, jQuery 는 Client에서 해석하는 언어이고, PHP는 서버와의 통신을 위한 스크립트 언어다.

서버상에서 가져온 파일을 읽으려면 클라이언트에서 인식할 수 있도록 해줘야 한다.

아니면 PHP 코드를 HTML 파일보다 먼저 읽어들이도록 위치를 위에다 놓은 것도 방법이다.


눈에 보이지 않게 <div id="div1" data-lat="<?php echo $lat;?>"></div> 를 이용해서 PHP 변수를 기록하면, HTML 에 기록된 내용을 jQuery, javaScript 에서 읽어올 수 있다.


PHP 변수를 받는 방법은 다른 파일에서 넘겨준 걸 읽을 때는 $_GET, $_POST 배열로 받아서 처리하면 된다.

아니면 직접 include_once '읽고자하는 파일'; 을 지정해주고 파일을 include 하면 해당 파일의 변수가 인식된다.


속성값 읽어오기

자바스크립트에서는 document.getElementById('div1').getAttribute('data-lat');

jQuery 에서는 $("#div1").attr('data-lat');


속성값 변경하기

자바스크립트에서는 document.getElementById('div1').setAttribute('data-lat','변경할값');

jQuery 에서는 $("#div1").attr('data-lat','변경할값');


DB에서 테이블 형태로 읽어온 걸 화면에 표시하고 테이블내 한 행의 게시글의 특정 정보를 알아내고자 할 때에는 this 를 사용한다.

group=$(this).attr('data-group');


==== 예제 파일 =====

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script>
$(document).ready(function(){ // html 문서를 다 읽어들인 후
    //var lat = $("#div1").attr('data-lat'); // jQuery 방식
    var lat = document.getElementById('div1').getAttribute('data-lat'); // javaScript 방식
    var lon = $("#div2").attr('data-lon');
    alert("lat:"+ lat +" lon:"+ lon);
});
</script>
<body>
<?php
//include_once 'getPHP.php'; 다른 파일 내용을 읽어오고자 할 때
$lat = 33.4505296;
$lon = 126.570667;
?>
<div id="div1" data-lat="<?php echo $lat;?>"></div>
<div id="div2" data-lon="<?php echo $lon;?>"></div>
</body>
</html>

728x90
블로그 이미지

Link2Me

,

jQuery Mobile 템플릿을 사용하여 Layout 기본 구조를 파악해보자.



jQuery Mobile 에 대한 자세한 설명은 http://www.w3schools.com/jquerymobile/default.asp 에서 영문으로 찬찬히 읽어가면서 습득하면 도움된다.

jQuery Mobile 버전이 달라지면서 표시되는 색상도 변경될 수 있으므로 무조건 버전을 높은걸 사용하는게 좋지 않을 수도 있다. 높은 버전을 사용하면 변경된 부분을 파악해서 수정해주어야 한다.


<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
<meta http-equiv="cache-control" content="no-cache" />
<meta http-equiv="expires" content="0" />
<meta http-equiv="pragma" content="no-cache" />

<!-- Include meta tag to ensure proper rendering and touch zooming -->
<meta name="viewport" content="user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, width=device-width" />

<!-- Include jQuery Mobile stylesheets -->

<link href="http://code.jquery.com/mobile/1.3.1/jquery.mobile-1.3.1.css" rel="stylesheet" type="text/css" />

<!-- Include the jQuery library -->

<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>

<!-- Include the jQuery Mobile library -->

<script src="http://code.jquery.com/mobile/1.3.1/jquery.mobile-1.3.1.min.js"></script>
</head>


<body>
<div data-role="page">
    <div data-role="header" data-position="fixed" data-theme="b">
        <h1>Header title</h1>
    </div>
    <div id="content" data-role="content" data-theme="e">
        <ul data-role="listview">
        <?php
            echo  '<li>';
            echo  '<a href="#">목록이 없습니다.</a>';
            echo  '</li>';
        ?>
        </ul>
    </div>
    <div data-role="footer" data-position="fixed" data-theme="d">
        <table>
        <tr>
        <td width="15%"><a href="index.html" data-role="button" data-icon="plus" data-iconpos="left">추가</a>
        </td>
        <td width="70%" align=center>Footer Title</td>
        <td width="15%"></td>
        </tr>
        </table>
    </div>
</div>
</body>
</html>


일반적인 웹 사이트의 경우 1 페이지 = 1 HTML 파일이지만, jQuery Mobile 에서는 data-role 속성 'page'를 갖는 div 요소가 1페이지가 된다.

http://www.w3schools.com/jquerymobile/tryit.asp?filename=tryjqmob_pages

에서 보면 1 페이지 안에
<div data-role="page" id="pageone">

<div data-role="page" id="pagetwo">

로 구분하여 작성된 것을 실행해 볼 수 있다. 즉 HTML 페이지는 1Page이지만, jQuery Mobile 에서는 2Page 인 것처럼 만들 수 있다는 의미다.


data-theme="b" 를 사용하여 테마를 변경할 수 있다. (a ~ e 까지 5개 테마)

data-inset="true" 는 모서리를 둥글게 처리

data-split-icon="gear" : 스플릿된 우측모양이 기어모양

data-position="fixed" : 하단에 고정하는 기능

data-rel="dialog" : 다이얼로그 팝업창으로 띄워라

<div data-role="header" data-add-back-btn="true" data-back-btn-text="이전">

data-add-back-btn="true" : Back 버튼 표시

data-back-btn-text="뒤로" : 라벨 변경

<ul data-role="listview" data-theme="e" data-inset="true">

data-theme="e" : 리스트 테마의 변경

data-inset="true" : 모서리를 둥글게 처리

<li data-theme="b" >

data-theme="b" : 해당 항목만 별도로 리스트 테마 변경

<li data-role="list-divider">

data-role="list-divider" : 리스트에 제목 설정

<span class="ui-li-count">10</span><!-- class="ui-li-count" 은 카운트 버블 표시 -->

<ul data-role="listview" data-count-theme="b" data-filter="true" data-filter-placeholder="검색어">
        <!--data-count-theme="c" : 카운드 버블의 테마 변경 -->
        <!--data-filter="true" : 검색 필터 => 일치하는 검색어만 표시됨 -->
        <!--data-filter-placeholder="검색어" : 플레이스 홀더 변경 -->
        <li><a href="#index" data-transition="slideup">
        <!--data-transition="slideup" 위쪽으로 슬라이드되면서 페이지 전환 -->
        <h3>메인 페이지</h3>
        </a></li>
        <li><a href="#about" data-transition="slide">
         <!--data-transition="slide" 왼쪽으로 슬라이드되면서 페이지 전환 -->

data-transition="flip"

data-transition="flip" data-direction="reverse"

<li><a href="#access" data-transition="slide">
    <p class="ui-li-aside">보충정보 표시</p>
    <!--class="ui-li-aside" 속성 추가시 보충정보 표시됨 -->
    <h3>오시는 길</h3>
    <p>설명 내용</p> <!-- 설명문이 있는 리스트 표시됨 -->
    <span class="ui-li-count">99</span>
    <!-- class="ui-li-count" 은 카운트 버블 표시 -->
</a></li>
<li><a href="#contact" data-transition="pop">
    <p class="ui-li-aside">보충정보 표시</p>
    <!--class="ui-li-aside" 속성 추가시 보충정보 표시됨 -->
    <h3>문의</h3>
    <p>설명 내용</p> <!-- 설명문이 있는 리스트 표시됨 -->
</a></li>

<div data-role="content">
    <form action="form.php" method="post">
        <div data-role="fieldcontain">
            <label for="name">이름</label>
            <input type="text" id="name"><!-- id는 전체 소스 기준으로 중복되지 않게 처리해라. -->
        </div>
        <div data-role="fieldcontain">
            <label for="gender">성별</label>
            <select name="gender" id="gender" data-role="slider"><!--플립스위치 표시 -->
            <option value="남자">남자</option>
            <option value="여자">여자</option>
            </select>
        </div>
        <div data-role="fieldcontain">
            <fieldset data-role="controlgroup">
                <legend>주제별 문의</legend>
                <input type="checkbox" name="type1" id="type1" value="수주">
                <label for="type1">프로그램 수주</label>
                <input type="checkbox" name="type2" id="type2" value="기획">
                <label for="type2">프로그램 기획</label>
                <input type="checkbox" name="type3" id="type3" value="개발">
                <label for="type3">프로그램 개발</label>
                <input type="checkbox" name="type4" id="type4" value="배포">
                <label for="type4">프로그램 배포</label>
            </fieldset>
        </div>
        <div data-role="fieldcontain">
            <label for="comment">문의 내용</label>
            <textarea id="comment"></textarea>
        </div>
        <div data-role="fieldcontain">
            <input type="button" value="취소" data-theme="a" data-icon="delete" data-inline="true">
            <input type="submit" value="전송" data-theme="a" data-icon="arrow-r" data-inline="true">

        </div>
    </form>

</div>


jQuery 아이콘 모양은 http://demos.jquerymobile.com/1.4.5/icons/ 에서 참조하면 된다.

data-role 의 설명은 http://blog.naver.com/kimchangyoun/70184929188 참조


728x90
블로그 이미지

Link2Me

,

홈페이지에 접속시 index.php 처리 흐름도는 다음 그림과 같다.


프로그램에서 중요한 것은 어떤 로직으로 그릴것인가 하는 점이다.

사용하는 언어에 따른 문법, 사용법은 당연히 익혀야 한다.


1. index.php 파일에는 순수한 PHP 코드만으로 session 이 있으면 바로 메인페이지로 접속하도록 처리한다.

    session 정보가 없으면 로그인 화면을 띄우도록 한다.

    <?php
    if(!isset($_SESSION)) {
        session_start();
    }
    if(isset($_SESSION['userID']) && !empty($_SESSION['userID'])){
        // 세션 정보가 있으면
        include "main.php";       
    } else {
        // 세션 정보가 없으면
        include "loginForm.php";
    }
    ?>


    이 골격 기반위에 mobile 접속체크 기능을 추가할 수도 있다.

    추가한다면 loginClass.php 파일안에 mobile 체크 함수를 추가할 수 있다.


2. loginForm.php 파일에는 HTML header, body 정보가 들어가 있다.

    - 로그인 정보는 ID, PW 정보이므로 암호화하여 전송하는 것이 안전하다.

    - POST 전송방식으로 전송하여 ID,PW 정보 내용이 보이지 않도록 한다.

    - POST 전송방식 loginForm.php 파일

    <!DOCTYPE html>
    <html>
    <head>
        <title>로그인</title>
        <meta charset="utf-8" />    
        <meta name="viewport" content="width=device-width, initial-scale=1.0,maximum-scale=1.0, minimum-scale=1.0,user-scalable=no"/>
        <meta http-equiv="cache-control" content="no-cache" />
        <meta http-equiv="expires" content="0" />
        <meta http-equiv="pragma" content="no-cache" />

        <!-- Include jQuery Mobile stylesheets -->

        <link rel="stylesheet" href="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.css">

        <!-- Include the jQuery library -->

        <script src="http://code.jquery.com/jquery-1.8.2.min.js"></script>

        <!-- Include the jQuery Mobile library -->

        <script src="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.js"></script>

        <!-- 개발자 본인이 만든 jQuery -->

        <script src="js/loginScript.js"></script>
    </head>
    <body>
    <div id="content" data-role="content" style="margin-top:5%;">
        <center>
        <form id="loginForm" method="post" action="#" >
            <input type="text" name="userID" id="userID" value="" placeholder="아이디" style="width:50%" />
            <input type="password" name="password" id="password" value="" placeholder="패스워드" style="width:50%"/>
            <button type="submit" data-inline="true">로그인</button>
            <button type="reset" data-inline="true">다시작성</button>
        </form>
        </center>
    </div>
    </body>
    </html>


    === loginScript.js ===

    $(document).ready(function(){
        $("#loginForm").submit(function(){
            var loginID = $("#userID").val();
            var loginPW = $("#password").val();

            if(loginID =='') {
                alert("아이디를 입력하세요");
                $("#userID").focus();
                return false;
            }
           
            if(loginPW =='') {
                alert("패스워드를 입력하세요!");
                $("input[type='password']").focus();
                //$("#password").focus();
                return false;
            }    
            $.post('loginChk.php',{userID:loginID, password:loginPW}, function(msg) {
                if(msg==1){ // loginChk.php 파일에서 echo 결과값
                    window.location.href = 'main.php';
                } else {
                    alert('다시 로그인 하세요');
                }
            });
            return false;
        });

        $("input[type='reset']").click(function(){
            if(!confirm("정말 입력을 취소하시겠습니까?")){
                return false;
            }
        });
    });


3. loginChk.php 파일

<?php
if(empty($_POST['userID']) || empty($_POST['password'])){
    echo 0; // 실패
} else {
    $loginID=$_POST['userID'];
    $loginPW=$_POST['password'];

    require_once 'dbconnect.php';
    require_once 'phpclass/loginClass.php';

    $c=new LoginClass();
    $row=$c->UserAuthCheck($loginID,$loginPW);
    if(is_array($row)){
        if(!isset($_SESSION)) {
               session_start();
           }
        $_SESSION['userID'] = $row['userID'];
        $_SESSION['level'] = $row['level'];
        echo 1; // 로그인 성공
    } else {
        if(!isset($_SESSION)) {
               session_start();
           }
        session_destroy();
        echo 0; // 실패
    }
}
?>


※ dbconnect.php 파일 만드는 방법은 http://link2me.tistory.com/1110 참조하라.


=== loginClass.php 파일 발췌 ===

로그인 검사는 해킹 공격적인 요소를 필터링 하기 위한 것도 고려했다.

<?php
class LoginClass {
    function UserAuthCheck($u,$p) {
        if(!isset($u) || !isset($p) || empty($u) || empty($p)) {
            return 0;
        } else {
            global $db;           
            $u = preg_replace("/[\s\t\'\;\"\=\--]+/","", $u); // 공백이나 탭 제거(사용자 실수 방지)
            $p = preg_replace("/[\s\t\'\;\"\=\--]+/","", $p); // 공백이나 탭 제거, 특수문자 제거
            // SQL injection 검사
            $u = htmlentities($u); // <script>documnet.cookie();</script> 공격 방지, 한글인식 불가
            $p = htmlentities($p); // < 를 \< 로 바꿔준다.
            $u = str_replace(array("'",""","'",'"'), array("&#39;","&quot;","&#39;","&quot;"), $u);
            if(preg_match('/[\']/',$u)) return 0; // no quotes
            if(preg_match('/[\/\\\\]/', $u)) return 0; // no slashes
            if(preg_match('/(and|null|where|limit)/i', $u)) return 0; // i는 대소문자 구별하지 말라
            if(!preg_match('/^[0-9a-zA-Z\~\!\@\#\$\%\^\&\*\(\)]{7,}$/',$p)) return 0; // 7자리이상 허용 문자만 통과
            $sql = "select * from member where pw=md5('".$p."') and id= '".$u."' ";
            if($result = mysql_query($sql,$db)) { //성공
                $row = mysql_fetch_array($result);
                if($row == NULL) return 0;
                return $row;
            } else {
                return '-1';
            }
        }
    }

}//end class LoginClass

?>


4. main.php 파일에도 HTML header, body 정보가 들어가 있다.

   메인 페이지 내용을 작성하여 원하는 데이터를 출력한다.

   DB에서 조회하여 가져온 데이터를 테이블 형식으로 보여주고자 한다면

   너무 많은 자료를 가져오면 부하문제도 생기고 화면 스크롤 문제도 생기므로

   페이징 처리를 해서 보여줘야 한다.

   http://link2me.tistory.com/1112 참조


5. 변수가 제대로 넘어오는지 체크하고자 할 경우

아래 코드를 추가하고 exit; 를 넣은 이유는 다음 코드를 실행하지 말고 중단해서 변수가 제대로 넘어오는지 여부를 한번에 확인하고자 하는 목적이다.


@extract($_POST);
var_dump($_POST);
exit;

728x90
블로그 이미지

Link2Me

,

PHP 에서 페이징 처리하는 방법이다.
Paging 이란 전체 자료를 가져오는 것이 아니라 일정한 갯수만큼 화면에 가져오도록 처리하는 로직이다.


1. 한 페이지에 보여줄 개수를 정한다.

2. DB에서 전체 자료수(total Rows)에서 총 페이지수를 구한다.

3. 실제 페이지 번호가 표시될 개수를 정한다. 보편적으로 10개씩 보여주도록 할 수 있다.

4. 첫페이지로 가는 버튼

5. 마지막 페이지로 가는 버튼

6. 이전 블록으로 가는 버튼

7. 다음 블록으로 가는 버튼

 

변수를 정의해보자.

1. $totalcnt : 총 게시물수

2. $rowsPage : 한 페이지에 보여줄 개수

3. $totalPage = ceil($totalcnt/$rowsPage); // 총 페이지수

    총페이지수가 0 이면 1로 표기

    if($totalPage == 0) {

          ++$totalPage;

    }

4. $total_block = ceil($totalPage / $block_limit); //전체 블록 갯수

5. $curPage = $curPage ? $curPage : 1; // 현재 페이지

6. $block_limit : 한 화면에 뿌려질 게시글 개수

7. $current_block=ceil($curPage/$block_limit); // 현재 블럭 : 화면에 표시될 페이지 리스트

8. $fstPage = (((ceil($curPage/$block_limit)-1)*$block_limit)+1); // 현재 블럭의 시작

9. $endPage = $fstPage + $block_limit -1; // 현재 블럭의 마지막

    if($totalPage < $endPage) {
        $endPage = $totalPage;
     }
10. $prev_page = $fstPage - 1; // 시작 바로 전 페이지

11. $next_page = $endPage + 1; // 마지막 다음 페이지

 

 

이제 본문에 뿌릴 개수를 함수로 만들어 보자.

<?php
class MySQLDbClass {

 

    function isConnectDb($db) {
        $conn = mysql_connect($db['host'].':'.$db['port'],$db['user'],$db['pass']);
        //Set encoding
        mysql_query("SET CHARSET utf8");
        mysql_query("SET NAMES 'utf8' COLLATE 'utf8_general_ci'");
        if(!$conn){
        die('Not connected :' . mysql_error());
        exit;
        }
        $selc = mysql_select_db($db['name'],$conn); // 접근한 계정으로 사용할 수 있는 DB 선택
        return $selc ? $conn : false;
    }

 

    //DB데이터 ARRAY -> 테이블에 출력할 데이터 배열
    // order by : 정렬 순서, rowsPage : 화면에 출력할 개수, curPage : 현재 페이지
    function getDbArray($table,$where,$flddata,$orderby,$rowsPage,$curPage){
        global $db;
        $curPage = $curPage ? $curPage : 1; // 현재 페이지가 없으면 1로 설정
        $sql = 'select '.$flddata.' from '.$table.($where?' where '.$this->getSqlFilter($where):'').($orderby?' order by '.$orderby:'').($rowsPage?' limit '.(($curPage-1)*$rowsPage).', '.$rowsPage:'');
        //echo $sql;
        $result = mysql_query($sql);
        return $result;
    }

    //SQL필터링
    function getSqlFilter($sql){
        return $sql;
    }

}//end dbClass

 

화면 하단에 뿌릴 페이징 처리 함수 만들기

dbClass 함수 안에 넣어도 되고 별도의 클래스를 만들어서 호출해서 사용해도 된다.

// $curPage : 현재 페이지, $totalcnt : 총 게시물수
// $block_limit : 한 화면에 뿌려질 게시글 개수
function PageList($totalcnt,$rowsPage,$curPage,$block_limit) {
    $block_limit = $block_limit ? $block_limit : 10;  // 한 화면에 보여줄 개수 기본 10으로 설정

    // 총 페이지수 구하기
    $totalPage = ceil($totalcnt/$rowsPage); 
    if($totalPage == 0) {
        ++$totalPage;
    }
    $total_block = ceil($totalPage / $block_limit); //전체 블록 갯수
   
    $curPage = $curPage ? $curPage : 1; // 현재 페이지

    // 현재 블럭 : 화면에 표시될 페이지 리스트
    $current_block=ceil($curPage/$block_limit);
    // 현재 블럭에서 시작페이지
    $fstPage = (((ceil($curPage/$block_limit)-1)*$block_limit)+1);
    // 현재 블럭에서 마지막 페이지
    $endPage = $fstPage + $block_limit -1;
    if($totalPage < $endPage) {
        $endPage = $totalPage;
    }

    // 시작 바로 전 페이지
    $prev_page = $fstPage - 1;
    // 마지막 다음 페이지
    $next_page = $endPage + 1;

    foreach(range($fstPage, $endPage) as $val) {
        $row[] = $val;
    }
    // 배열로 결과를 돌려준다.
    return array(
        'total_block' => $total_block,
        'current_block' => $current_block,
        'totalPage' => $totalPage,
        'fstPage' => $fstPage,
        'endPage' => $endPage,
        'prev' => $prev_page,
        'next' => $next_page,
        'current' => $row
    );
}

 

페이징 화면에 출력하기

HTML 문법은 bootstrap3 또는 bootstrap4에 맞게 Class만 수정해주면 된다.

function PageLinkView($link_url,$totalcnt,$rowsPage,$curPage){
    echo '<div style="position:relative;vertical-align:top;padding-top:0;margin-top:0">';
        echo "<span style='position:absolute;top:10px;'>[총 자료수:".$totalcnt."]</span>";
        echo '<div class="pagelink">';
            $Info = $this->PageList($totalcnt,$rowsPage,$curPage,'');
            if($Info['current_block'] > 2){
                echo "<a href='".$link_url."?p=1'>◀</a> ";
            }
            if($Info['current_block'] > 1){
                echo "<a href='".$link_url."?p=".$Info['prev']."'>◁</a> ";
            }
            foreach($Info['current'] as $w) {
                if($curPage == $w){
                    echo "<a href='".$link_url."?p=".$w."'><span style='color:red;font-size:22pt'>".$w."</span></a> ";
                } else {
                    echo "<a href='".$link_url."?p=".$w."'>".$w."</a> ";
                }
            }
            if($Info['current_block'] < ($Info['total_block'])){
                echo "<a href='".$link_url."?p=".$Info['next']."'>▷</a> ";
            }
            if($Info['current_block'] < ($Info['total_block']-1)){
                echo "<a href='".$link_url."?p=".$Info['totalPage']."'>▶</a> ";
            }
        echo '</div>';
    echo '</div>';
}   

 

사용법 예제

<?php
include_once 'dbinfo.php';
require_once 'phpclass/dbClass.php';

$conn = new MySQLDbClass(); // DB 함수
$db = $conn->isConnectDb($DB);

// 화면에 출력할 칼럼 발췌
$flddata ="(select name from cate where uid=d.cat1) as cat1,subject,content";
$rowsPage = 12;
$curPage = isset($_GET['p']) ? $_GET['p'] : 1;
$result = $conn->getDbArray('data d','',$flddata,'',$rowsPage,$curPage);
$totalcnt 구하는 함수 처리

 

본문 Layout : 테이블을 작성해서 $result 배열 결과물을 table td 태그안에 기록

페이징 Layout : 페이징 화면 출력

 

?>

 

함수로 만든 모든 것을 표기하지는 않았다.

이런 형태로 만들어 볼 수 있다는 것만 알 수 있게 작성했다.

 

실 사용 예제

- 네이버지식인에 링크를 걸어줬더니 성의없는 답변이라는 댓글을 보고서 실제 사용하는 예제를 추가했음.

- 어떻게 처리하는지에 대한 흐름만 이해하면 되는 사항.

<?php
if(!isset($_SESSION)) {
    session_start();
}
 
require_once '../dbconnect.php';
require_once '../phpclass/dbClass.php';
require_once '../phpclass/bbsClass.php';
require_once '../phpclass/adminClass.php';
$a = new adminClass();
$b = new bbsClass();
$c = new MySQLDbClass();
 
// 설문 테이블 상태 변경 체크
$a->surveyDBupdate();
 
$url = $_SERVER['PHP_SELF']; // 현재 실행중인 파일명 가져오기
$page = isset($_GET['page'])? trim($_GET['page']):1;//페이지 변수 설정
$rowsPage = 10// 한 화면에 표시되는 게시글 수
$curPage = isset($_GET['p']) ? $_GET['p'] : 1;
$bd_name = isset($_GET['bd_name']) ? $_GET['bd_name'] :'';
$mode = isset($_GET['mode']) ? $_GET['mode'] :'list';
$sel = isset($_GET['sel'])? $_GET['sel'] : '';
 
$flddata ="*";// 화면에 출력할 칼럼 발췌
$where = isset($_GET['where']) ? $_GET['where']: '';
$keyword = isset($_GET['keyword']) ? $_GET['keyword']: '';
$xorderbyisset($xorderby) ? $xorderby : 'uid DESC';
if($where && $keyword) {
    if($where == 'title'$sql = "title LIKE '%".$keyword."%' ";
    if($where == 'content'$sql = "content LIKE '%".$keyword."%' ";
    if($where == 'unify') {
        $sql = "(title LIKE '%".$keyword."%' OR content LIKE '%".$keyword."%') ";
    }
else {
    $sql ='';
}
if(!empty($sel)){
    if($keyword){
        $sql .= " and status = ".$sel;
    } else {
        $sql = " status = ".$sel;
    }
}
 
//echo $sql.'<br />';
 
$link_url=($bd_name?'bd_name='.$bd_name.'&amp;':'').($mode?'mode='.$mode.'&amp;':'').($sel?'sel='.$sel.'&amp;':'').($where?'where='.$where.'&amp;':'').($keyword?'keyword='.urlencode(stripslashes($keyword)).'&amp;':'');
$g['bbs_reset'= $url// 초기화
 
$table ='poll_admin';
$rows$c->getDbArray($table,$sql,$flddata,$xorderby,$rowsPage,$curPage);
$NUM = $c->getDbRows($table,$sql); // 전체 게시글수
$TPG = $b->getTotalPage($NUM,$rowsPage);
?>
 
<!DOCTYPE html>
<head>
<title><?php echo $title;?></title>
<meta charset="utf-8">
<meta name="robots" content="noindex,nofollow"/>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="../vendor/bootstrap/css/bootstrap.min.css">
<link href="vendor/font-awesome/css/font-awesome.min.css" rel="stylesheet" type="text/css">
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,700" rel="stylesheet" type="text/css">
<link href="https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic" rel="stylesheet" type="text/css">
<link rel="stylesheet" type="text/css" href="../css/survey.css" />
<script src="../vendor/jquery/jquery.min.js"></script>
<script src="../vendor/bootstrap/js/bootstrap.min.js"></script>
<script src="../js/modal.js"></script>
</head>
<body>
<div class="container">
<table class="table table-bordered">
<tr>
    <td align=center><font class='title'><b>설문조사<br><br>
    <div class="pull-left info bmargin">
        <select name='sel' onchange='document.searchf.sel.value=this.value;document.searchf.submit();'>
        <option value=''>전체목록보기</option>
        <option value='1' <?php if("1"==$sel):?> selected<?php endif?>>진행중목록</option>
        <option value='2' <?php if("2"==$sel):?> selected<?php endif?>>종료 목록</option>");
        </select>
    </div>
    <div class="pull-right info bmargin">
        <a href='survey_admin.php'><button class="w3-button w3-blue-grey w3-tiny">관리</button></a>&nbsp;
        <a href='add_form.php?mode=new'><button class="w3-button w3-blue-grey w3-tiny">등록</button></a>
    </div>
<!--  설문 내용 -->
<table class='w3-table w3-bordered'>
    <thead>
        <tr class="w3-blue-grey">
            <th width="8%">No</th>
            <th width="43%">설문 제목</th>
            <th width="11%">총응답</th>
            <th width="13%">시작일</th>
            <th width="13%">종료일</th>
            <th width="10%">상 태</th>
        </tr>
    </thead>
    <tbody>
        <?php $i=1;foreach($rows as $R):?>
        <tr>
            <td><?php echo $i;?></td>
            <td>
            <?php
                $memo="&nbsp;<a href='survey_memo.php?bd_name=".$R['bd_name']."&mode=list&sel=".$sel."'><img src='./image/memo.gif' border='0' alt='메모보기'></a>";
                if($R['enddate'< date("Y-m-d")){
                    echo "<a href='survey_res.php?bd_name=".$R['bd_name']."&sel=".$sel."'> ".$R['title']."</a>$memo</td>";
                    $status = "종 료";
                } else {
                    if($R['startdate'> date("Y-m-d")) $status = "준비중";
                    else $status = "진행중</td>";
                    echo "<a href='survey.php?bd_name=".$R['bd_name']."&sel=".$sel."'> ".$R['title']."</a>$memo</td>";
                }
            ?>
            </td>
            <td><?php echo $R['totalcnt'];?></td>
            <td><?php echo $R['startdate'];?></td>
            <td><?php echo $R['enddate'];?></td>
            <td><?php echo $status;?></td>
        </tr>
        <?php $i++;endforeach;?>
    </tbody>
</table>
<div><br></div>
<div class='searchbox'>
    <form name="searchf" class="form-inline" action="<?php echo $url.'?'.$link_url;?>">
        <input type="hidden" name="mode" value="<?php echo $mode?>" />
        <input type="hidden" name="sel" value="<?php echo $sel?>" />
        <input type="hidden" name="p" value="1" />
        <select name="where" class="form-control input-sm">
            <option value="unify">통합</option>
            <option value="title">제목</option>
            <option value="content">설명</option>
        </select>
        <div class="input-group input-group-sm">
            <input type="text" name="keyword" value="" class="form-control input-search" placeholder="검색어">
            <span class="input-group-btn">
                <button type="button" class="btn btn-default" onclick="this.form.where.value='title';this.form.keyword.value='',this.form.submit();" title="리셋"><i class="glyphicon glyphicon-repeat"></i></button>
                <button type="submit" class="btn btn-info" title="검색"><i class="glyphicon glyphicon-search"></i></button>
            </span>
        </div>
    </form>
</div>
<div class="pull-right info">
    <a href="<?php echo $g['bbs_reset']?>" class="btn btn-default btn-sm pull-right">처음목록</a>
</div>
<?php $b->PageLinkView($url,$NUM,$rowsPage,$curPage,$link_url);?>
</td>
</tr>
</table>
</div>
</body>
</html>
<?php mysqli_close($db);?>
 

 

<?php
class bbsClass extends MySQLDbClass {
 
    function PageLinkView($link_url$totalcnt$rowsPage$curPage$m) {
        echo '<div id="paging">';
        echo '<ul class="pagination">';
        $Info = $this -> PageList($totalcnt$rowsPage$curPage'');
        if ($Info['current_block'> 2) {
            echo "<li><a href='" . $link_url . "?p=1&$m'>◀</a></li> ";
        }
        if ($Info['current_block'> 1) {
            echo "<li><a href='" . $link_url . "?p=" . $Info['prev'] . "&$m'>◁</a></li> ";
        }
        foreach ($Info['current'as $w) {
            if ($curPage == $w) {
                echo "<li class='act'><a href='" . $link_url . "?p=" . $w . "&$m'><span style='color:red;'>" . $w . "</span></a></li> ";
            } else {
                echo "<li><a href='" . $link_url . "?p=" . $w . "&$m'>" . $w . "</a></li> ";
            }
        }
        if ($Info['current_block'< ($Info['total_block'])) {
            echo "<li><a href='" . $link_url . "?p=" . $Info['next'] . "&$m'>▷</a></li> ";
        }
        if ($Info['current_block'< ($Info['total_block'- 1)) {
            echo "<li><a href='" . $link_url . "?p=" . $Info['totalPage'] . "&$m'>▶</a></li> ";
        }
        echo '</ul>';
        echo '</div>';
    }
 
    // $curPage : 현재 페이지, $totalcnt : 총 게시물수
    // $block_limit : 한 화면에 뿌려질 게시글 개수
    function PageList($totalcnt,$rowsPage,$curPage,$block_limit) {
        $block_limit = $block_limit ? $block_limit : 10;  // 한 화면에 보여줄 개수 기본 10으로 설정
 
        // 총 페이지수 구하기
        $totalPage = ceil($totalcnt/$rowsPage);
        if($totalPage == 0) {
            ++$totalPage;
        }
        $total_block = ceil($totalPage / $block_limit); //전체 블록 갯수
 
        $curPage = $curPage ? $curPage : 1// 현재 페이지
 
        // 현재 블럭 : 화면에 표시될 페이지 리스트
        $current_block=ceil($curPage/$block_limit);
        // 현재 블럭에서 시작페이지
        $fstPage = (((ceil($curPage/$block_limit)-1)*$block_limit)+1);
        // 현재 블럭에서 마지막 페이지
        $endPage = $fstPage + $block_limit -1;
        if($totalPage < $endPage) {
            $endPage = $totalPage;
        }
 
        // 시작 바로 전 페이지
        $prev_page = $fstPage - 1;
        // 마지막 다음 페이지
        $next_page = $endPage + 1;
 
        foreach(range($fstPage$endPageas $val) {
            $row[] = $val;
        }
        // 배열로 결과를 돌려준다.
        return array(
            'total_block' => $total_block,
            'current_block' => $current_block,
            'totalPage' => $totalPage,
            'fstPage' => $fstPage,
            'endPage' => $endPage,
            'prev' => $prev_page,
            'next' => $next_page,
            'current' => $row
        );
    }
 
    //총페이지수
    function getTotalPage($num,$rec){
        return @intval(($num-1)/$rec)+1;
    }
 
}//end class boardClass

 

 
<?php
extract($_GET);
extract($_POST);
class MySQLDbClass {
    protected $db;
    private $host = 'localhost';
    private $database = 'survey';
    private $userid = 'root';
    private $password = 'autoset';
 
    public function __construct() {
        $this->db = $this->connectDB();
    }
 
    function __destruct(){
        mysqli_close($this->connectDB());
        //mysqli_close($this->db);
    }
 
    private function connectDB() {
        $dbconn = mysqli_connect($this->host, $this->userid, $this->password, $this->database);
        mysqli_set_charset($dbconn"utf8"); // DB설정이 잘못되어 euc-kr 로 되어 있으면 문제가 됨
        if (mysqli_connect_errno()) {
           printf("Connect failed: %s\n", mysqli_connect_error());
           exit();
        } else {
          return $dbconn;
        }
    }
 
    //DB-UID데이터
    function getUidData($table,$uid){
        return $this->getDbData($table,'uid='.(int)$uid,'*');
    }
 
    // DB Query Cutom 함수
    function getDbData($table,$where,$column) {
        $result = mysqli_query($this->db,'select '.$column.' from '.$table.($where?' where '.$this->getSqlFilter($where):''));
        $row = mysqli_fetch_array($result);
        return $row;
    }
 
    // DB Query result 함수
    function getDbresult($table,$where,$column) {
        $result = mysqli_query($this->db,'select '.$column.' from '.$table.($where?' where '.$this->getSqlFilter($where):''));
        return $result;
    }
 
    //DB데이터 ARRAY -> 테이블에 출력할 데이터 배열
    function getDbArray($table,$where,$flddata,$orderby,$rowsPage,$curPage){
        $sql = 'select '.$flddata.' from '.$table.($where?' where '.$this->getSqlFilter($where):'').($orderby?' order by '.$orderby:'').($rowsPage?' limit '.(($curPage-1)*$rowsPage).', '.$rowsPage:'');
        if($result = mysqli_query($this->db,$sql)){
            return $result;
        }
    }
 
    //DB데이터 레코드 총 개수
    function getDbRows($table,$where){
        $sql = 'select count(*) from '.$table.($where?' where '.$this->getSqlFilter($where):'');
        if($result = mysqli_query($this->db,$sql)){
            $rows = mysqli_fetch_row($result);
            return $rows[0] ? $rows[0] : 0;
        }
    }
 
    //DB삽입
    function getDbInsert($table,$key,$val){
        mysqli_query($this->db,"insert into ".$table." (".$key.")values(".$val.")");
    }
 
    //DB업데이트
    function getDbUpdate($table,$set,$where){
        mysqli_query('set names utf8');
        mysqli_query('set sql_mode=\'\'');
        mysqli_query($this->db,"update ".$table." set ".$set.($where?' where '.$this->getSqlFilter($where):''));
    }
 
    //DB삭제
    function getDbDelete($table,$where)    {
        mysqli_query($this->db,"delete from ".$table.($where?' where '.$this->getSqlFilter($where):''));
    }
 
    //SQL필터링
    function getSqlFilter($sql){
        return $sql;
    }
 
}//end dbClass
 
?>

 

728x90
블로그 이미지

Link2Me

,

코딩을 배우면서 느끼는 것은 기본기가 중요하다는 것이다.

그래서 기초적인 걸 다시 정리차원에서 적어둔다.


HTML5의 기본적인 템플릿 구조는 이렇게 되어 있다.

스마트폰에서 접속하는 걸 고민하지 않게 하는 한줄이 viewport 기능이다.


익스플로러의 최대 단점은 버전별로 보여지는 웹의 모습이 많이 다르다는 것이다.
마이크로소프트사는 X-UA-Compatible 태그로 웹의 호환성을 지정할 수 있도록 하였다.
바로  X-UA-Compatible 태그다.
<meta http-equiv="X-UA-Compatible" content="IE=8" />
<meta http-equiv="X-UA-Compatible" content="IE=9" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
edge라고 기록된건 IE 브라우저의 최신 버전의 엔진을 사용하라는 뜻이다.
모든 버전에서 사용가능한 사이트라고 하면 edge만 추가해주면 된다.



<!DOCTYPE html> <!--HTML5 선언 -->
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no"/><!--화면 사이즈를 고려하지 않아도 적절하게 표시 -->
        <meta http-equiv="X-UA Compatible" control="IE=edge,chrome=1" /> <!--브라우저 호환성 설정 -->
        <title>HTML 서식</title>

        <!-- Include the jQuery library -->
        <script src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
    </head>
    <body>
        문서본문
    </body>
</html>


HTML5 에서는 <script type="text/javascript"를 넣지 않아도 된다.

Web은 HTTP(Hyper Text Transfer Protocol) 라는 프로토콜에 따라 서버와 클라이언트 간의 통신을 수행한다.
HTML은 태그를 통해 정보를 구조화한다.
태그란?
- 문서의 글자크기, 글자색, 글자모양, 그래픽, 링크 등을 정의하는 명령어
- 꺽쇠괄호 ‘<>’를 사용 <html>
- 일반적으로 태그는 시작과 끝을 표시하는 2개의 쌍 <table></table>
- 태그의 종류는 엄청 많다. 문법과 용도에 맞게 사용해야 한다.
Web browser마다 랜더링 방식이 서로 달라 HTML5가 나왔다.
- HTML에 화면 표시와 관련된 태그까지 추가하게 되자 간단하게 해결하고자
  CSS(Cascading Style Sheets)가 담당하게 했다.


화면에 정보를 보여주는 방법으로 가장 많이 사용하는 것이 테이블이다.

테이블은 table 태그를 사용한다.
테이블 선언 <table></table>
- 테이블 행은 <tr>을 사용
- 행을 셀로 분할하는 태그는 <td>를 사용, 제목 태그는 <th>를 사용
- 테이블의 너비, 테두리, Padding, 셀간격, 경계설정 등은 CSS를 사용
- CSS 는 head에 정의한다.
  <style>
    table,tr,td {border:1px solid #000000}
  </style>


테이블에서 셀간에 병합을 하는 것은 셀에 해당하는 <tr>, <th> 테그이다.

영어로 행에 해당하는 row, 열에 해당하는 column 을 사용하여

위아래 행을 병합하는 것은 <tr rowspan="합치고 싶은 만큼의 숫자">

같은 행에서 옆으로 병합하는 것은 <tr colspan="합치고 싶은 만큼의 숫자"> 로 하면 된다.


테이블에서 실제 정보가 표현되는 것은 <tr> 태그이다.

예제를 살펴보자.

DB와 연결하기 위해 DB 연결파일을 include 하고 나서, 테이블 태그를 작성하고 실제 내용을 채울 곳은 while 문으로 반복해서 <tr><td>내용</td></tr> 구조로 작성된 것을 알 수 있다.


<?php
include_once 'dbconnect.php'; // DB 연결

echo '<table border="1">';
// 제목
echo '<tr>';
echo '<th ALIGN=CENTER BGCOLOR="#9DEEE1">번호</td>';
echo '<th ALIGN=CENTER BGCOLOR="#9DEEE1">구분자</td>';
echo '<th ALIGN=CENTER BGCOLOR="#9DEEE1">연관번호</td>';
echo '</tr>';

$sql = "SELECT uid, classname, relateduid FROM category ORDER BY uid DESC";
$result = mysql_query($sql);
while ($row = mysql_fetch_array($result) ){ // DB에서 가져온 갯수만큼 테이블 행 생성
    // 내용
    echo '<tr>';
    echo '<td ALIGN=CENTER>'.$row['uid'].'</td>';
    echo '<td ALIGN=CENTER>'.$row['classname'].'</td>';
    echo '<td ALIGN=CENTER>'.$row['relateduid'].'</td>';
    echo '</tr>';
}
echo '</table>';

?>


Web 에서의 특수문자

공백

&nbsp;

>

&gt;

 <

&lt;


728x90
블로그 이미지

Link2Me

,
본 게시글은 처음 시작은 단순한 정리 개념이었는데, PHP 기본을 이해하는 핵심이라고 봐도 좋다.

네이버지식인 질문을 보면 PHP 개념은 모른 상태에서 Android 앱과의 통신을 어떻게 하는지 알고 싶은 Copy&Paste 초보자 도움 요청을 많이 본다. 가장 중요한 것은 기본 개념을 얼마나 잘 이해하고 있는가다.

스스로 로직을 그려보고 테스트하고 디버깅하면서 조금씩 성장할 수 있다.


모든 내용을 하나의 파일로 처리할 수는 없다. 파일을 모듈단위로 나누어서 처리하는게 좋다.

통신할 때 파일 처리에 대한 기본 개념을 알아야 한다.



(GET,POST 개념을 모른다면 일단 눌러서 읽어본다. http://link2me.tistory.com/398)


파일간에 정보를 넘겨주고 받기 위해서는 $_GET 배열, $_POST 배열을 사용하여 변수를 넘긴다.

$_GET 배열, $_POST 배열 구분없이 둘다 인식하도록 하려면 PHP 파일 B에서 $_REQUEST 배열을 사용한다.


아래 표에서 PHP 관련 게시글은 초보자 도움 링크를 추가한 것이니 꼭 읽어보시길 ^^


PHP

 - LoingForm.php (파일A)에서 loginID, loginPW 값을 POST 방식으로 보낸다.

 - PHP 파일B에서 읽어들일 때 $_POST 배열로 읽어서 처리한다.

 - 배열변수를 MySQL DB 변수로 보내서 결과를 return 받아서 로그인 성공과 실패를 판단한다.

 - 로그인 성공이면 main.php or list.php 와 같은 파일로 이동시킨다.

 - 로그인 실패면 LoginForm.php 파일로 다시 이동시킨다.

 MySQL DB 생성 및 사용자 권한 부여 방법 : http://link2me.tistory.com/431 참조

 MySQL 연동 기본 코딩 방법 : http://link2me.tistory.com/1213 참조

 PHP 디버깅 요령 및 경고 메시지 처리 방법 : https://link2me.tistory.com/1130 참조

 PHP 변수지정 기초 지식 : https://link2me.tistory.com/523 참조

 PHP isset 와 empty 설명 : https://link2me.tistory.com/996 참조

 닥치고 객체지향 MySQLi 연동방식 예제 : http://link2me.tistory.com/1395 참조

 제대로 배우는 자바스크립트 Form 전송 기초 : http://link2me.tistory.com/954 참조

 회원가입 및 중복체크 Form 예제 : https://link2me.tistory.com/1480 참조

 PHP Legacy 함수를 PDO Class 로 변경하는 방법 : https://link2me.tistory.com/1636 참조

 PHP PDO Class 및 부트스트랩 로그인 폼/처리 예제 : http://link2me.tistory.com/1402 참조

 Windows 기반 APM(Apaceh + PHP + MySQL) 설치 https://link2me.tistory.com/797  참조

 PHP 함수의 결과는 정수일까? String일까? https://link2me.tistory.com/1487 참조

 Android

PHP 와 Android 간 연동 처리 개념

 - Android 에서 로그인 정보를 조회한다고 하면 loginID, loginPW 값을 POST 방식으로 보낸다.

 - PHP 파일B에서 읽어들일 때 $_POST 배열로 읽어서 처리한다.

 - DB 조회 결과를 echo 문으로 출력한다.
 - echo 출력 결과를 읽어서 로그인 성공, 실패 여부를 판단 처리한다.

   가령, echo 1 이면, Android 에서는 1의 결과로 로그인 성공으로 다음 Activity 로 전환처리한다.

 - 많은 값을 결과로 돌려 받아야 하는 경우에는

   echo json_encode(배열) 로 받은 결과를 파싱하여 처리한다.

  Android JSON 파헤치기(필수사항) : https://link2me.tistory.com/1247  참조

  Android Volley 라이브러리 사용 예제 : https://link2me.tistory.com/1533 

  Android Retrofit2 라이브러리 사용 예제 : https://link2me.tistory.com/1806

  Android AsyncTask Class화하여 사용하는 방법 : https://link2me.tistory.com/1516 

  Android 암호화 로그인 처리 : https://link2me.tistory.com/1231

  Android - MySQL 연동 Web Part : http://link2me.tistory.com/1022

  Android Studio 기반 로그인 예제 : http://link2me.tistory.com/1230 

  Android Studio & PHP PDO 기반 회원가입 예제 : http://link2me.tistory.com/1405

  Android Studio & PHP PDO 기반 로그인 예제 : http://link2me.tistory.com/1404 

 C#

 - C# 에서 로그인 정보를 조회한다고 하면 loginID, loginPW 값을 POST 방식으로 보낸다.

 - PHP 파일B에서 읽어들일 때 $_POST 배열로 읽어서 처리한다.

 - DB 조회 결과를 echo 문으로 출력한다.

 - echo 출력 결과를 읽어서 C# 에서 로그인 성공, 실패 여부를 판단 처리한다.

  C# Web 접속 로그인 예제 : http://link2me.tistory.com/1118 

 

 윈도우즈 환경에서 리눅스 서버를 설치하고 Web서버를 운용할 수 있다.

 APM(Apache + PHP + MariaDB) 를 설치하는 방법을 자세히 알려주고 있다.

 - Window10 에 CentOS7(리눅스) 설치 및 APM 구성 : https://link2me.tistory.com/1885

 - 윈도우기반 APM 설치 툴 autoset9 : http://link2me.tistory.com/797

 - Apache 환경설정 방법 : http://link2me.tistory.com/426, http://link2me.tistory.com/999

 - PHP 환경 설정 방법 : http://link2me.tistory.com/967, http://link2me.tistory.com/986


Web(PHP 파일B) 에서 변수가 없거나 값이 넘어오지 않을 경우에는 동작하지 않도록 코딩을 해야 한다.


초보자들이 가장 많이 하는 실수(내가 초보시절에 겪은 실수)는 통신방식을 고려하지 않고 코딩을 하거나 서버 세팅정보를 대충 하는 것이다. 대화해보면 코딩 좀 하는 분도 이런걸 대략 하는 분이 있다. (한국어와 영어 소통하는 것과 같은 것)

UTF-8 로 세팅한다는 의미는 파일 Encoding Mode 도 UTF-8 로 하고, 서버에 세팅도 UTF-8 로 하고 DB에도 UTF-8 로 해야 한다는 것이다. (엑셀은 EUC-KR 방식으로 CSV 파일 내보내기를 한다)


참고사항


DB 연결정보는 로그인 처리 뿐만 아니라 거의 모든 PHP에서 사용한다고 볼 수 있다.

모든 PHP 파일에서 중복해서 DB 연결 정보를 코딩하는 것은 비효율적이므로, 파일을 분리하여 dbconnect.php 파일로 작성해두기만 하면 코딩이 심플해지고 가독성도 좋아진다.


dbconnection 을 하는 파일을 만드는 방법을 알아보자.


require문, include문 : 자주 사용하는 PHP 코드를 다른 파일에 모아 두고 필요할 때 파일을 읽어들여서 사용할 수 있도록 하는 명령


require "파일명";

- 만일 지정된 파일이 존재하지 않을 경우에는 php.ini에 설정된 include_path에서 파일을 찾는다.

- include_path에도 파일이 존재하지 않는다면 require문을 작성한 현재 파일이 있는 디렉토리에서 찾는다.

- 현재 디렉토리에도 없다면 오류표시하고 정지된다.


require와 include의 차이점

- require문은 오류가 발생했을 경우에 Fatal Error가 되어 정지가 되어버린다.

- require_once() : 지정한 파일을 한 번 읽어 들이면 같은 처리 중에는 다시 읽어 들일 수 없다.

- include문은 오류가 발생했을 경우에 Warning을 출력하고 처리코드를 수행한다.

- include_once() : 지정된 파일을 이미 읽어 들어 경우에는 다시 파일을 읽어 들이지 않는다.


PHP Connect to MySQL

- MySQL (procedural) : MySQL DB에서만 동작하며, , PHP 7.0 이상에선 동작안됨. PHP 5.5에서 deprecated

- MySQLi (procedural) : MySQL DB에서만 동작한다.

- MySQLi (object-oriented) : MySQL DB에서만 동작한다.
- PDO(PHP Data Objects) :
Oracle, PostgreSQL, SQLite, MySQL 등 12가지의 DB에서 동작한다.


Connecting to MySQL using the legacy MySQL functions

절차지향(procedural) 접속 함수는 MySQLi 방식과 MySQL 방식이 있다.

MySQL 설치방식에 따라 둘다 지원할 수도 있고 둘 중에 하나만 지원할 수도 있다.

MySQL 방식과 MySQLi 방식은 연결 방식이 약간 다르므로 코딩시 실수하지 않도록 주의가 필요하다.

======== dbinfo.php ======

<?php
$db['host'] = "localhost";
$db['name'] = "";
$db['user'] = "";
$db['pass'] = "";
$db['port'] = "3306";
?>


======= dbconnect.php ========

PHP 프로그램 내에서 MySQL 데이터베이스에 접근하는 함수가 mysqli_connect()이다.

$dbconn 라고 했지만 $db 또는 $conn 등 개발자 취향에 따라 변수명을 지정한다.

dbClass.php 에 만든 사용자 함수에 global $dbconn 연결 부분과 관련된 사항이다.


MySQLi 접속용과 MySQL 접속용 코드가 약간 다르다는 걸 확인하고 맞게 사용해야 한다.

MySQLi

<?php
include_once 'phpclass/dbinfo.php';
$dbconn = isConnectDb($db);

function isConnectDb($db)
{
    $conn = mysqli_connect($db['host'],$db['user'],$db['pass'],$db['name'],$db['port']);
    mysqli_set_charset($conn, "utf8");  // DB설정이 잘못되어 euc-kr 로 되어 있으면 문제가 됨
    if (mysqli_connect_errno()) {
       echo "Failed to connect to MySQL: " . mysqli_connect_error();
       exit;
    } else {
      return $conn;   
    }
}
?>

 MySQL

<?php
include_once 'phpclass/dbinfo.php';
$dbconn = isConnectDb($db);

function isConnectDb($db) {
    $conn = @mysql_connect($db['host'].':'.$db['port'],$db['user'],$db['pass']);
    //Set encoding
    mysql_query("SET CHARSET utf8");
    mysql_query("SET NAMES 'utf8' COLLATE 'utf8_general_ci'");
    if(!$conn){
        die('Not connected :' . mysql_error());
        exit;
    }
    $selc = mysql_select_db($db['name'],$conn); // 접근한 계정으로 사용할 수 있는 DB 선택
    // 연결 식별자($conn) 는 생략 가능하며, 생략시 가장 최근에 설정한 연결 식별자가 사용된다.
    return $selc ? $conn : false;
}
?>


아래 두 명령의 차이점에 대해 이해하자.

MySQL

 mysql_query ("select * from tableName"); // 최근에 열려진 db conection 을 자동으로 사용
 mysql_query ("select * from tableName", $dbconn); // db connection을 지정해서 사용

 MySQLi

 mysqli_query ($dbconn, "select * from tableName"); // db connection 지정만 허용


dbconnect.php 함수를 만들었으면 이제 실제 코드상에서 사용하는 방법을 알아보자.

LoginForm.php 인 A 파일에서 입력한 데이터를 받아서 처리하는 loginChk.php 인 파일 B의 일부 로직이다.

코딩을 하면서 고려할 점은 loginChk.php 파일을 단독으로 실행했을 때 파일이 실행되어서는 안되도록 체크하는 로직을 반드시 추가해야 한다. 즉, 파일 A에서 입력된 변수가 없으면 파일 B는 동작되지 않도록 해야 한다.

파일B에서 값이 제대로 넘어왔는지 체크하는 방법은 http://link2me.tistory.com/1130 를 참조하면 도움된다.


아래 코드는 실제로 사용하는 코드다.

안드로이드에서 받은 입력값과 웹 LoginForm.php 에서 전달받은 값을 구분하여 체크하는 로직이다.

안드로이드폰/아이폰은 고유한 ID값을 가지고 있는데 이 ID값이 넘어오면 안드로이드 로그인으로 구분하도록 if문을 사용했다.

대부분 세션 스타트를 session_start(); 로만 처리하는데

if(!isset($_SESSION)) {
    session_start();
}

로 해주어야 한다. 그래야 경고 메시지가 나오지 않는다.


=== loginChk.php ====

 <?php
if(!isset($_SESSION)) {
    session_start();
}

@extract($_POST); // POST 전송으로 전달받은 값 처리
// $_POST['loginID'] 라고 쓰지 않고, $loginID 라고 써도 인식되게 하려면 extract($_POST); 를 써주면 된다.

// 변수가 존재하거나 값이 있는 경우에만 데이터 업데이트를 하도록 하는 로직
// 이 파일명으로 직접 접속하면 변수 값이 넘어오지 않으므로 실행 불가되도록 처리
if(isset($loginID) && !empty($loginID) && isset($loginPW) && !empty($loginPW)) {

   require_once $_SERVER['DOCUMENT_ROOT'].'/dbconnect.php'; // db접속
   require_once $_SERVER['DOCUMENT_ROOT'].'/loginClass.php';
   $c=new LoginClass(); // 로그인 처리 관련 함수를 모아서 작성한 클래스

   $deviceID = $deviceID ? $deviceID : '';  // 안드로이드 접속인지 PHP Web 접속인지 판단

    if(empty($deviceID)){ // 장치 값이 없으면, 즉 Web 접속이면
        $row = $c->WebUserAuthCheck($loginID,$loginPW);
        if(is_array($row)) {
            if($row['code'] > 0) {
                $_SESSION['userID'] = $row['id'];
                $_SESSION['userPW'] = md5($loginPW);
                $_SESSION['code'] = $row['code'];
                $_SESSION['ip'] = $_SERVER['REMOTE_ADDR'];
                $_SESSION['ua'] = $_SERVER['HTTP_USER_AGENT'];
                $c->AccessLog($_SESSION['userID'],''); // 접속 로그 기록

                echo("<meta http-equiv='Refresh' content='0; URL=mobile/list.php'>");
            } else {
                echo '권한 불가';
            }
        } else if($row == '0'){
            $msg ='정보가 올바르지 않습니다';
            echo "<script>alert('".$msg."');history.go(-1);</script>";
        } else {
            $msg ='정보가 올바르지 않습니다';
            echo "<script>alert('".$msg."');history.go(-1);</script>";
        }

    } else {  // 안드로이드 접속이면
        $result = $c->MobileUserAuthCheck($loginID,$loginPW,$deviceID);
        if($result > 0 ) {
            session_save_path('./_tmp/session');

            $_SESSION['userID'] = $loginID;
            $_SESSION['userPW'] = md5($loginPW);
            $_SESSION['ip'] = $_SERVER['REMOTE_ADDR'];
            $_SESSION['ua'] = $_SERVER['HTTP_USER_AGENT'];
            $c->AccessLog($loginID,$deviceID); // 접속 로그 기록

            echo 1; // 로그인 성공 결과를 1로 처리
            // 안드로이드에서는 화면출력하는 결과값으로 로그인 성공/실패 판단 처리
        } else if($result == 0) {
            echo 0; // Login Fail

        } else {
            echo -1; // Phone Dismatch

        }
    }

} else {  // 이 부분은 Web 접속 변수가 없는 경우를 처리하는 부분
    // $_POST 전송값이 없이 바로 이 파일을 실행하면 로그인 창으로 돌려보내라.
    echo("<meta http-equiv='Refresh' content='0; URL=loginForm.php'>");
}
?>


loginChk.php 파일에서 보면 WebUserAuthCheck($loginID,$loginPW) 함수를 사용한 것을 볼 수 있다. 이 함수는 loginClass.php 파일에 작성되어 있는데, loginClass.php 함수중에서 Web 로그인 체크하는 부분만 발췌했다.

사용자가 해킹을 시도할 의도가 있어도 방지하는 코드를 추가된 것을 확인할 수 있다.


==== loginClass.php =====

 <?php
class LoginClass {
    function WebUserAuthCheck($u,$p) {
        if(!isset($u) || !isset($p) || empty($u) || empty($p)) {
            return 0;
        } else {
            global $dbconn; // global 키워드를 사용하여 변수에 선언할 경우 함수 밖의 변수를 참조할 수 있다
            $u = preg_replace("/[\s\t\'\;\"\=\--]+/","", $u); // 공백이나 탭 제거(사용자 실수 방지)
            $p = preg_replace("/[\s\t\'\;\"\=\--]+/","", $p); // 공백이나 탭 제거, 특수문자 제거
            // SQL injection 검사
            $u = mysqli_real_escape_string($dbconn,$u); // <script>documnet.cookie();</script> 공격 방지
            $p =
mysqli_real_escape_string($dbconn,$p); //
            if(preg_match('/[\/\\\\]/', $u)) $this->popup('비정상적 접근입니다'); // no slashes
            //if(preg_match('/(and|null|where|limit)/i', $u)) { // i는 대소문자 구별하지 말라
            //    $this->popup('비정상적 접근입니다');
            //} // 회원아이디가 일치하는 경우가 생겨서 이 구문은 사용을 자제해야 할 듯해서 주석처리함.
            if(!preg_match('/^[0-9a-zA-Z\~\!\@\#\$\%\^\&\*\(\)]{7,}$/',$p)) { // 최소7자리 이상 허용 문자만 통과
                $this->popup('정보가 올바르지 않습니다');
                // 같은 클래스안에 있는 다른 함수를 사용할 때 $this 로 기술
            }

            $sql = "select code, id ";
            $sql.= "from member where pw=md5('".$p."') and id= '".$u."' ";
            if($result = mysql_query($sql,$dbconn)) { //성공
                $row = mysql_fetch_array($result);
                if($row == NULL) return 0;
                return $row;
            } else {
                return '-1';
            }
        }
    }

    // 로그인함수 경고메시지
    function popup($msg) {
        echo "<script>alert('".$msg."');history.go(-1);</script>";
    }
} // End of LoginClass
?>


위 SQL 인젝션 방지 코드가 완벽하지 않을 수도 있다.

정규식 예제 : https://link2me.tistory.com/1489 를 참조하면 조금 더 도움될 것으로 본다.

그리고 구글링으로 PHP 정규식 을 검색해서 코드를 완벽하게 보완하면 좋을 것이다.



첨부파일 (db 연결함수)

dbconn.ZIP


본 첨부파일은 초보자 분들이 타이핑 하면서 실수하지 않게 제공하는 것입니다.

블로그내 다른 소스를 복사해서 활용하고 싶다면 c browser 를 검색해서 설치하고 사용하면 됩니다.

도움되셨다면 댓글이나 공감 부탁드립니다.



추가 작성 : 2016-11-23일자 (네이버지식인 답변시 추가)

DB를 연결하는 방법만 언급하다보니 함수화하는 것과 연결고리를 잘 모르는 분을 위해서 적어본다.

통계처리용으로 만는 함수다. 함수화를 해두면 나중에 추가할 사항이 있으면 함수만 추가하면 된다.

MySQLi 를 사용하는 환경이면 사용자 함수도 MySQLi 기반으로 수정해주면 된다.


=== statClass.php ===


이런 함수를 호출해서 사용하는 방법은 간단하다.

<?php

require_once "statsClass.php";
$s=new StatsClass(); // 객체 생성(인스턴스화)
$row = $s->today_statsCount(); // 배열이므로 배열로 받아서

?>

<?php echo '개인별(오늘/어제) : '.$row[0].'/'.$yes[0];?></th>


도움이 되셨다면 00 해 주세요. 좋은 글 작성에 큰 힘이 됩니다.


728x90
블로그 이미지

Link2Me

,

내 Web Site에 로그인한 접속자의 통계를 구해보자.


접속자의 정보를 테이블에 기록하는 로직을 그려본다.

1. 로그인한 ID 정보를 기록한다.

2. 접속자의 IP 주소 정보를 구한다.

   $ip = $_SERVER[REMOTE_ADDR];    //방문자 IP저장

3. 오늘 날짜와 시간을 저장한다.

4. OS 정보를 추출하여 저장한다.

    - Web 브라우저에서 접속한 경우에는 $_SERVER['HTTP_USER_AGENT'] 에서 정보를 추출할 수 있다.

    - Android App, iOS App 에서 접속하는 경우에는 DeviceID를 가지고 식별하게 코드를 추가하면 된다.

5. 동일한 ID에 대해 하루에 한번만 저장할 것인가?

    접속할 때마다 기록할 것인가를 정한다.

    접속할 때마다 기록하면 테이블에 저장되는 Record 수가 많아진다.

    이 경우에는 매일 일정한 시간주기로 Raw Data 를 가지고 일단위 통계, 주간단위 통계, 월단위 통계를 만들고

    2개월이 넘어간 데이터는 삭제하는 방법등을 고려하는 것이 좋다.

    데이터 저장이 너무 많아지는 경우에는 테이블 설계시 partition 까지 고려하는 것이 좋을 수 있다.

6. Index 는 어떤 걸 자주 검색하게 될 것인가를 고려해서 설정한다.

7. 통계 생성을 고려한다면 테이블에 저장되는 값을 숫자로 표시되게 하는 걸 같이 고려한다.

8. 접속자의 접속정보를 테이블에 추가(Insert)한다.



1. 테이블 구조

CREATE TABLE IF NOT EXISTS AccessLog (
  uid int(11) NOT NULL AUTO_INCREMENT,
  ipaddr varchar(20) NOT NULL,
  date char(8) NOT NULL DEFAULT '',
  time varchar(10) NOT NULL,
  OS varchar(60) DEFAULT NULL,
  browser varchar(30) DEFAULT NULL,
  userID varchar(60) DEFAULT NULL,
  hit int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (uid),
  KEY ipaddr (ipaddr)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;


2. phpClass 함수

관련 모든 함수는 첨부파일 참조

AccessClass.zip


조건기준 : IP주소와 오늘날짜를 기준으로 카운트

만약 userID 기준으로 접속기록을 남기려면 where 조건문을 수정해주면 된다.


function AccessLog($userID){
    // 테이블 구조 : uid, ipaddr, date, time, OS, browser, userID, hit
    global $db;
    $access_ip=$_SERVER['REMOTE_ADDR'];
    $getOS = $this->getOS(); // 접속 OS 정보
    $getBrowser = $this->getBrowser(); // 브라우저 접속 정보
    $date = date("Ymd"); // 오늘날짜
    $time = date("H:i:s"); // 시간
    $userID = $userID ? $userID : '';
    $sql ="select count(*) from rb_accessLog where ipaddr='".$access_ip."' and date='".$date."'";
    $result=mysql_query($sql);
    if($row=mysql_fetch_row($result)){
        if($row[0] == 0){ // 오늘 접속날짜 기록이 없으면
            $sql = "INSERT INTO rb_accessLog (ipaddr,date,time,OS,browser,userID,hit) ";
            $sql.= "VALUES ('$access_ip','$date','$time','$getOS','$getBrowser','$userID','1');";
            $result=mysql_query($sql);
        } else { // 접속 기록이 있으면 해당 IP주소의 카운트만 증가시켜라.
            $sql = "UPDATE rb_accessLog SET hit=hit+1 Where ipaddr='".$access_ip."'";
            $result=mysql_query($sql);
        }
    }
}


3. 사용법

로그인 정보를 검사하여 로그인이 성공(ID, PW 일치)하면 1, 실패하면 0 을 반환한다.

성공할 경우 SESSION 을 생성하고 접속 로그를 기록한다.


<?php
if(isset($_POST['loginID']) && !empty($_POST['loginID']) && isset($_POST['loginPW']) && !empty($_POST['loginPW'])) {
    $loginID = trim($_POST['loginID']);
    $loginPW = trim($_POST['loginPW']);

    require_once 'dbconnect.php'; // db접속
    require_once 'phpclass/AccessClass.php';
    require_once 'phpclass/loginClass.php';

    $a=new AccessClass();
    $c=new LoginClass();

    $row = $c->UserAuthCheck($loginID,$loginPW); // 성공(1), 실패(0)
    if($row == 1) {
        $_SESSION['userID'] = $row['id'];
        $_SESSION['userPW'] = md5($loginPW);
        $a->AccessLog($_SESSION['userID']); // 접속 로그 기록
    } else {
        $msg ='정보가 올바르지 않습니다';
        echo "<script>alert('".$msg."');history.go(-1);</script>";
    }
}

?>


728x90
블로그 이미지

Link2Me

,

<th>
<select id="searchName" name="searchName">
    <option value=''>구분</option>
    <option value="userNM">성명</option>
    <option value="userID">아이디</option>
</select>
<input type="text" id="searchValue" name="searchValue">
<span class="spanBtn" id="SearchBtn">검 색</span>           
</th>


위와 같은 option 값을 변경하는 jQuery

// 지정된 index 값으로 select 하기

$('#searchName option:eq(2)').prop('selected', true); // option 3번째 선택

또는 value값을 직접 적어주는 방법도 가능하다.

$('#searchName option[value=userID]').prop('selected', 'selected').change();


$('#searchValue').val(ID); // searchValue 값을 ID로 자동 입력


// 초기화 처리

$('#searchName option:eq(0)').attr('selected','selected');
$('#searchValue').val('');


// 선택된 값 읽기

$("select[name=searchName]").val();

$("#searchName option:selected").val();


// 선택된 내용(text) 읽어오기

$("#searchName option:selected").text(); // 선택된 text 읽어오기

$("select[name=searchName]").text(); // 이건 원하는 결과가 나오지 않더라.



var ID=$(this).children('.gc').eq(6).text(); // 테이블에서 선택 행의 td 태그의 값을 가져오라

<td class="gc">행복</td>


// 선택된 위치 index

var index = $("#searchName option").index($("#searchName option:selected"));


728x90
블로그 이미지

Link2Me

,

AES 암호화 방식으로 암호화하는 예제이다.


1. AESCrypt Class 를 선언해준다. Class 명칭은 본인 스타일에 맞게 수정한다.


class AESCrypt {
    function encrypt($plain_text){
        global $key, $iv;
        // AES 암호화 기법은 평문을 128비트 단위로 나누어 암호화, 복호화를 수행
        // 각각의 128비트를 4x4 행렬로 표현하여 연산을 수행함
        // 사용하는 암호화 키의 길이는 128, 192, 256비트 중 하나를 선택할 수 있음
        // CBC(Cipher Block Chaining) Mode : 블록 암호화 운영 모드 중 보안 성이 제일 높은 암호화 방법으로 가장 많이 사용
        // 평문의 각 블록은 XOR연산을 통해 이전 암호문과 연산되고 첫번째 암호문에 대해서는 IV(Initial Vector)가 암호문 대신 사용
        // IV (initialization vector)는 제 2의 키가 될 수 있으며, 길이는 16bits
        $encryptedMessage = openssl_encrypt($plain_text, "aes-256-cbc", $key, true, $iv);
        return base64_encode($encryptedMessage);
    }

    function decrypt($base64_text){
        global $key, $iv;
        $decryptedMessage = openssl_decrypt(base64_decode($base64_text), "aes-256-cbc", $key, true, $iv);
        return $decryptedMessage;
    }

}//end class



2. AES 사용법

class.crypto.php 파일안에다 AESCrypt Class 를 선언했다.


<?php
    include 'phpclass/class.crypto.php';
    $crypto = new Crypto(); // 암호화 객체 생성
    $text ='암호화할 문장을 여기에 적어주시면 됩니다.';
    $enc = $crypto->encrypt($text);
    echo $enc.'<br /> 원문 길이 : '.strlen($text).'  암호화 길이 : '.strlen($enc).'<br />';
    $dec = $crypto->decrypt($enc);
    echo $dec.'<br /><br />';

    $aescrypt = new AESCrypt();
    $key = "key996rfy7ja6ng7gisu8kim55s";
    $iv = "f781576ae8dfe846";
    $enc = $aescrypt->encrypt($text);
    echo $enc.'<br /> 원문 길이 : '.strlen($text).'  암호화 길이 : '.strlen($enc).'<br />';
    $dec = $aescrypt->decrypt($enc);
    echo $dec;
   
?>


3. 결과

최대 길이는 SEED 와 AES 모두 입력되는 길이에 비례하여 길어진다.


SEED 결과

48cdef6c9738608cbbfb30965e1c665904a214ef99a0dc20ebf6cf6592de45aaf9eeb48106628db5b3747122251d16145cd9a0f17afc6857623891ff4882864e
원문 길이 : 59 암호화 길이 : 128
암호화할 문장을 여기에 적어주시면 됩니다.


AES 결과
lcFPY8OXrCHTUFNaz7PeQ+xzYMsxxw2SDFD1aR8nb3QNa7z6ELfxuhNjIVg/j/5tyWN13StkGwZoL0TARI9vwA==
원문 길이 : 59 암호화 길이 : 88
암호화할 문장을 여기에 적어주시면 됩니다.


4. 비고

테스트를 해보니 AES 암호화는 key 길이가 32비트까지 인식 하는 거 같다.





728x90
블로그 이미지

Link2Me

,