728x90

PHP 에서 MySQL 을 접속하고 DB 작업을 편리하게 하는 함수이다.

킴스큐 RB 빌더는 DB 접속 등 함수화를 해서 편하게 코딩하게 만들었다.

하지만 아쉬운 점은 Class 화를 하지 않아서 좀 불편한 면이 있다.

아래 Class 는 나의 사용 환경에 맞게 변경하거나 신규 기능을 추가하여 사용하고 있다.

본인만의 함수를 만들면 코딩이 간단해지고 직관적으로 이해할 수 있다.


MySQL 접속 환경이 MySQL 인가? MySQLi 인가? 에 따라 함수를 선택해서 사용하면 된다.


함수 사용법

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

include_once $_SERVER['DOCUMENT_ROOT'].'/db.info.php';
require_once $_SERVER['DOCUMENT_ROOT'].'/phpclass/dbClass.php';
$conn=new MySQLDbClass();
$DB_CONNECT = $conn->isConnectDb($DB);


===== db.info.php ===== 파일에는 접속 정보가 들어가 있다.

<?php
$DB['host'] = "localhost";
$DB['name'] = "DB명";
$DB['user'] = "DB접속ID";
$DB['pass'] = "DB패스워드";
$DB['port'] = "3306";
$DB['type'] = "MyISAM";
?>


===== dbClass.php ======

<?php
class MySQLDbClass {

    function isConnectDb($db) {
        $conn = mysql_connect($db['host'].':'.$db['port'],$db['user'],$db['pass']);

        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;
    }

    //DB-UID데이터
    function getUidData($table,$uid){
        return $this->getDbData($table,'uid='.(int)$uid,'*');
    }

    // DB Query Cutom 함수
    function getDbData($table,$where,$column){
        global $DB_CONNECT;
        $result = mysql_query('select '.$column.' from '.$table.($where?' where '.$this->getSqlFilter($where):''));
        $row = mysql_fetch_array($result);
        return $row;
    }

    // DB Query result 함수
    function getDbresult($table,$where,$column){
        global $DB_CONNECT;
        $result = mysql_query('select '.$column.' from '.$table.($where?' where '.$this->getSqlFilter($where):''));
        return $result;
    }

    //DB데이터 필드 개수
    function getDbColums($table,$where,$column){
        global $DB_CONNECT;
        $result = mysql_query('select '.$column.' from '.$table.($where?' where '.$this->getSqlFilter($where):''));
        return mysql_num_fields($result);
    }

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

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

    //DB select
    function getDbSelect($table,$where,$column){
        global $DB_CONNECT;
        $row = mysql_query('select '.$column.' from '.$table.($where?' where '.$this->getSqlFilter($where):''),$DB_CONNECT);
        return $row;
    }

    //DB삽입
    function getDbInsert($table,$key,$val){
        global $DB_CONNECT;
        mysql_query("insert into ".$table." (".$key.")values(".$val.")");
    }

    //DB업데이트
    function getDbUpdate($table,$set,$where){
        global $DB_CONNECT;
        mysql_query('set names utf8');
        mysql_query('set sql_mode=\'\'');
        mysql_query("update ".$table." set ".$set.($where?' where '.$this->getSqlFilter($where):''));
    }

    //DB삭제
    function getDbDelete($table,$where){
        global $DB_CONNECT;
        mysql_query("delete from ".$table.($where?' where '.$this->getSqlFilter($where):''),$DB_CONNECT);
    }

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

}//end dbClass

class MySQLiDbClass {
    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()) {
           printf("Connect failed: %s\n", mysqli_connect_error());
           exit();
        } else {
          return $conn;   
        }
    } // */

    //DB-UID데이터
    function getUidData($table,$uid)
    {
        return $this->getDbData($table,'uid='.(int)$uid,'*');
    }

    // DB Query Cutom 함수
    function getDbData($table,$where,$column) {
        global $DB_CONNECT;
        $result = mysqli_query('select '.$column.' from '.$table.($where?' where '.$this->getSqlFilter($where):''));
        $row = mysqli_fetch_array($result);
        return $row;
    }

    // DB Query result 함수
    function getDbresult($table,$where,$column) {
        global $DB_CONNECT;
        $result = mysqli_query('select '.$column.' from '.$table.($where?' where '.$this->getSqlFilter($where):''));
        return $result;
    }

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

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

    //DB삽입
    function getDbInsert($table,$key,$val){
        global $DB_CONNECT;
        mysqli_query("insert into ".$table." (".$key.")values(".$val.")");
    }

    //DB업데이트
    function getDbUpdate($table,$set,$where){
        global $DB_CONNECT;
        mysqli_query('set names utf8');
        mysqli_query('set sql_mode=\'\'');
        mysqli_query("update ".$table." set ".$set.($where?' where '.$this->getSqlFilter($where):''));
    }

    //DB삭제
    function getDbDelete($table,$where)    {
        global $DB_CONNECT;
        mysqli_query("delete from ".$table.($where?' where '.$this->getSqlFilter($where):''),$DB_CONNECT);
    }

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

}//end dbClass

?>

728x90
블로그 이미지

Link2Me

,
728x90

ajax 에 대한 기본 개념이 잘 설명된 곳은 https://www.w3schools.com/jquery/jquery_ajax_intro.asp 다.

ajax 의 강력한 특징은 페이지 전체를 refresh 하지 않고서도 수행되는 비동기성이다. 이러한 비동기성을 통해 사용자의 Event가 있으면 전체 페이지가 아닌 일부분만을 업데이트 할 수 있게 해준다.


jQuery ajax 의 다른 형태로 .get 또는 .post 처리가 가능하다.

형태가 심플하여 더 편할 수 있다. 아래 코드는 100% 동작하는 걸 확인하고 적어둔다.

대부분 자료들이 대략적인 컨셉만 적혀있고 참고로 사용할만한 샘플이 없는 거 같아서 적었다.

나와 같은 초보자들은 제대로 동작하는 샘플이 있어야만 그 다음에 응용 또는 활용이 가능하다.


$.get()함수, $.post() 함수는 url, url 파라미터, 요청의 성공시 응답을 받기 위한 콜백함수가 있다.

$.post(url, {userID:input_value}, function(data) {

     // 통신이 성공했을 때 실행하는 함수

}, 'json');


url 파라미터는 key 와 value 쌍으로 구성된다. 파라미터가 여러개이면 콤마로 구분한다.


===== idCheck.php ====

<!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" /> <!--브라우저 호환성 설정 -->
<title>ID Join Check</title>
<!-- 모바일 웹 페이지 설정 -->
<link rel="shortcut icon" href="img/icon.png" />
<link rel="apple-touch-icon" href="img/icon.png" />
<!-- 모바일 웹 페이지 설정 끝 -->

<link rel="stylesheet" type="text/css" href="css/common.css"/>
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<script type="text/javascript" src="js/idCheck.js"></script>
</head>
<body>
    <h1 class="title">아이디 중복검사</h1>
    <div class="exec">
        <form>
            <input type="text" name="userID" />
            <input type="button" id="checkid" value="중복검사" />
        </form>
    </div>
    <div class="console"></div>
</body>
</html>


