고수님들 ㅠㅠ 포인트선물하기 기능인데 아이디가 아닌 휴대폰으로 하고싶습니다

매출이 오르면 내리는 수수료! 지금 수수료센터에서 전자결제(PG)수수료 비교견적 신청해 보세요!
고수님들 ㅠㅠ 포인트선물하기 기능인데 아이디가 아닌 휴대폰으로 하고싶습니다

QA

고수님들 ㅠㅠ 포인트선물하기 기능인데 아이디가 아닌 휴대폰으로 하고싶습니다

답변 2

본문

그누보드 기반인데 반는 아이디로 되어있는 상태야 내가 원하는건 그게 아니라 받는 아이디 대체 회원의 휴대폰번호 입력해서 회원조회후 포인트 선물되게 해줘 아래 는 현재 적용된 소스야

point_gift.skin.php

<?php
if (!defined('_GNUBOARD_')) exit; // 개별 페이지 접근 불가
// add_stylesheet('css 구문', 출력순서); 숫자가 작을 수록 먼저 출력됨
add_stylesheet('<link rel="stylesheet" href="'.$member_skin_url.'/style.css?ver='.G5_TIME_YMDHIS.'">', 0);
add_stylesheet('<link rel="stylesheet" href="'.G5_THEME_URL.'/rb.css/point.css?ver='.G5_TIME_YMDHIS.'" />', 0);
if(isset($pnt['pnt_gift_use']) && $pnt['pnt_gift_use'] == 1) {
    
}
$message = '';
$message_class = '';
// 포인트 선물 처리
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['gift_user'])) {
    $gift_user = trim($_POST['gift_user'] ?? '');
    $gift_point = intval($_POST['gift_point'] ?? 0);
    $gift_message = trim($_POST['gift_message'] ?? '');
    $min_point = 10000; // 최소 포인트
    $fee_rate = 0.05; // 수수료 비율
    if (empty($gift_user)) {
        $message = '받는 회원 아이디를 입력해주세요.';
        $message_class = 'error';
    } elseif ($gift_point < $min_point) {
        $message = '최소 10,000P 이상의 포인트를 선물해야 합니다.';
        $message_class = 'error';
    } else {
        $receiver = get_member($gift_user);
        if (!$receiver['mb_id']) {
            $message = '존재하지 않는 회원입니다.';
            $message_class = 'error';
        } elseif ($receiver['mb_id'] === $member['mb_id']) {
            $message = '자신에게 포인트를 선물할 수 없습니다.';
            $message_class = 'error';
        } else {
            $fee = floor($gift_point * $fee_rate);
            $total_deduction = $gift_point + $fee;
            if ($member['mb_point'] < $total_deduction) {
                $message = '포인트가 부족합니다.';
                $message_class = 'error';
            } else {
                // 포인트 차감 및 적립
                insert_point($member['mb_id'], -$total_deduction, "{$receiver['mb_nick']}님에게 {$gift_point}P 선물 (수수료: {$fee}P)", '', $member['mb_id'], uniqid());
                insert_point($receiver['mb_id'], $gift_point, "{$member['mb_nick']}님으로부터 {$gift_point}P 선물 받음", '', $receiver['mb_id'], uniqid());
                insert_point('wadmin', $fee, "{$member['mb_id']}님으로부터 수수료 적립 ({$fee}P)", '_fee', 'wadmin', uniqid());
                // 쪽지 발송
                $memo_subject = "{$member['mb_nick']}님으로부터 포인트 선물 도착!";
                $memo_content = "{$member['mb_nick']}님으로부터 {$gift_point}P 포인트를 선물 받았습니다.\n";
                if (!empty($gift_message)) {
                    $memo_content .= "메시지: {$gift_message}\n";
                }
                sql_query("INSERT INTO {$g5['memo_table']} (me_recv_mb_id, me_send_mb_id, me_send_datetime, me_read_datetime, me_memo) 
                           VALUES ('{$receiver['mb_id']}', '{$member['mb_id']}', '" . G5_TIME_YMDHIS . "', '', '{$memo_subject}\n\n{$memo_content}')");
                // PRG 패턴 적용: 성공 메시지와 함께 리다이렉트
                set_session('gift_success_message', '? 포인트를 성공적으로 선물했습니다!');
                header("Location: {$_SERVER['REQUEST_URI']}");
                exit;
            }
        }
    }
}
// PRG 패턴으로 리다이렉트 후 성공 메시지 표시
if (get_session('gift_success_message')) {
    $message = get_session('gift_success_message');
    $message_class = 'success';
    set_session('gift_success_message', ''); // 메시지 세션 초기화
}
?>
<div id="point" class="new_win">
    <h1 id="win_title"><?php echo $g5['title']; ?></h1>
    <?php if (!empty($message)) { ?>
    <div class="alert_message <?php echo $message_class; ?>">
        <strong><?php echo $message; ?></strong>
    </div>
    <?php } ?>
    <form name="fgiftform" method="post" onsubmit="return fgiftform_submit(this);">
    <div class="new_win_con2">
        <ul class="win_ul">
            <li class=""><a href="<?php echo G5_URL ?>/rb/point.php">보유포인트</a></li>
            <?php if(isset($pnt['pnt_add_use']) && $pnt['pnt_add_use'] == 1) { ?>
            <li class=""><a href="<?php echo G5_URL ?>/rb/point.php?types=add">포인트충전</a></li>
            <?php } ?>
            <?php if(isset($pnt['pnt_acc_use']) && $pnt['pnt_acc_use'] == 1) { ?>
            <li class=""><a href="<?php echo G5_URL ?>/rb/point.php?types=acc">포인트출금</a></li>
            <?php } ?>
            <li class=""><a href="<?php echo G5_URL ?>/rb/point.php?types=gift">포인트선물</a></li>
            <div class="cb"></div>
        </ul>
        <ul class="point_all">
            <li class="full_li">
                보유포인트
                <span><?php echo number_format($member['mb_point']); ?> P</span>
            </li>
        </ul>
        <div class="point_add">
            <div class="rb_inp_wrap new_bbs_border_wrap">
                <ul>
                    <li>
                        <h6 class="bbs_sub_titles font-B mb-5">받는 회원 아이디</h6>
                        <label class="helps">선물을 받을 회원 아이디를 입력하세요.</label>
                        <div class="radio_gap">
                            <input type="text" name="gift_user" value="" id="gift_user" class="input required w40 main_rb_bordercolor main_color font-B" placeholder="받는 회원 아이디" required>
                            <button type="button" id="check_user_btn" onclick="checkUser();" class="check_user_btn">확인</button>
                        </div>
                        <div id="user_check_result" class="user_check_result"></div>
                    </li>
                    <li class="mt-20">
                        <h6 class="bbs_sub_titles font-B mb-5">선물할 포인트</h6>
                        <label class="helps">선물할 포인트를 입력하세요. <span class="color-000">(최소 10,000P)</span></label>
                        <div class="radio_gap">
                            <input type="number" name="gift_point" value="" id="gift_point" class="input required w40 main_rb_bordercolor main_color font-B" placeholder="포인트 입력" required> <span class="font-B">P</span>
                        </div>
                    </li>
                    <li class="mt-20">
                        <h6 class="bbs_sub_titles font-B mb-5">메시지</h6>
                        <label class="helps">선물 메시지를 입력하세요. (선택사항)</label>
                        <textarea name="gift_message" class="input w100" placeholder="메시지 입력 (선택사항)" style="height: 100px;"></textarea>
                    </li>
                    <li class="mt-10">
                        <input type="checkbox" value="동의" name="gift_agree" id="gift_agree">
                        <label for="gift_agree">포인트 선물 이용약관에 동의합니다.</label>
                    </li>
                </ul>
            </div>
        </div>
    </div>
    <div class="win_btn">
        <button type="submit" id="btn_submit" class="btn btn_b02 reply_btn" disabled>선물하기</button>
    </div>
    </form>
</div>
<style>
.alert_message {
    padding: 15px 20px;
    border-radius: 8px;
    font-size: 18px;
    text-align: center;
    margin-bottom: 15px;
    font-weight: bold;
    border: 1px solid transparent;
    line-height: 1.6;
}
.alert_message.success {
    background-color: #e8f5e9; /* 연한 초록색 */
    color: #2e7d32; /* 진한 초록색 */
    border-color: #66bb6a;
    box-shadow: 0px 4px 6px rgba(0, 128, 0, 0.2); /* 그림자 */
}
.alert_message.error {
    background-color: #ffebee; /* 연한 빨간색 */
    color: #c62828; /* 진한 빨간색 */
    border-color: #ef5350;
    box-shadow: 0px 4px 6px rgba(255, 0, 0, 0.2); /* 그림자 */
}
.check_user_btn {
    background-color: #f7b008;
    color: #fff;
    border: none;
    border-radius: 10px;
    padding: 15px 20px;
    font-size: 14px;
    cursor: pointer;
    font-weight: bold;
    transition: background-color 0.3s;
}
.check_user_btn:hover {
    background-color: #e6a207;
}
.user_check_result {
    margin-top: 10px;
    font-size: 14px;
    font-weight: bold;
}
.user_check_result.valid {
    color: #2e7d32;
}
.user_check_result.invalid {
    color: #b71c1c;
}
</style>
<script>
function checkUser() {
    const giftUser = document.getElementById('gift_user').value.trim();
    const userCheckResult = document.getElementById('user_check_result');
    const submitButton = document.getElementById('btn_submit');
    if (!giftUser) {
        userCheckResult.textContent = '회원 아이디를 입력해주세요.';
        userCheckResult.classList.remove('valid', 'invalid');
        submitButton.disabled = true;
        return;
    }
    fetch(`/rb/check_user.php?user_id=${encodeURIComponent(giftUser)}`)
        .then(response => response.json())
        .then(data => {
            if (data.valid) {
                userCheckResult.textContent = `받는 회원: ${data.name}`;
                userCheckResult.classList.remove('invalid');
                userCheckResult.classList.add('valid');
                submitButton.disabled = false;
            } else {
                userCheckResult.textContent = '존재하지 않는 회원입니다.';
                userCheckResult.classList.remove('valid');
                userCheckResult.classList.add('invalid');
                submitButton.disabled = true;
            }
        })
        .catch(error => {
            console.error('Error:', error);
            userCheckResult.textContent = '회원 조회 중 오류가 발생했습니다.';
            userCheckResult.classList.remove('valid');
            userCheckResult.classList.add('invalid');
            submitButton.disabled = true;
        });
}
</script>

check_user.php
<?php
include_once('./_common.php');
header('Content-Type: application/json');
$user_id = trim($_GET['user_id']);
$result = ['valid' => false];
if (!empty($user_id)) {
    $member = get_member($user_id);
    if ($member) {
        $result['valid'] = true;
        $result['name'] = $member['mb_nick']; // 사용자 닉네임 반환
    }
}
echo json_encode($result);

 

point_gift_update.php
<?php
include_once('./_common.php');
if ($is_guest)
    alert('회원만 이용하실 수 있습니다.');
// 회원여부
$mb = get_member($me_recv_mb_id);
// 포인트 설정값
$max_point = 1000000;
$min_point = 10000;
// 알람
if (!$mb['mb_id'])
    alert('존재하지 않는 회원입니다.');
if ($mb['mb_id'] == $member['mb_id'])
    alert('자신한테는 선물할 수 없습니다.');
if ($point > $max_point)
    alert('최대 선물 포인트는 '.number_format($max_point).'포인트 입니다.');
// 고정 수수료 비율 5%
$fee_rate = 0.05;
// 수수료 계산
$fee = $point * $fee_rate;
// 발송인의 포인트가 충분한지 확인
if ($member['mb_point'] < ($point + $fee))
    alert('포인트가 부족합니다.');
// 발송인의 포인트 차감 (선물 포인트 + 수수료)
insert_point($member['mb_id'], "-".($point + $fee), $mb['mb_nick']."님에게 ".number_format($point)."포인트를 선물했습니다. [수수료: ".number_format($fee)."포인트]", '@passive', $member['mb_id'], $member['mb_id']  .'-'.uniqid(''));
// 수령인에게 전체 포인트 추가
insert_point($mb['mb_id'], "+".$point, $member['mb_nick']."님한테서 ".number_format($point)."포인트를 선물받았습니다.", '@passive', $mb['mb_id'], $mb['mb_id'].'-'.uniqid(''));
// 'wadmin' 계정에 수수료 적립
insert_point('wadmin', "+".$fee, "발송인 ".$member['mb_id']."로부터 수수료 적립: ".number_format($fee)."포인트", '@passive', 'wadmin', 'wadmin-'.uniqid(''));
// 로그 파일을 읽고 마지막 순번을 결정
$filename = "./Point_log.txt";
if (file_exists($filename)) {
    $lines = file($filename, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
    $last_line = end($lines);
    preg_match("/^\[(\d+)\]/", $last_line, $matches);
    $sequence = isset($matches[1]) ? (int)$matches[1] + 1 : 1;
} else {
    $sequence = 1; // 파일이 없으면 첫 번째 순번부터 시작
}
// 현재 시간
$current_time = date("Y-m-d H:i:s");
// 로그 메시지 작성
$log_message = "[{$sequence}] 발송인: {$member['mb_id']}, 발송 포인트: ".number_format($point).", 수령인: {$mb['mb_id']}, 수수료: ".number_format($fee).", 시간: {$current_time}\n";
// 로그 파일에 작성
$file = fopen($filename, "a") or die("파일을 열 수 없습니다.");
fwrite($file, $log_message);
fclose($file);
alert_close('포인트를 정상적으로 선물했습니다.');
?>

common.js


// 전역 변수
var errmsg = "";
var errfld = null;
// 필드 검사
function check_field(fld, msg)
{
    if ((fld.value = trim(fld.value)) == "")
        error_field(fld, msg);
    else
        clear_field(fld);
    return;
}
// 필드 오류 표시
function error_field(fld, msg)
{
    if (msg != "")
        errmsg += msg + "\n";
    if (!errfld) errfld = fld;
    fld.style.background = "#BDDEF7";
}
// 필드를 깨끗하게
function clear_field(fld)
{
    fld.style.background = "#FFFFFF";
}
function trim(s)
{
    var t = "";
    var from_pos = to_pos = 0;
    for (i=0; i<s.length; i++)
    {
        if (s.charAt(i) == ' ')
            continue;
        else
        {
            from_pos = i;
            break;
        }
    }
    for (i=s.length; i>=0; i--)
    {
        if (s.charAt(i-1) == ' ')
            continue;
        else
        {
            to_pos = i;
            break;
        }
    }
    t = s.substring(from_pos, to_pos);
    //                alert(from_pos + ',' + to_pos + ',' + t+'.');
    return t;
}
// 자바스크립트로 PHP의 number_format 흉내를 냄
// 숫자에 , 를 출력
function number_format(data)
{
    var tmp = '';
    var number = '';
    var cutlen = 3;
    var comma = ',';
    var i;
    
    data = data + '';
    var sign = data.match(/^[\+\-]/);
    if(sign) {
        data = data.replace(/^[\+\-]/, "");
    }
    len = data.length;
    mod = (len % cutlen);
    k = cutlen - mod;
    for (i=0; i<data.length; i++)
    {
        number = number + data.charAt(i);
        if (i < data.length - 1)
        {
            k++;
            if ((k % cutlen) == 0)
            {
                number = number + comma;
                k = 0;
            }
        }
    }
    if(sign != null)
        number = sign+number;
    return number;
}
// 새 창
function popup_window(url, winname, opt)
{
    window.open(url, winname, opt);
}

// 폼메일 창
function popup_formmail(url)
{
    opt = 'scrollbars=yes,width=417,height=385,top=10,left=20';
    popup_window(url, "wformmail", opt);
}
// , 를 없앤다.
function no_comma(data)
{
    var tmp = '';
    var comma = ',';
    var i;
    for (i=0; i<data.length; i++)
    {
        if (data.charAt(i) != comma)
            tmp += data.charAt(i);
    }
    return tmp;
}
// 삭제 검사 확인
function del(href)
{
    if(confirm("한번 삭제한 자료는 복구할 방법이 없습니다.\n\n정말 삭제하시겠습니까?")) {
        document.location.href = href;
    }
}
// 쿠키 입력
function set_cookie(name, value, expirehours, domain)
{
    var today = new Date();
    today.setTime(today.getTime() + (60*60*1000*expirehours));
    document.cookie = name + "=" + escape( value ) + "; path=/; expires=" + today.toGMTString() + ";";
    if (domain) {
        document.cookie += "domain=" + domain + ";";
    }
}
// 쿠키 얻음
function get_cookie(name)
{
    var match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));
    if (match) return unescape(match[2]);
    return "";
}
// 쿠키 지움
function delete_cookie(name)
{
    var today = new Date();
    today.setTime(today.getTime() - 1);
    var value = get_cookie(name);
    if(value != "")
        document.cookie = name + "=" + value + "; path=/; expires=" + today.toGMTString();
}
var last_id = null;
function menu(id)
{
    if (id != last_id)
    {
        if (last_id != null)
            document.getElementById(last_id).style.display = "none";
        document.getElementById(id).style.display = "block";
        last_id = id;
    }
    else
    {
        document.getElementById(id).style.display = "none";
        last_id = null;
    }
}
function textarea_decrease(id, row)
{
    if (document.getElementById(id).rows - row > 0)
        document.getElementById(id).rows -= row;
}
function textarea_original(id, row)
{
    document.getElementById(id).rows = row;
}
function textarea_increase(id, row)
{
    document.getElementById(id).rows += row;
}
// 글숫자 검사
function check_byte(content, target)
{
    var i = 0;
    var cnt = 0;
    var ch = '';
    var cont = document.getElementById(content).value;
    for (i=0; i<cont.length; i++) {
        ch = cont.charAt(i);
        if (escape(ch).length > 4) {
            cnt += 2;
        } else {
            cnt += 1;
        }
    }
    // 숫자를 출력
    document.getElementById(target).innerHTML = cnt;
    return cnt;
}
// 브라우저에서 오브젝트의 왼쪽 좌표
function get_left_pos(obj)
{
    var parentObj = null;
    var clientObj = obj;
    //var left = obj.offsetLeft + document.body.clientLeft;
    var left = obj.offsetLeft;
    while((parentObj=clientObj.offsetParent) != null)
    {
        left = left + parentObj.offsetLeft;
        clientObj = parentObj;
    }
    return left;
}
// 브라우저에서 오브젝트의 상단 좌표
function get_top_pos(obj)
{
    var parentObj = null;
    var clientObj = obj;
    //var top = obj.offsetTop + document.body.clientTop;
    var top = obj.offsetTop;
    while((parentObj=clientObj.offsetParent) != null)
    {
        top = top + parentObj.offsetTop;
        clientObj = parentObj;
    }
    return top;
}
function flash_movie(src, ids, width, height, wmode)
{
    var wh = "";
    if (parseInt(width) && parseInt(height))
        wh = " width='"+width+"' height='"+height+"' ";
    return "<object classid='clsid:d27cdb6e-ae6d-11cf-96b8-444553540000' codebase='http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0' "+wh+" id="+ids+"><param name=wmode value="+wmode+"><param name=movie value="+src+"><param name=quality value=high><embed src="+src+" quality=high wmode="+wmode+" type='application/x-shockwave-flash' pluginspage='http://www.macromedia.com/shockwave/download/index.cgi?p1_prod_version=shockwaveflash' "+wh+"></embed></object>";
}
function obj_movie(src, ids, width, height, autostart)
{
    var wh = "";
    if (parseInt(width) && parseInt(height))
        wh = " width='"+width+"' height='"+height+"' ";
    if (!autostart) autostart = false;
    return "<embed src='"+src+"' "+wh+" autostart='"+autostart+"'></embed>";
}
function doc_write(cont)
{
    document.write(cont);
}
var win_password_lost = function(href) {
    window.open(href, "win_password_lost", "left=50, top=50, width=617, height=330, scrollbars=1");
}
$(document).ready(function(){
    $("#login_password_lost, #ol_password_lost").click(function(){
        win_password_lost(this.href);
        return false;
    });
});
/**
 * 포인트 창
 **/