===== idCheck.js =====

$(function(){
    $("#checkid").click(function(e) {

        e.preventDefault(); // a 링크, form submit 실행 방지

        var input_value = $("input[name='userID']").val();
       
        // 입력 여부 검사
        if(!input_value) {
            alert("아이디를 입력하세요");
            $("input[name='userID']").focus();
            return false;
        }

        var url = 'idCheck_ok.php';
        $.post(url, {userID:input_value}, function(msg) {
            if (msg.result==1) { // idCheck_ok.php 의 결과값
                $(".console").html("<span style='color:blue'>사용할 수 있는 아이디 입니다.</span>");

                // alert('사용할 수 있는 아이디 입니다.'); 로 대신해도 된다.

            } else {
                $(".console").html("<span style='color:red'>사용할 수 없는 아이디 입니다.</span>");

                // alert('사용할 수 없는 아이디 입니다.'); 로 대신해도 된다.

                // 이 경우에는 $("input[name='userID']").val(''); 로 입력값을 초기화해도 좋다.

            }
        },'json');
       
    });
});



https://link2me.tistory.com/954 참조하면 javascript 로 Form 제어하는 개념을 이해할 수 있다.

위의 예제에는 form method, action 을 생략해서 원하는 결과를 얻지 못할 수 있다.

form method를 생략하면 GET방식으로 동작된다.

form action 을 추가하고 동작할 경우에는 반드시 e.preventDefault(); // a 링크, form submit 실행 방지

를 추가해줘야 제대로 원하는 결과를 얻을 수 있다.


===== idCheck_ok.php ====

# PHP 기본 개념 이해는 http://link2me.tistory.com/1110 게시글을 참조하시라.

# ajax 를 이용하면 파일 A --> 파일 B로 이동하지 않고 결과를 얻을  수 있다.

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

    require_once $_SERVER['DOCUMENT_ROOT'].'/dbconnect.php'; // db접속 성공
    require_once $_SERVER['DOCUMENT_ROOT'].'/phpclass/loginClass.php';

    $c=new LoginClass();
    $rs = $c->UserIDJoinCheck($userID);
    if($rs == '0') {
        echo '{"result":"1"}';
    } else {
        echo '{"result":"0"}';
    }
}
?>

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

<?php
class LoginClass {
    function UserIDJoinCheck($userID) {
        if(!isset($userID) || empty($userID)) {
            return '-1';
        } else {
            global $db;           
            $userID = preg_replace("/[\s\t]+/","", $userID); // 공백이나 탭 제거(사용자 실수 방지)

            $sql = "select id, count(id) ";
            $sql.= "from rb_s_mbrid where id= '".$userID."' ";
            if($result = mysqli_query($db,$sql)) { //성공
                $row = mysqli_fetch_row($result);
                if($row[1] == '0') return 0;
                return $row[1];
            } else {
                return '-1';
            }
        }
    }

}//end class LoginClass

?>


===== 테이블 구조 =====