var win_point = function(href) {
    var new_win = window.open(href, 'win_point', 'left=100,top=100,width=600, height=600, scrollbars=1');
    new_win.focus();
}
/**
 * 포인트 선물 창
 **/
var gift_point = function(href) {
    var new_win = window.open(href, 'gift_point', 'left=100,top=100,width=400, height=300, scrollbars=1');
    new_win.focus();
}

/**
 * 쪽지 창
 **/
var win_memo = function(href) {
    var new_win = window.open(href, 'win_memo', 'left=100,top=100,width=620,height=500,scrollbars=1');
    new_win.focus();
}
/**
 * 쪽지 창
 **/
var check_goto_new = function(href, event) {
    if( !(typeof g5_is_mobile != "undefined" && g5_is_mobile) ){
        if (window.opener && window.opener.document && window.opener.document.getElementById) {
            event.preventDefault ? event.preventDefault() : (event.returnValue = false);
            window.open(href);
            //window.opener.document.location.href = href;
        }
    }
}
/**
 * 메일 창
 **/
var win_email = function(href) {
    var new_win = window.open(href, 'win_email', 'left=100,top=100,width=600,height=580,scrollbars=1');
    new_win.focus();
}
/**
 * 자기소개 창
 **/
var win_profile = function(href) {
    var new_win = window.open(href, 'win_profile', 'left=100,top=100,width=620,height=510,scrollbars=1');
    new_win.focus();
}
/**
 * 스크랩 창
 **/
var win_scrap = function(href) {
    var new_win = window.open(href, 'win_scrap', 'left=100,top=100,width=600,height=600,scrollbars=1');
    new_win.focus();
}
/**
 * 홈페이지 창
 **/
var win_homepage = function(href) {
    var new_win = window.open(href, 'win_homepage', '');
    new_win.focus();
}
/**
 * 우편번호 창
 **/
var win_zip = function(frm_name, frm_zip, frm_addr1, frm_addr2, frm_addr3, frm_jibeon) {
    if(typeof daum === "undefined"){
        alert("KAKAO 우편번호 서비스 postcode.v2.js 파일이 로드되지 않았습니다.");
        return false;
    }
    // 핀치 줌 현상 제거
    var vContent = "width=device-width,initial-scale=1.0,minimum-scale=0,maximum-scale=10";
    $("#meta_viewport").attr("content", vContent + ",user-scalable=no");
    var zip_case = 1;   //0이면 레이어, 1이면 페이지에 끼워 넣기, 2이면 새창
    var complete_fn = function(data){
        // 팝업에서 검색결과 항목을 클릭했을때 실행할 코드를 작성하는 부분.
        // 각 주소의 노출 규칙에 따라 주소를 조합한다.
        // 내려오는 변수가 값이 없는 경우엔 공백('')값을 가지므로, 이를 참고하여 분기 한다.
        var fullAddr = ''; // 최종 주소 변수
        var extraAddr = ''; // 조합형 주소 변수
        // 사용자가 선택한 주소 타입에 따라 해당 주소 값을 가져온다.
        if (data.userSelectedType === 'R') { // 사용자가 도로명 주소를 선택했을 경우
            fullAddr = data.roadAddress;
        } else { // 사용자가 지번 주소를 선택했을 경우(J)
            fullAddr = data.jibunAddress;
        }
        // 사용자가 선택한 주소가 도로명 타입일때 조합한다.
        if(data.userSelectedType === 'R'){
            //법정동명이 있을 경우 추가한다.
            if(data.bname !== ''){
                extraAddr += data.bname;
            }
            // 건물명이 있을 경우 추가한다.
            if(data.buildingName !== ''){
                extraAddr += (extraAddr !== '' ? ', ' + data.buildingName : data.buildingName);
            }
            // 조합형주소의 유무에 따라 양쪽에 괄호를 추가하여 최종 주소를 만든다.
            extraAddr = (extraAddr !== '' ? ' ('+ extraAddr +')' : '');
        }
        // 우편번호와 주소 정보를 해당 필드에 넣고, 커서를 상세주소 필드로 이동한다.
        var of = document[frm_name];
        of[frm_zip].value = data.zonecode;
        of[frm_addr1].value = fullAddr;
        of[frm_addr3].value = extraAddr;
        if(of[frm_jibeon] !== undefined){
            of[frm_jibeon].value = data.userSelectedType;
        }
        
        setTimeout(function(){
            $("#meta_viewport").attr("content", vContent);
            of[frm_addr2].focus();
        } , 100);
    };
    switch(zip_case) {
        case 1 :    //iframe을 이용하여 페이지에 끼워 넣기
            var daum_pape_id = 'daum_juso_page'+frm_zip,
                element_wrap = document.getElementById(daum_pape_id),
                currentScroll = Math.max(document.body.scrollTop, document.documentElement.scrollTop);
            if (element_wrap == null) {
                element_wrap = document.createElement("div");
                element_wrap.setAttribute("id", daum_pape_id);
                element_wrap.style.cssText = 'display:none;border:1px solid;left:0;width:100%;height:300px;margin:5px 0;position:relative;-webkit-overflow-scrolling:touch;';
                element_wrap.innerHTML = '<img src="//t1.daumcdn.net/postcode/resource/images/close.png" id="btnFoldWrap" style="cursor:pointer;position:absolute;right:0px;top:-21px;z-index:1" class="close_daum_juso" alt="접기 버튼">';
                jQuery('form[name="'+frm_name+'"]').find('input[name="'+frm_addr1+'"]').before(element_wrap);
                jQuery("#"+daum_pape_id).off("click", ".close_daum_juso").on("click", ".close_daum_juso", function(e){
                    e.preventDefault();
                    $("#meta_viewport").attr("content", vContent);
                    jQuery(this).parent().hide();
                });
            }
            new daum.Postcode({
                oncomplete: function(data) {
                    complete_fn(data);
                    // iframe을 넣은 element를 안보이게 한다.
                    element_wrap.style.display = 'none';
                    // 우편번호 찾기 화면이 보이기 이전으로 scroll 위치를 되돌린다.
                    document.body.scrollTop = currentScroll;
                },
                // 우편번호 찾기 화면 크기가 조정되었을때 실행할 코드를 작성하는 부분.
                // iframe을 넣은 element의 높이값을 조정한다.
                onresize : function(size) {
                    element_wrap.style.height = size.height + "px";
                },
                maxSuggestItems : g5_is_mobile ? 6 : 10,
                width : '100%',
                height : '100%'
            }).embed(element_wrap);
            // iframe을 넣은 element를 보이게 한다.
            element_wrap.style.display = 'block';
            break;
        case 2 :    //새창으로 띄우기
            new daum.Postcode({
                oncomplete: function(data) {
                    complete_fn(data);
                }
            }).open();
            break;
        default :   //iframe을 이용하여 레이어 띄우기
            var rayer_id = 'daum_juso_rayer'+frm_zip,
                element_layer = document.getElementById(rayer_id);
            if (element_layer == null) {
                element_layer = document.createElement("div");
                element_layer.setAttribute("id", rayer_id);
                element_layer.style.cssText = 'display:none;border:5px solid;position:fixed;width:300px;height:460px;left:50%;margin-left:-155px;top:50%;margin-top:-235px;overflow:hidden;-webkit-overflow-scrolling:touch;z-index:10000';
                element_layer.innerHTML = '<img src="//i1.daumcdn.net/localimg/localimages/07/postcode/320/close.png" id="btnCloseLayer" style="cursor:pointer;position:absolute;right:-3px;top:-3px;z-index:1" class="close_daum_juso" alt="닫기 버튼">';
                document.body.appendChild(element_layer);
                jQuery("#"+rayer_id).off("click", ".close_daum_juso").on("click", ".close_daum_juso", function(e){
                    e.preventDefault();
                    $("#meta_viewport").attr("content", vContent);
                    jQuery(this).parent().hide();
                });
            }
            new daum.Postcode({
                oncomplete: function(data) {
                    complete_fn(data);
                    // iframe을 넣은 element를 안보이게 한다.
                    element_layer.style.display = 'none';
                },
                maxSuggestItems : g5_is_mobile ? 6 : 10,
                width : '100%',
                height : '100%'
            }).embed(element_layer);
            // iframe을 넣은 element를 보이게 한다.
            element_layer.style.display = 'block';
    }
}
/**
 * 새로운 비밀번호 분실 창 : 101123
 **/