CREATE TABLE IF NOT EXISTS `rb_s_mbrid` (
  `uid` int(11) NOT NULL AUTO_INCREMENT,
  `site` int(11) NOT NULL DEFAULT '0',
  `id` varchar(50) NOT NULL DEFAULT '',
  `pw` varchar(50) NOT NULL DEFAULT '',
  `code` int(6) NOT NULL DEFAULT '0',
  PRIMARY KEY (`uid`),
  KEY `site` (`site`),
  KEY `id` (`id`),
  KEY `code` (`code`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

도움되셨다면 공감 또는 ... 눌러주세요.

728x90
블로그 이미지

Link2Me

,
728x90
PHP 로 파싱하는 것은 아직 안해봤다. PHP 로 파싱하는 걸 알면 여러모로 편리할 거 같기는 하다.

다른 Web 사이트에 있는 정보를 가져와서 재가공 해야 하는 경우에 Snoopy.class.php 를 활용하면 된다.


Snoopy 클래스 다운로드 http://sourceforge.net/projects/snoopy/files/latest/download


네이버지식인 답변에 올라온 것을 적어둔다.

답변자 출처 : http://dolgo.net/php/questions/85

<?php
include_once 'snoopy/Snoopy.class.php';
$snoopy = new Snoopy;
$getUrl = "http://www.645lotto.net/lotto645Confirm.do?method=byWin&drwNo=710";
$snoopy->fetch($getUrl);
$pattern='/img src="\/img\/common\/ball_(.*?).png/';
preg_match_all($pattern,$snoopy->results,$out); 
for($i=0;$i<=6;$i++){
    echo $out[1][$i]."\n";
}
?>


분석

- $snoopy = new Snoopy; // Class화된 PHP는 객체 생성을 해야 함

- 확장자를 do를 사용하는 것은 PHP 인지 JSP 인지 식별할 수 없게 하기 위함이다.

- 로또번호 회차 표시부분을 수정하면 매번 다르게 보일 것이다.

- fetch($getUrl) : 입력받은 주소의 html소스를 텍스트 형식으로 $results에 저장

- fetchlinks($URI) : fetch와 비슷하지만 링크만을 배열의 형태로 $results에 저장

- fetchtext($URI) : fetch와 비슷하지만 스크립트를 제외한 텍스트만 $results에 저장

- fetchform($URI) : fetch와 비슷하지만 폼 부분을 html형식으로 $results에 저장

- submit($URI, $formvars="", $formfiles="") : 폼에 여러 변수를 붙여서 전송 가능

- setcookies() : 종종 쿠키정보를 유지해야하는 경우가 있을 때 사용

- preg_match 정규식을 사용해서 이제 본문 필요 요소만을 추출



728x90

'Web 프로그램 > JSON, 파싱 다루기' 카테고리의 다른 글

Parse JSON with PHP (JSON 파싱)  (2) 2017.11.27
PHP Array 활용 JSON  (0) 2017.05.11
[PHP] MySQL Data to JSON using PHP  (0) 2016.12.22
XML 데이터 생성 처리  (0) 2016.06.06
PHP 와 XML 연동처리  (0) 2016.06.04
블로그 이미지

Link2Me

,
728x90

// DB Query Cutom 함수
function getDbData($table,$where,$data,$orderby){
    global $db;
    $result = mysql_query('select '.$data.' from '.$table.($where?' where '.getSqlFilter($where):'').($orderby?' order by '.getSqlFilter($orderby):''));
    $row = mysql_fetch_array($result);
    return $row;
}

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


함수를 만들어서 사용할 경우 제대로 잘 만들어졌는지 테스트 하는 과정은 아래과정으로 진행했다.

sql 쿼리문을 화면상에 나오게 하여 제대로 나왔는지 확인했다.


<?php
$table ='MEMBER';
$part1CD='04';
$part2CD='23';
$part3CD='00';
$partNM = '기타';
$where ="part1CD='".$part1CD."' and part2CD='".$part2CD."' and part4CD='00' and partNM='".$partNM."'";
$data ='*';
$orderby = 'idx DESC';
//$orderby = '';

$sql = 'select '.$data.' from '.$table.($where?' where '.getSqlFilter($where):'').($orderby?' order by '.getSqlFilter($orderby):'');
echo $sql;

function getSqlFilter($sql)
{
    return $sql;
    // preg_replace("/찾을 문자열/" , "변경할 문자열" , "해당 문자열");
    // /찾을 문자열/ 에서 / 는 정규식의 시작과 끝을 알린다.
    //return preg_replace("( union| update| insert| delete| drop|\/\*|\*\/|\\\|\;)",'',$sql);
}

?>

728x90
블로그 이미지

Link2Me

,
728x90

파일을 업로드하는 코딩시 고려할 사항이다.


파일을 업로드시에 공격이 성공하면 바로 서버가 해킹되는 것이기 때문에 가장 리스크가 큰 취약점이다.

보안(Security)을 고려하고 실행파일이 업로드되지 않도록 해야 한다.

먼저, 파일 업로드 기능이 있는 페이지를 전부 조사해서 WebShell 같은 악의적인 파일이 업로드될 수 있는지 체크해야 한다.


1. 파일 업로드시 확장자 검사 루틴

    - 기본적으로는 Apache 환경설정에서 mine type 필터링을 설정한다.

      Apache 환경설정 http://link2me.tistory.com/426  http://link2me.tistory.com/991 참조

    <IfModule mime_module>
        TypesConfig conf/mime.types
        AddType application/x-compress .Z
        AddType application/x-gzip .gz .tgz
        AddType application/x-httpd-php .php .html
        AddType application/x-httpd-php-source .phps
    </IfModule>


   - 하지만 공격자가 Proxy-Server 등을 통해 우회할 수 있으므로 확장자 필터링을 적용한다.

     업로드가 허용된 확장자만 업로드가 가능하도록 서버 필터링을 하여야 한다.

 

2. 파일명은 치환(난수화)해서 저장한다.
    그리고 파일 접근권한을 읽기 전용모드로 등록한다. (실행권한 부여 금지)


3. 등록시 변경 파일명을 DB에 저장한다.

    - 게시판에 첨부되는 파일명인 경우, 변경 파일명을 DB 테이블에 기록하여 찾을 수 있도록 한다.


4. 가능하면 파일 업로드 장소를 물리적으로 분리한다.

    물리적으로 분리하지 않은 경우라면 해당 디렉토리가 어디인지 알수 없게 다른 곳으로 지정한다.


파일 업로드시 제한 용량은 php.ini 파일에 설정되어 있다.

업로드 용량을 많이 설정하려면 php.ini 파일을 수정하고 Apache 를 restart 해야 한다.

; PHP 가 받아들이는 POST data 최대 크기
; default 8M 로 되어 있음, upload_max_filesize 보다 크게 설정해야 함
post_max_size = 20M
memory_limit = 128M
upload_max_filesize = 19M


// 테이블 구조 예시

CREATE TABLE IF NOT EXISTS file_upload (
  uid int(11) NOT NULL AUTO_INCREMENT,
  folder varchar(10) NOT NULL DEFAULT '',
  name varchar(250) NOT NULL DEFAULT '',
  size int(11) NOT NULL DEFAULT '0',
  d_regis varchar(14) NOT NULL DEFAULT '',
  PRIMARY KEY (uid),
  KEY d_regis (d_regis)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;


//파일을 전송하는 PHP 소스 부분

파일명을 excel 로 사용했으면 받는 쪽에서도 excel 로 사용해야 한다.

보통은 userfile 이라고 많이 쓴다.

<form enctype="multipart/form-data" action="fileupload.php" method="POST">
 <input 
type="file" name="excel"  />

 <input type="submit" value="upload" />
</form>



// 파일을 전송받은 PHP 소스 부분

여러개의 확장자를 검사하려면 strstr('[csv]',$fileExt) 부분을 수정하면 된다.

strstr('[csv,php,html,htm,inc,do]',$fileExt) 와 같이 확장자 여러개를 나열해준다.


<?php
    // Edit upload location here
    $tmpname    = $_FILES['excel']['tmp_name'];
    $realname    = $_FILES['excel']['name'];
    $fileExt    = getExt($realname);  // 확장자 필터링을 위한 확장자 추출
    $destination_path='uploads/';
    $rndname = hash('sha256', $realname).date("Ymd").'.'.$fileExt;  // 파일명 hash 처리
    $readFile = $destination_path . $rndname;

    if (is_uploaded_file($tmpname)) {
        if (!strstr('[csv]',$fileExt)) {  // 확장자 필터링 검사
            echo '<script type="text/javascript">alert("csv 파일만 등록할 수 있습니다.");</script>';
            exit;
        }
        move_uploaded_file($tmpname,$readFile);
        @chmod($readFile,0404);  // 파일 권한을 읽기모드로 설정

    }

    function getExt($filename){
        $ext = substr(strrchr($filename,"."),1); // 뒤에서부터 콤마 위치로부터 가져오기
        $ext = strtolower($ext); // 소문자로 강제치환
        return $ext;
    }

    ?>



아래 코드는 업로드시 파일명을 치환하는 연습 코드이다.


<?php
//$realname = strtolower($_FILES['excel']['name']);
$realname = 'shell.asp;.jpg';
$fileExt = getExt($realname);
//$tmpname = md5($realname).date("Ymd").'.'.$fileExt;
$tmpname = hash('sha256', $realname).date("Ymd").'.'.$fileExt;

echo $tmpname;
echo '<br />';
echo strlen($tmpname);

function getExt($filename){
    $ext = substr(strrchr($filename,"."),1); // 뒤에서부터 콤마 위치로부터 가져오기
    $ext = strtolower($ext); // 소문자로 강제치환
    return $ext;
}

?>


파일을 2개 업로드하는 걸 고려한다면

<form enctype="multipart/form-data" action="fileupload.php" method="POST">

이미지 파일1 <input type="file" name="imagefile[]">

이미지 파일2 <input type="file" name="imagefile[]">

<input type="submit" value="upload" />

</form>


fileupload.php 에서 확인해 볼 사항

echo '<pre>', print_r($_FILES) ,"</pre>";

$_FILES['imagefile']['name'][0];

$_FILES['imagefile']['name'][1];

$_FILES['imagefile']['type'][0];

$_FILES['imagefile']['type'][1];

$_FILES['imagefile']['tmp_name'][0];

$_FILES['imagefile']['tmp_name'][1];

$_FILES['imagefile']['size'][0];

$_FILES['imagefile']['size'][1];

$_FILES['imagefile']['error'][0];

$_FILES['imagefile']['error'][1];


참조하면 도움되는 게시글

http://blog.habonyphp.com/entry/php-POST-%ED%8C%8C%EC%9D%BC-%EC%97%85%EB%A1%9C%EB%93%9C#.V5RntaKzHpU


jQuery PHP 파일 업로드 게시글 : http://link2me.tistory.com/1142


Ajax PHP 파일 업로드 게시글 : http://link2me.tistory.com/1143

728x90
블로그 이미지

Link2Me

,
728x90

서버가 CentOS7 환경이라면 https://link2me.tistory.com/1842 를 참고해야 한다.


웹파일 형식으로 내보내기를 하면 속도가 짱 빠르기 때문에 사용하는데 문제가 없다.

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

$file_name = "xxx_code.xls";
header( "Content-type: application/vnd.ms-excel; charset=utf-8");
header( "Cache-Control: must-revalidate, post-check=0,pre-check=0" );
header( "Content-Disposition: attachment; filename=$file_name" );
header( "Content-Description: PHP4 Generated Data" );


error_reporting(E_ALL ^ E_NOTICE);

include_once 'db.info.php';
include_once 'function/db.mysql.func.php';
$DB_CONNECT = isConnectDb($DB);


?>


윈도우10 환경하에서 인식이 제대로 안되는 현상이 생겨서 이번 기회에 엑셀 파일로 직접 저장하는 법을 찾아봤다.

엑셀로 저장하면 일단 속도가 많이 느리다.


https://github.com/PHPOffice/PHPExcel 에서 파일을 다운로드한다.

다운로드 한 파일을 압축을 풀어서 서버에 업로드한다.


아래 코드처럼 작성하면 된다.


<?php
if(!isset($_SESSION)) {
    session_start();
}
if(!empty($_SESSION['userID'])){
    echo "<script>window.top.location.replace('/index.php');</script>";
    exit;
}

$fname="xxx_code";  // 저장할 파일명
// 파일의 저장형식이 utf-8일 경우 한글파일 이름은 깨지므로 euc-kr로 변환해준다.
//$fname = iconv("UTF-8", "EUC-KR", "한글이름");

require_once "dbconnect.php";
require_once 'phpclass/PHPExcel.php';

$objPHPExcel = new PHPExcel();
$objPHPExcel->setActiveSheetIndex(0); //set first sheet as active

$objSheet = $objPHPExcel->getActiveSheet();
$objSheet->setTitle('코드');
$objSheet->getCell('A1')->setValue('코드');
$objSheet->getDefaultStyle('A1')->getFont()->setName('맑은 고딕');
$objSheet->mergeCells('A1:M1'); // 셀 병합
$objSheet->getStyle('A1')->getFont()->setSize(16); // 셀의 textsize

$objPHPExcel->getDefaultStyle()->getFont()->setSize(12); // 폰트 사이즈
$objSheet->SetCellValue('A2', "NO");
$objSheet->mergeCells('A2:A3'); // 셀 병합
$objSheet->SetCellValue('B2', "부서");
$objSheet->mergeCells('B2:E2');
$objSheet->SetCellValue('F2', "순서");
$objSheet->mergeCells('F2:I2');
$objSheet->SetCellValue('J2', "코드");
$objSheet->mergeCells('J2:M2');

$objSheet->SetCellValue('B3', "부서1");
$objSheet->SetCellValue('C3', "부서2");
$objSheet->SetCellValue('D3', "부서3");
$objSheet->SetCellValue('E3', "부서4");

$objSheet->SetCellValue('F3', "계위1");
$objSheet->SetCellValue('G3', "계위2");
$objSheet->SetCellValue('H3', "계위3");
$objSheet->SetCellValue('I3', "계위4");

$objSheet->SetCellValue('J3', "계위1");
$objSheet->SetCellValue('K3', "계위2");
$objSheet->SetCellValue('L3', "계위3");
$objSheet->SetCellValue('M3', "계위4");

cellColor('A2:M3', 'F28A8C'); // 헤더 배경색 지정

$i=4; // 값을 기록할 셀의 시작위치
$rowCount = 1; // 넘버링

$sql="select * from tablename where 조건";
$result=mysql_query($sql);
while($row=mysql_fetch_row($result)){


    $objSheet->SetCellValue('A'.$i, $rowCount);
    $objSheet->SetCellValue('B'.$i, $row[0]);
    $objSheet->SetCellValue('C'.$i, $row[1]);
    $objSheet->SetCellValue('D'.$i, $row[2]);
    $objSheet->SetCellValue('E'.$i, $row[3]);

    $objSheet->SetCellValue('F'.$i, $row[4]);
    $objSheet->SetCellValue('G'.$i, $row[5]);
    $objSheet->SetCellValue('H'.$i, $row[6]);
    $objSheet->SetCellValue('I'.$i, $row[7]);

    $objSheet->SetCellValue('J'.$i, $row[8]);
    $objSheet->SetCellValue('K'.$i, $row[9]);
    $objSheet->SetCellValue('L'.$i, $row[10]);
    $objSheet->SetCellValue('M'.$i, $row[11]);

    $i++;
    $rowCount++;
}

// 표 그리기
$i--;
$objSheet->getStyle('A2:M'.$i)->getBorders()->getAllBorders()->setBorderStyle(PHPExcel_Style_Border::BORDER_THIN);

// 헤더 칼럼 가운데 정렬
$objSheet->getStyle('A2:M'.$i)->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_CENTER);

// 셀 높이
$objSheet->getRowDimension(1)->setRowHeight(20);

// 칼럼 사이즈 자동 조정
$objSheet->getColumnDimension('A')->setAutoSize(true);
$objSheet->getColumnDimension('B')->setWidth(18);  // 칼럼 크기 직접 지정
$objSheet->getColumnDimension('C')->setWidth(18);
$objSheet->getColumnDimension('D')->setWidth(18);
$objSheet->getColumnDimension('E')->setWidth(18);

// 파일 PC로 다운로드
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment;filename='.$fname.'.xlsx');
header('Cache-Control: max-age=0');

$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, "Excel2007");
$objWriter->save('php://output');
exit;

function SaveViaTempFile($objWriter){
    $filePath = '/tmp/' . rand(0, getrandmax()) . rand(0, getrandmax()) . ".tmp";
    $objWriter->save($filePath);
    readfile($filePath);
    unlink($filePath);
}

// 엑셀의 셀 배경색 지정
function cellColor($cells,$color){
    global $objSheet;

    $objSheet->getStyle($cells)->getFill()->applyFromArray(array(
        'type' => PHPExcel_Style_Fill::FILL_SOLID,
        'startcolor' => array(
             'rgb' => $color
        )
    ));
}

?>

728x90
블로그 이미지

Link2Me

,
728x90

PHP 를 이용하여 MySQL 칼럼명을 가져오는 코드를 필요했다.

테이블을 INNER JOIN 하면서 select * from tableA a, tableB b where a.uid=b.uid 로 하면 tableA 와 tableB의 모든 칼럼을 가져오게 된다.


가져오고 싶은 것은 tableA의 칼럼만 가져오고 싶어서 함수로 구현했다.


<?php
require_once $_SERVER['DOCUMENT_ROOT'].'/dbconnect.php'; //db접속

echo getColumns('member_table'); // table name

function getColumns($table){

    global $DB_CONNECT;
    $fields = array();
    $res=mysql_query("SHOW COLUMNS FROM ".$table."");
    while ($x = mysql_fetch_assoc($res)){
      array_push($fields,$x['Field']);
    }

    for($i = 0; $i < count($fields); $i++){
        $columns = join($fields,",");
    }
    return $columns;
}

?>


728x90
블로그 이미지

Link2Me

,
728x90

<!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-1.11.0.min.js"></script>
<script>
$(function(){
    $("#sel2").click(function(){
        cw=screen.availWidth;     //화면 넓이
        ch=screen.availHeight;    //화면 높이

        sw=cw/2;    //띄울 창의 넓이
        sh=ch/2;    //띄울 창의 높이

        ml=(cw-sw)/2; //가운데 띄우기위한 창의 x위치
        mt=(ch-sh)/2; //가운데 띄우기위한 창의 y위치

        var url = $("#sel").val();
        if(url != '0'){
            window.open(url, 'tst','width='+sw+',height='+sh+',top='+mt+',left='+ml+',resizable=no,scrollbars=yes');
        }

    });
});
</script>
<body>
<select id="sel">
  <option value="0" >선택 사이트로 이동</option>
  <option value="http://link2me.tistory.com">My Blog</option>
  <option value="http://www.naver.com">네이버</option>
  <option value="http://www.daum.net">다음</option>
 </select><a href="#" id="sel2" >이동</a>

</body>
</html>

728x90
블로그 이미지

Link2Me

,
728x90

<input type="button" id="orderBtn" name="Test" value = "순서변경"></button>


MouseOver 시 손가락 모양 표시

css로 손가락 모양을 만든다.


    $('#orderBtn').css("cursor","pointer").click(function() {
        $.ajax ({
            type:"POST",
            url:"./order_process.php",
            data:ordered_items,
            success:function(data) {
                alert ("서열순서를 DB에 반영했습니다.");
            }
        });   
    });

728x90

'Web 프로그램 > js, jQuery' 카테고리의 다른 글

jQuery 모달(dialog) 코드 이해하기  (2) 2016.10.11
jQuey 새창 띄우기  (0) 2016.07.11
jQuery 모달(modal) 윈도우  (0) 2016.05.01
JSON 기초  (0) 2016.04.24
부모창 새로 고침  (1) 2016.04.10
블로그 이미지

Link2Me

,
728x90

테이블 게시글 순서를 변경 저장해야 할 경우가 있다.

그래서 jQuery tableDnD 를 이용해서 테스트한 것을 적어둔다.


마우스로 Drag 하여 놓기를 하고  순서변경만 누르면 DB에 반영된다.




파일은 https://github.com/isocra/TableDnD 에서 다운로드 받아 jquery.tablednd.js 만 include 한다.


순서를 변경하는 것은 직급 서열 순서를 변경하는 경우에 처리할 것이므로, 화면에 표시할 게시글수를 2페이지로 분리해서 나오도록 하면 안된다.

그래서 limit 에 조건을 만족하는 개수만큼 표시되도록 처리했다.


<?php
session_start();
// 세션 검사 처리는 생략
// DB 연결
include_once $_SERVER['DOCUMENT_ROOT'].'/db.info.php';
require_once $_SERVER['DOCUMENT_ROOT'].'/phpclass/dbClass.php';
$c=new MySQLDbClass();
$DB_CONNECT = $c->isConnectDb($DB);

$where =""; // where 조건문
$limit = $NUM = $c->getDbRows('BOOKS',''); // 조건에 맞는 게시글 개수
$flddata ="uid, title, price, category, orderNO";
$orderby = "orderNO";
$curPage = 1;
$result = $c->getDbArray('BOOKS',$where,$flddata,$orderby,$limit,$curPage);

?>

<!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-1.11.0.min.js"></script>
<script type="text/javascript" src="js/jquery.tablednd.js"></script>
<style>
body {font-family: "맑은 고딕";}
table,td,th {border: 1px solid #000;border-collapse:collapse;padding:5px;}
/*사용자 정의 스타일 */
.dragRow {background-color: #fee;}

td.dragHandle {}

td.showDragHandle {
    background-image: url(images/updown2.gif);
    background-repeat: no-repeat;
    background-position: center left;
    cursor: move;
}

table td {padding:5px;}
</style>

<script>
$(function() {
    var ordered_items;
    $('#table_1').tableDnD({
        onDragClass: "dragRow",
        onDrop: function(table, row) {
        ordered_items = $.tableDnD.serialize('id');
        }
    });

    $('#btn_order').css("cursor","pointer").click(function() {
        $.ajax ({
            type:"POST",
            url:"./order_process.php",
            data:ordered_items,
            success:function(data) {
                alert ("서열순서를 DB에 반영했습니다.");
            }
        });   
    });


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

}); // ready

</script>
<body>
<div class="container">
    <div id="article">
        총 : <?php echo number_format($NUM)?> 개
    </div>

    <section id="content">
        <table id="table_1" border="1" style="width:800px;">
        <tr class="nodrop nodrag"><!-- Drag & Drop 제외 -->
            <th>uid</th>
            <th>타이틀</th>
            <th>가격</th>
            <th>구분</th>
            <th style="width:50px;">순번</th>
        </tr>
        <?php
        while($row = mysql_fetch_array($result)){
            echo '<tr id="'.$row[0].'" class="tr1">';
            for($i=0;$i < count(explode(",",$flddata)); $i++){
                echo '<td>'.$row[$i].'</td>';
            }
            echo '</tr>';
        }
        ?>
        </table>
        <input type="button" id="btn_order" name="Test" value = "순서변경"></button>
    </section><!-- content -->
</div><!-- container -->
</body>
</html>


===== order_process.php =====

<?php
if(!isset($_POST['table_1'])) {
    echo 'error';
    exit;
}

$table_1 = $_POST['table_1'];
foreach ($table_1 as $key=>$value) {
    // 정렬순서 변경내역 DB에 반영
    require_once $_SERVER['DOCUMENT_ROOT'].'/dbconnect.php'; // db접속
    $query = 'UPDATE BOOKS SET orderNO = '.($key+1).' WHERE uid = '.$value.' LIMIT 1';
    mysql_query($query) or die (mysql_error());
}

?>



728x90
블로그 이미지

Link2Me

,
728x90

테이블 게시물 순서 바꾸기를 연습해봤다.

테이블 순서를 변경해주는 jQuery 소스는 https://github.com/isocra/TableDnD 에서 받을 수 있다.

jquery.tablednd.js


첨부로 올린 이 파일을 받아도 된다.

이것은 테이블에서 마우스로 위아래 게시물 순서를 변경할 수 있다는 것만 연습해볼 수 있다.

DB와 연동하여 실제 게시물 순서를 변경하는 것 까지는 안된다.

하지만 거의 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-1.11.0.min.js"></script>
<script type="text/javascript" src="js/jquery.tablednd.js"></script>
<style>
body {font-family: "맑은 고딕";}
table,td,th {border: 1px solid #000;border-collapse:collapse;padding:5px;}
/*사용자 정의 스타일 */
.dragRow {background-color: #eee;}

td.dragHandle {}

td.showDragHandle {background-image: url(images/updown2.gif);
    background-repeat: no-repeat;background-position: center left;
    cursor: move;
}

table td {padding:5px;}
</style>

<script>
$(function() {
    var ordered_items;
    onDragClass: "drag",
    $('#table_1').tableDnD({
        onDrop: function(table, row) {
        ordered_items = $.tableDnD.serialize('id');
        }
    });

    $('#btn_order').click(function() {
        $('#result').load("test.php?" + ordered_items);
    });

});
</script>
</script>


<div id="result">테이블 순서변경 결과 메시지 보여주는 곳</div>
<br>
<table id="table_1" border="1" style="width: 500px;">
    <tr id="1"><td>1</td><td>첫번째</td></tr>
    <tr id="2"><td>2</td><td>두번째</td></tr>
    <tr id="3"><td>3</td><td>세번째</td></tr>
    <tr id="4"><td>4</td><td>네번째</td></tr>
    <tr id="5"><td>5</td><td>다섯번째</td></tr>
</table>
<input type="button" id="btn_order" name="Test" value = "순서변경"></button>


</body>
</html>


===== test.php =====

<?php
$table_1 = $_GET['table_1'];
echo '저장순서 : ';
foreach ($table_1 as $key=>$value) {
    echo '순번 '. ($key+1) . ' 번의 DB idx = '. $value . ', ';
    // DB에 결과를 반영하고자 하는 쿼리문을 적어준다
    // $query = 'UPDATE table SET orderNO = '.($key+1).' WHERE idx = '.$value.' LIMIT 1';
    // mysql_query($query) or die (mysql_error());
}

?>


DB에서 읽어온 파일을 테이블로 구성한다면 <tr id='row['idx']'> 에 값이 저장되도록 한다.

테이블의 순서를 변경하면 자동으로 DB에 저장된 순서로 orderNO 에 순서의 값이 저장된다.


게시물을 읽어서 테이블에 보여주는 개수를 잘 처리하는 것이 중요 포인트가 될 수도 있다.

가령 뽑아내야 할 게시글의 수가 18개 였다고 가정해보자.

그러면 화면에서는 18개가 모두 나오도록 처리하는게 중요하다.

화면에 출력해야 할 Query 문의 개수(count)를 구한 다음에 그 개수만큼 출력하려면 LIMIT $count 만큼 나오도록 쿼리문을 만들어야 한다.

728x90
블로그 이미지

Link2Me

,
728x90

SQL 인젝션 공격을 방지하기 위한 로그인 함수 사용예이다.

공격코드로 사용하는 특수문자를 전부 공백으로 대체시켜 버리도록 했다.


function UserAuthCheck($userID,$passwd) {
    if(!isset($userID) || !isset($passwd) || empty($userID) || empty($passwd)) {
        return 0;
    } else {
        global $DB_CONNECT;           
        $userID = preg_replace("/[\s\t\'\;\"\=\-\-]+/","", $userID); // 공백이나 탭 제거(사용자 실수 방지)
        $passwd = preg_replace("/[\s\t\'\;\"\=\-\-]+/","", $passwd); // 공백이나 탭 제거, 특수문자 제거(",',;,=,--)
        // SQL injection 검사
        $userID = htmlentities($userID); // <script>documnet.cookie();</script> 공격 방지, 한글인식 불가
        $passwd = htmlentities($passwd); // < 를 \< 로 바꿔준다.
        //$userID = str_replace(array("'",""","'",'"'), array("&#39;","&quot;","&#39;","&quot;"), $userID);
        if(preg_match('/(and|null|where|limit)/i', $userID)) { $this->popup('비정상적 접근입니다');} // i는 대소문자 구별하지 말라
        if(!preg_match('/^[0-9a-zA-Z\~\!\@\#\$\%\^\&\*\(\)]{7,}$/',$passwd)) { // 최소7자리 이상 허용 문자만 통과
            $this->popup('정보가 올바르지 않습니다');
        }

        $sql = "select code, id ";
        $sql.= "from memberdata where pw=md5('".$passwd."') and id= '".$userID."' ";
        if($result = mysqli_query($DB_CONNECT,$sql)) { //성공
            $row = mysqli_fetch_array($result);
            if($row == NULL) $this->popup('정보가 올바르지 않습니다');
                return $row;
            } else {
                $this->popup('정보가 올바르지 않습니다');
        }
    }
}

728x90
블로그 이미지

Link2Me

,
728x90

XML 데이터 생성하여 화면에 보여주거나, 파일로 저장하는 방법에 대한 함수를 시간을 많이 할애하고 테스트하고 적어둔다.

작업을 하다보니 XML 데이터의 칼럼수가 달라지는 경우 일일이 적어주는 것도 일이더라.

그래서 함수로 만들어서 사용하니 매우 편하다.

dbClass.php 에 대한 설명은 http://link2me.tistory.com/1110 참조하면 된다.


<?php
    include_once $_SERVER['DOCUMENT_ROOT'].'/db.info.php';
    require_once $_SERVER['DOCUMENT_ROOT'].'/phpclass/dbClass.php';
    require_once $_SERVER['DOCUMENT_ROOT'].'/phpclass/xmlClass.php';

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

    // 화면에 출력할 칼럼 발췌
   $sql ="select (select classname from category where uid=d.cate1) as cat1,(select classname from category where uid=d.cate2) as cat2,subject,content from data d where is_direct=2 and is_checking=0";
   $result = mysql_query($sql,$DB_CONNECT);

    $c = new xmlcreateClass();
    $c->XML2View($result); // XML 데이터 화면 출력
    //$c->XML2File($result); // XML 데이터 파일 서버에 저장
    //$c->XMLDownload($result, 'myTest'); // XML 데이터 파일 PC에 저장

?>



<?php
class xmlcreateClass {

    // MySQL DB 자료를 column 개수, 게시물 총개수 만큼 자동으로 XML로 만들기
    function exportAsXML($result){
        $xml ='<?xml version="1.0" encoding="UTF-8" ?>'."\n";
        $xml.='<ListInfo>'."\n";
        while($row = mysql_fetch_array($result, MYSQL_ASSOC)) {
            $xml.="<items>"."\n";
            foreach($row as $column => $value) {
                $xml.="<".$column."><![CDATA[".$value."]]></".$column.">"."\n";
            }
            $xml.="</items>"."\n";
        }
        $xml.='</ListInfo>';
        return $xml;
    }

    // XML 데이터를 모니터 화면으로 출력
    // $c->XML2View($result); // XML 데이터 화면 출력
    function XML2View($result) {
        header('Content-type: text/xml');
        echo $this->exportAsXML($result);
    }

    // XML 데이터를 파일로 서버 저장
    function XML2File($result) {
        $destination_path='files/';
        $xmlfile ='XMLSaveFile.xml';
        $filename = $destination_path . $xmlfile;

        @chmod($filename,0707);  // 파일의 소유권이 있는 경우에만 권한 변경

        $file = fopen($filename,"w");
        fwrite($file, $this->exportAsXML($result));
        fclose($file);

        echo '<script>alert("파일저장 완료");</script>';
    }

    // XML 생성 데이터를 PC에 파일로 저장
    function XMLDownload($result, $filename) {
        header("Content-type: application/vnd.ms-excel; charset=UTF-8");
        header("Content-Disposition: attachment; filename = ".$filename."_".date("Ymd").".xml");
        header("Content-Description: PHP5 Generated Data");
        header("Cache-Control: no-cache"); header("Pragma: no-cache");
        echo $this->exportAsXML($result);
        exit;
    }

}  // end of Class
?>

728x90
블로그 이미지

Link2Me

,
728x90

PHP 에서 XML 문서로 데이터 출력을 하는 방법에 대해 알아보자.


XML 문서 만들기의 규칙

- 모든 XML 문서들은 정확한 형식을 갖추어야 한다.

- 모든 태그들은 쌍(시작태그, 종료태그)을 이루어야 한다.


PHP XML Parser 는 두가지 종류가 있다.

SimpleXML Parser 와 XML expat Parser이다.

XML expat Parser 는 event 기반 parser 이다. (http://www.w3schools.com/php/php_xml_parser_expat.asp)

XML expat Parser 는 XML 파일 데이터가 많은 경우에 효과적이다.

XML Expat Parser functions 의 구성요소는 3개의 이벤트로 구성되어 있다고 볼 수 있다.

- Start element: from
- Start CDATA section, value: Jani
- Close element: from


<?php

// 1. DB 접속 경로 지정하여 DB를 읽어들인다.
// 2. 읽어들일 XML 파일의 경로를 지정한다. $readFile
// 3. 읽어들일 파일이 XML 파일인지 여부를 검사한다.
// 4. 초기 변수를 선언한다.
// 5. XML parser 를 생성하고 읽어들인 XML 파일을 파싱처리하여 DB에 저장한다.
$parser=xml_parser_create(); // XML parser 생성

// element handler 등록, start/stop 은 함수명
xml_set_element_handler($parser,"start","stop");

// data handler 등록, char 는 함수명
xml_set_character_data_handler($parser,"char");

//Open XML file
$fp=fopen($readFile,"r");

//Read data
while (!feof($fp)) { // 파일의 마지막까지
    $data = fgets($fp);  // 파일을 한줄씩 읽어들인다.
    xml_parse($parser,$data,feof($fp)) or
    die (sprintf("XML Error: %s at line %d", xml_error_string(xml_get_error_code($parser)),
    xml_get_current_line_number($parser)));
}

//Free the XML parser
xml_parser_free($parser);

//Function to use at the start of an element
function start($parser,$element_name,$element_attrs) {
    global $parsedata;
    $parsedata = "";
}

//Function to use at the end of an element
function stop($parser,$element_name) {
    switch($element_name) {
        case "user_id":
            $user_id = $parsedata
            break;
        case "user_email":
            $user_email = $parsedata
            break;
        case "content":
            $content = $parsedata
            break;
        case "item":
            // <item> </item> 으로 하나의 자료가 끝나는 시점이므로 parse data 를 DB에 저장 처리
            // DB 저장시 key 값 기준으로 데이터 중복체크하여 insert, update 처리
            break;
    }
}

//Function to use when finding character data
function char($parser,$data) {
    global $parsedata;
    $parsedata = $data;
}

?>


728x90
블로그 이미지

Link2Me

,
728x90

if(!isset($_SESSION['userID']) || empty($_SESSION['userID']) || empty($_GET['uid'])){
    // 세션 및 접속 조건을 만족하지 못하면 (비정상접속)
    // 둘중의 하나를 적어준다.
    echo ("<script>alert('정상적인 접속이 아닙니다');window.top.location.replace('index.php');</script>");
    //echo ("<meta http-equiv='Refresh' content='0; URL=index.php'>");
    exit;
}

// 접속 IP 체크는 필요한 경우에 코드를 추가한다.


require_once $_SERVER['DOCUMENT_ROOT'].'/dbconnect.php'; // 데이터베이스 접속


728x90
블로그 이미지

Link2Me

,
728x90

접속 허용을 할 IP대역을 지정할 경우 간단하게 사용할 수 있는 방법이다.

내가 접속한 IP주소 확인은 http://www.findip.kr 에 접속하면 Public IP 주소를 알려준다.

그런데 findip.kr 사이트에서 받은 결과와 운영하는 서버에서 인식하는 IP주소가 다를 수 있다.

이때에는 운영하는 서버에서 인식하는 IP기준으로 필터링을 해야 한다.

 

<?php
$UserIP = $_SERVER['REMOTE_ADDR'];  // 접속한 사용자의 IP주소 불러오기
echo $UserIP."<br />";
echo $_SERVER['HTTP_USER_AGENT']; // 접속자의 사용자 브라우저 환경값 가져오기

$ip_extract = explode(".",$UserIP);  //.로 분리해서 배열로 저장
$UserIP_trim = $ip_extract[0].".".$ip_extract[1].".".$ip_extract[2];

$ipcheck_1 = "100.200.200"; // 접속 허용 IP 블럭

if($UserIP_trim == $ipcheck_1) {
   // 인증시키는 창으로 이동시킨다.
   $url = $PHP_SELF;
   $url = urlencode($url);
   echo ("<meta http-equiv='Refresh' content='0; URL=list.php'>");
   exit;
} else {
    echo ("<script>alert('허용된 사용자가 아닙니다');window.top.location.replace('index.php');</script>");
}

?>

 

다음과 같이 해도 된다.

<?php
if(strpos($UserIP, "100.200.200.") !== false) {  // 포함
    
} else {  // 미포함

}
?>

 

DB에 접속을 허용할 user 를 등록한 경우에만 허용하고자 한다면 아래와 같이 함수를 만들어서 사용하면 된다.

<?php
class LoginClass {
    function allowIPaddressChk(){
        global $db;
        $access_ip=$_SERVER['REMOTE_ADDR'];
        $sql ="select count(*) from allowHosts where ipaddr='".$access_ip."'";
        $result=mysql_query($sql);
        if($row=mysql_fetch_row($result)){
            if($row[0] == '1'){
                return 1;
            } else {
                return 0;
            }
        }
    }

} // End of Class

 

접속 허용 여부를 체크할 PHP 파일에 아래 코드를 추가한다.

require_once "dbconnect.php";
require_once "phpclass/LoginClass.php";

$access=new LoginClass();
if($access->allowIPaddressChk() == '0'){
    echo $_SERVER['REMOTE_ADDR'];
    exit;
}

 

728x90

'Web 프로그램 > PHP 응용 및 활용' 카테고리의 다른 글

PHP 일일 통계 테이블 구조 및 코드  (0) 2016.11.16
접속자 통계 구하기  (0) 2016.10.24
문자열 숫자 표기  (0) 2016.04.23
킴스큐 함수 활용  (0) 2016.04.19
[PHP] 날짜 함수 정리  (0) 2015.08.03
블로그 이미지

Link2Me

,
728x90

자바스크립트의 window.open() 로 팝업창을 열면 부모창에 대한 접근이 자유롭다. 하지만, modal 팝업창은 팝업창을 닫기 전까지는 부모창에 대한 접근이 불가능한 형태이다.


괜찮은 모달 jQuery

https://github.com/syakuis/jmodal



728x90

'Web 프로그램 > js, jQuery' 카테고리의 다른 글

jQuey 새창 띄우기  (0) 2016.07.11
[jQuery] 마우스 오버시 손가락 모양 표시  (0) 2016.07.10
JSON 기초  (0) 2016.04.24
부모창 새로 고침  (1) 2016.04.10
[자바스크립트] 제대로 배우는 폼 전송 기초  (0) 2016.02.18
블로그 이미지

Link2Me

,
728x90

PHP 낮은 버전을 높은 버전으로 업그레이해서 사용할 때 실수를 해서 적어둔다.


PHP 낮은 버전에서는 MySQL 을 사용하고, 높은 버전에서는 MySQLi 를 사용한다.

이런 부분에서 처리를 제대로 못해주니까 동작하는게 제대로 동작이 잘 안된다.


MySQLi 를 사용하는 문법과 MySQL 를 사용하는 문법이 별반 다를게 없지만 약간 차이가 있다.

MySQLi 에서 i 는 improved 로 MySQL 성능이 더 좋아졌다고 한다.


$conn = mysqli_connect($db_host,$db_user,$db_pass,$db_name,$db_port);

$conn = mysql_connect($db_host,$db_user,$db_pass);
$db = mysql_select_db($db_name,$conn);


접속하는 문법이 약간 달라졌다.

이런 부분을 고려해줘야 한다.


mysql_fetch_array($que);

mysqli_fetch_array($que); // i 가 추가되었다.


$result = mysql_query($sql, $db)

$result = mysqli_query($db, $sql)

로 순서가 변경된 것을 주의하지 않으면 오류가 발생한다.

728x90
블로그 이미지

Link2Me

,
728x90

isset 함수는 변수 자체가 존재하는지 여부를 알려준다.

isset() 함수는 변수가 존재하면 true를 반환한다.


empty 함수는 값이 true 인지 검사한다.

empty 함수는 값이 0 또는 null 이면 true

                    값이 존재하면 false 를 반환 한다.
변수가 존재하지 않아도 true 를 반환하므로 주의해야 한다.

isset()함수는 0 이든 문자열 "0"이든 값이 설정되어 있기 때문에 True를 반환한다.


unset($var); // 주어진 변수를 제거한다.

배열 전체를 제거할 수도 있고 배열의 원소 일부만 제거할 수도 있다.

unset($arr[0]); // $arr 배열의 첫번째 원소만 제거


is_array($arr); // 주어진 변수($arr)가 배열인지를 확인한다.



변수를 변경해가면서 테스트해 보면 화면에 어떤 결과를 보여주는지 확인할 수 있다.


<?php
    //$var = "Who are you?";
    //$var = false;
    $var = "";  // 변수는 있고 값은 없다.
    //$var = 0; // 변수는 있고 0은 false 로 인식한다.
    //$var = NULL;  // 변수 없고, 값도 없다.

    echo "var : ".$var."<br /><br />";

    if(isset($var)) {
        echo "변수가 있어요"."<br /><br />";
    } else {
        echo "변수가 없어요"."<br /><br />";
    }

    if(empty($var)) {
        echo "empty true : ".$var ."<br /><br />";
    } else {
        echo "empty false : ".$var ."<br /><br />";
    }

    if($var) {
        echo "값이 존재 : ".$var ."<br /><br />";
    } else {
        echo "값이 XX : ".$var ."<br /><br />";
    }

    if(isset($var) && !empty($var)) {
        echo "두개의 조건 만족 : ".$var ."<br /><br />";
    } else {
        echo "두개의 조건을 만족하지 않아요";
    }

?>


PHP의 문자열은 문자열을 '문자배열'로 간주해 배열처럼 첨자를 붙일 수 있다.

$str = 'student';

echo $str[3];

echo $str['a'];  // PHP 5.4 이상에서는 warning 발생처리

PHP 5.3까지는 $str['a'] 에서 a를 첫번째로 간주하여 첫번째 문자 s를 출력한다.

따라서 if(isset($str['a'])) 로 검사할 경우에 오류가 발생할 수 있다.

PHP 5.3까지는 true를 반환하고, PHP 5.4 이상에서는 false 를 반환한다.


$_GET['id'] 로 변수를 받았는데 경고 메시지가 나오면 3항 연산자를 사용하여

$id = isset($_GET['id']) ? $_GET['id'] : '';

로 해주면 된다.


728x90

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

[PHP] 배열에만 동작하는 foreach 문  (0) 2017.01.26
PHP Class 개념 이해 ★★  (0) 2017.01.10
PHP 대체 문법  (0) 2016.04.05
[PHP] switch 문  (0) 2015.06.01
[PHP] 문자열 자르기 substr  (0) 2015.05.16
블로그 이미지

Link2Me

,
728x90

JSON(Javascript Object Notation)

구문형식은 자바스크립트를 따르지만, 언어로부터 완전 독립적이기 때문에 서로 다른 프로그래밍언어간에 데이터를 교환하기 위해 현재 가장 널리 사용되는 표기법이다.


XML 은 열기 태그와 닫기 태그를 일일이 써줘야 한다.

<name>홍길동</name>

<age>32</age>


JSON 은 key : value 로 간단하게 표기한다.

var kk = { "name" : "홍길동", "age" : 32 }


value 에는 문자열(string), 숫자, 객체(object), 배열(array), 불리언(boolean), null 이 들어갈 수 있다.


JSON 으로 코드를 구현할 경우 반드시 알아야 할 사항은 UTF-8 만 인식한다는 점이다.

파일 Encoding 모드가 ANSI로 되어 있으면 결과값을 돌려주지 못한다.


EditPlus 에디터에서 보면 화면 하단 오른쪽에 파일의 인코딩 모드가 무엇인지 알려준다.



JSON.parse()
인자로 전달된 문자열(string 객체)을 자바스크립트의 데이터(json 객체)로 변환한다.

JSON.stringify()
인자로 전달된 자바스크립트의 데이터(json 객체)를 문자열(string 객체)로 변환한다.


<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JSON Example</title>
</head>
<body>
<script>
    var mydetails = {
        "name" : "John",
        "age " : "31"
    };
    var jsonto = JSON.stringify(mydetails);
    console.log(jsonto);

    var data = '{"name": "식빵", "family": "웰시코기", "age": 1, "weight": 2.14}';  // JSON 형식의 문자열
    var dog = JSON.parse(data); // JSON 형식의 문자열을 자바스크립트 객체로 변환함.
    console.log(dog);
</script>
<script>
    function signup() {

        var member = {
            "email" : "test@naver.com",
            "password" : "1234"
        };

        $.ajax({
            url : '/abc/result.php',
            dataType : 'json',
            type : 'POST',
            data : JSON.stringify(member), //그냥 member 사용하면 error 발생!
            contentType : 'application/json; charset=UTF-8',
            success : function(result) {
                console.log(result);
            }
        });

    }
</script>
</body>
</html>


결과


 <script src="//ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"></script>
<script>
    $('#execute').click(function(){
        var formData = $('form').serialize();
        $.ajax({
            url:'./abc.php',
            type:'post',
            data:formData,
            success:function(data){
                $('#showtime').text(data);
            }
        });
    });
</script>

<!-- 문서에 여러개의 폼이 있을 경우 document.forms[index] 로 접근할 수 있다. -->
<script>
$("#sub").click(function(){
    $("form").each(function(){
        var fd = new FormData($(this)[0]);
        $.ajax({
            type: "POST",
            url: "solve.php",
            data: fd,
            processData: false,
            contentType: false,
            success: function(data,status) {
               //this will execute when form is submited without errors
           },
           error: function(data, status) {
               //this will execute when get any error
           },
       });
    });
});
</script>


728x90
블로그 이미지

Link2Me

,