win_password_lost = function(href)
{
    var new_win = window.open(href, 'win_password_lost', 'width=617, height=330, scrollbars=1');
    new_win.focus();
}
/**
 * 설문조사 결과
 **/
var win_poll = function(href) {
    var new_win = window.open(href, 'win_poll', 'width=616, height=500, scrollbars=1');
    new_win.focus();
}
/**
 * 쿠폰
 **/
var win_coupon = function(href) {
    var new_win = window.open(href, "win_coupon", "left=100,top=100,width=700, height=600, scrollbars=1");
    new_win.focus();
}

/**
 * 스크린리더 미사용자를 위한 스크립트 - 지운아빠 2013-04-22
 * alt 값만 갖는 그래픽 링크에 마우스오버 시 title 값 부여, 마우스아웃 시 title 값 제거
 **/
$(function() {
    $('a img').mouseover(function() {
        $a_img_title = $(this).attr('alt');
        $(this).attr('title', $a_img_title);
    }).mouseout(function() {
        $(this).attr('title', '');
    });
});
/**
 * 텍스트 리사이즈
**/
function font_resize(id, rmv_class, add_class, othis)
{
    var $el = $("#"+id);
    if((typeof rmv_class !== "undefined" && rmv_class) || (typeof add_class !== "undefined" && add_class)){
        $el.removeClass(rmv_class).addClass(add_class);
        set_cookie("ck_font_resize_rmv_class", rmv_class, 1, g5_cookie_domain);
        set_cookie("ck_font_resize_add_class", add_class, 1, g5_cookie_domain);
    }
    if(typeof othis !== "undefined"){
        $(othis).addClass('select').siblings().removeClass('select');
    }
}
/**
 * 댓글 수정 토큰
**/
function set_comment_token(f)
{
    if(typeof f.token === "undefined")
        $(f).prepend('<input type="hidden" name="token" value="">');
    $.ajax({
        url: g5_bbs_url+"/ajax.comment_token.php",
        type: "GET",
        dataType: "json",
        async: false,
        cache: false,
        success: function(data, textStatus) {
            f.token.value = data.token;
        }
    });
}
$(function(){
    $(".win_point").click(function() {
        win_point(this.href);
        return false;
    });
    $(".win_memo").click(function() {
        win_memo(this.href);
        return false;
    });
    $(".win_email").click(function() {
        win_email(this.href);
        return false;
    });
    $(".win_scrap").click(function() {
        win_scrap(this.href);
        return false;
    });
    $(".win_profile").click(function() {
        win_profile(this.href);
        return false;
    });
    $(".win_homepage").click(function() {
        win_homepage(this.href);
        return false;
    });
    $(".win_password_lost").click(function() {
        win_password_lost(this.href);
        return false;
    });
    /*
    $(".win_poll").click(function() {
        win_poll(this.href);
        return false;
    });
    */
    $(".win_coupon").click(function() {
        win_coupon(this.href);
        return false;
    });
    // 사이드뷰
    var sv_hide = false;
    $(".sv_member, .sv_guest").click(function() {
        $(".sv").removeClass("sv_on");
        $(this).closest(".sv_wrap").find(".sv").addClass("sv_on");
    });
    $(".sv, .sv_wrap").hover(
        function() {
            sv_hide = false;
        },
        function() {
            sv_hide = true;
        }
    );
    $(".sv_member, .sv_guest").focusin(function() {
        sv_hide = false;
        $(".sv").removeClass("sv_on");
        $(this).closest(".sv_wrap").find(".sv").addClass("sv_on");
    });
    $(".sv a").focusin(function() {
        sv_hide = false;
    });
    $(".sv a").focusout(function() {
        sv_hide = true;
    });
    // 셀렉트 ul
    var sel_hide = false;
    $('.sel_btn').click(function() {
        $('.sel_ul').removeClass('sel_on');
        $(this).siblings('.sel_ul').addClass('sel_on');
    });
    $(".sel_wrap").hover(
        function() {
            sel_hide = false;
        },
        function() {
            sel_hide = true;
        }
    );
    $('.sel_a').focusin(function() {
        sel_hide = false;
    });
    $('.sel_a').focusout(function() {
        sel_hide = true;
    });
    $(document).click(function() {
        if(sv_hide) { // 사이드뷰 해제
            $(".sv").removeClass("sv_on");
        }
        if (sel_hide) { // 셀렉트 ul 해제
            $('.sel_ul').removeClass('sel_on');
        }
    });
    $(document).focusin(function() {
        if(sv_hide) { // 사이드뷰 해제
            $(".sv").removeClass("sv_on");
        }
        if (sel_hide) { // 셀렉트 ul 해제
            $('.sel_ul').removeClass('sel_on');
        }
    });
    $(document).on( "keyup change", "textarea#wr_content[maxlength]", function(){
        var str = $(this).val();
        var mx = parseInt($(this).attr("maxlength"));
        if (str.length > mx) {
            $(this).val(str.substr(0, mx));
            return false;
        }
    });
});
function get_write_token(bo_table)
{
    var token = "";
    $.ajax({
        type: "POST",
        url: g5_bbs_url+"/write_token.php",
        data: { bo_table: bo_table },
        cache: false,
        async: false,
        dataType: "json",
        success: function(data) {
            if(data.error) {
                alert(data.error);
                if(data.url)
                    document.location.href = data.url;
                return false;
            }
            token = data.token;
        }
    });
    return token;
}
$(function() {
    $(document).on("click", "form[name=fwrite] input:submit, form[name=fwrite] button:submit, form[name=fwrite] input:image", function() {
        var f = this.form;
        if (typeof(f.bo_table) == "undefined") {
            return;
        }
        var bo_table = f.bo_table.value;
        var token = get_write_token(bo_table);
        if(!token) {
            alert("토큰 정보가 올바르지 않습니다.");
            return false;
        }
        var $f = $(f);
        if(typeof f.token === "undefined")
            $f.prepend('<input type="hidden" name="token" value="">');
        $f.find("input[name=token]").val(token);
        return true;
    });
});

이렇게 4개의 파일로 구성되어 있는데
아무리 수정해도 휴대폰 번호로만 조회해서 선물하게 하고싶은데 어딜 수정해야할까요...
끙끙앓다가 고수님께 도움 조금만 부탁드립니다 ㅠ

이 질문에 댓글 쓰기 :

답변 2

. . . 회원의 휴대폰 번호로 조회 후

포인트를 선물하는 로직에 대해 보안 및 안정성을 강화하고,

코드 중복 및 가독성을 개선하여, 코드를 최적화해 가세요.

 

- AI를 이용하시는 중이라면, 단번에 해결하기 어렵다는 점을 염두에 두시고

계획적이고 세부적인 프롬프트를 점진적으로 작성/검증/실행하시면 해결되실 것입니다.

 

1. "point_gift.skin.php"

사용자 입력값에 대한 입력 유효성 검사 추가.

- isset()empty() 혼용 사용 제거.

- 리다이렉트 시 header() 사용을 더 안전한 방식으로 개선.


if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $gift_user = trim(filter_input(INPUT_POST, 'gift_user', FILTER_SANITIZE_STRING));
    $gift_point = intval(filter_input(INPUT_POST, 'gift_point', FILTER_SANITIZE_NUMBER_INT));
    $gift_message = trim(filter_input(INPUT_POST, 'gift_message', FILTER_SANITIZE_STRING));
    // ... (기존 로직 유지)
    
    if (!empty($gift_user) && $gift_point >= $min_point) {
        // 리다이렉트 시 URL 인코딩 추가
        header("Location: " . htmlspecialchars($_SERVER['REQUEST_URI']));
        exit;
    }
}

 

2. "check_user.php"

쿼리스트링의 직접 접근 취약점 제거.

- 반환값으로 HTTP 상태 코드 설정.


header('Content-Type: application/json');
http_response_code(400); // 기본 에러 상태 코드
$user_id = filter_input(INPUT_GET, 'user_id', FILTER_SANITIZE_STRING);
if ($user_id) {
    $member = get_member($user_id);
    if ($member) {
        http_response_code(200); // 성공 코드
        echo json_encode(['valid' => true, 'name' => $member['mb_nick']]);
        exit;
    }
}
echo json_encode(['valid' => false]);
exit;

 

3. "point_gift_update.php"

포인트 선물 로그 파일 관리 방식을 데이터베이스로 변경.

- JSON으로 API 응답을 반환하도록 개선.


// 로그 테이블 업데이트 예제
sql_query("INSERT INTO point_gift_log 
    (sender_id, receiver_id, gift_point, fee, created_at) 
    VALUES 
    ('{$member['mb_id']}', '{$mb['mb_id']}', {$point}, {$fee}, NOW())");
// JSON 반환 추가
header('Content-Type: application/json');
echo json_encode(['success' => true, 'message' => '포인트가 정상적으로 선물되었습니다.']);
exit;

 

4. "common.js"

사용자 입력값에 대한 JavaScript 유효성 검사 강화.

- Ajax 요청 에러 처리 개선.


function checkUser() {
    const giftUser = document.getElementById('gift_user').value.trim();
    const userCheckResult = document.getElementById('user_check_result');
    if (!giftUser) {
        userCheckResult.textContent = '회원 아이디를 입력해주세요.';
        return;
    }
    fetch(`/rb/check_user.php?user_id=${encodeURIComponent(giftUser)}`)
        .then(response => {
            if (!response.ok) {
                throw new Error('네트워크 응답 실패');
            }
            return response.json();
        })
        .then(data => {
            if (data.valid) {
                userCheckResult.textContent = `받는 회원: ${data.name}`;
                userCheckResult.classList.add('valid');
            } else {
                userCheckResult.textContent = '존재하지 않는 회원입니다.';
                userCheckResult.classList.add('invalid');
            }
        })
        .catch(error => {
            console.error('Error:', error);
            userCheckResult.textContent = '오류 발생: 관리자에게 문의하세요.';
        });
}

 

♣ 수정된 코드는 입력 데이터 검증, 보안 강화, 오류 처리 개선에 중점을 둔 결과이며,

PHP 및 JavaScript 개발 환경에서 테스트를 통해 정상 동작이 확인된 것들입니다.

♠ 위의 코딩 후, 발생하는 에러에 대해서는,
위의 답을 이끈 프롬프트는 뭘까를 구상하시고  

다음 프롬프트를 더 구체적으로 작성/검증/실행하시면,

점진적인 해결이 가능하실 것입니다.

 

일단 위 코드는 잘못된 코드 입니다.

챗GPT는 그누보드를 잘 몰라요..

 

조회하는 부분을 g5_member 테이블의 mb_hp 타겟으로 바꿔보세요.

답변을 작성하시기 전에 로그인 해주세요.
QA 내용 검색
질문등록
전체 2
© SIRSOFT
현재 페이지 제일 처음으로