회원 주소록 페이지를 만들고 싶어요

회원 주소록 페이지를 만들고 싶어요

QA

회원 주소록 페이지를 만들고 싶어요

사용하는 빌더

기타

그누보드5(영카트) 버전

5.6.10

사용 PHP 버전

최신버전

본문

회원가입 하신 분에게 다른 회원 목록이 보여지도록 하고 싶습니다. 클릭하면 팝업이나 페이지 이동으로 그사람의 이메일, 전화번호, 닉네임 등이 나오게 하고싶어요.

친목 사이트라 주소록을 만들어 달라고 하셔서요. 이런 기능을 지원하나요? 안한다면 비슷한 기능 구현이 가능한지도 궁금합니다.

이 질문에 댓글 쓰기 :

답변 4

주소록 페이지 샘플 코드입니다.

적절하게 필요한 부분 수정 및 보안 처리 등이 필요합니다.

 

1) 회원 주소록 목록

* /page/member_list.php


<?php
include_once('../common.php');
// 회원만 접근 가능하도록 제한
if (!$is_member) {
  alert('회원만 이용 가능합니다.', G5_BBS_URL.'/login.php?url='.urlencode(G5_URL.'/memberlist.php'));
}
// 페이지 제목 설정
$g5['title'] = '회원 주소록';
include_once(G5_PATH.'/head.php');
// 페이지네이션 설정
$page = isset($_GET['page']) ? intval($_GET['page']) : 1;
$rows = 10; // 한 페이지에 표시할 회원 수
$from_record = ($page - 1) * $rows;
// 검색 조건
$sfl = isset($_GET['sfl']) ? trim($_GET['sfl']) : '';
$stx = isset($_GET['stx']) ? trim($_GET['stx']) : '';
// 검색 쿼리 구성
$sql_search = "";
if ($stx) {
  $sql_search = " and ({$sfl} like '%{$stx}%') ";
}
// 총 회원 수 계산
$sql = " select count(*) as cnt from {$g5['member_table']} 
         where mb_leave_date = '' and mb_level > 1 {$sql_search} ";
$row = sql_fetch($sql);
$total_count = $row['cnt'];
// 회원 목록 쿼리
$sql = " select * from {$g5['member_table']}
         where mb_leave_date = '' and mb_level > 1 {$sql_search}
         order by mb_datetime desc
         limit {$from_record}, {$rows} ";
$result = sql_query($sql);
// 페이징 처리
$total_page = ceil($total_count / $rows);
?>
<div class="member-list-container">
  <h2 class="member-list-title">회원 주소록</h2>
  
  <!-- 검색 폼 -->
  <div class="member-search-wrap">
    <form name="fsearch" method="get" class="member-search">
      <select name="sfl" id="sfl">
        <option value="mb_nick" <?php echo ($sfl=='mb_nick')?'selected':''; ?>>닉네임</option>
        <option value="mb_name" <?php echo ($sfl=='mb_name')?'selected':''; ?>>이름</option>
      </select>
      <input type="text" name="stx" value="<?php echo $stx; ?>" class="search-input" placeholder="검색어 입력">
      <button type="submit" class="search-button">검색</button>
    </form>
  </div>
  
  <!-- 회원 목록 -->
  <div class="member-list">
    <table class="member-table">
      <thead>
        <tr>
          <th>프로필</th>
          <th>닉네임</th>
          <th>가입일</th>
          <th>상세정보</th>
        </tr>
      </thead>
      <tbody>
      <?php for ($i=0; $row=sql_fetch_array($result); $i++) { ?>
        <tr>
          <td class="profile-img"><?php echo get_member_profile_img($row['mb_id']); ?></td>
          <td class="td-name"><?php echo $row['mb_nick']; ?></td>
          <td class="td-date"><?php echo substr($row['mb_datetime'], 0, 10); ?></td>
          <td class="td-view">
            <button type="button" class="member-view-btn" 
                    onclick="viewMemberInfo('<?php echo $row['mb_id']; ?>')">상세보기</button>
          </td>
        </tr>
      <?php } ?>
      <?php if ($i == 0) { ?>
        <tr><td colspan="4" class="empty_table">등록된 회원이 없습니다.</td></tr>
      <?php } ?>
      </tbody>
    </table>
  </div>
  
  <!-- 페이지네이션 -->
  <div class="pagination">
    <?php echo get_paging(G5_IS_MOBILE ? $config['cf_mobile_pages'] : $config['cf_write_pages'], $page, $total_page, '?'.$qstr.'&page='); ?>
  </div>
</div>
<!-- 회원 상세정보 모달 -->
<div id="memberInfoModal" class="modal">
  <div class="modal-content">
    <span class="close">×</span>
    <div id="memberInfoContent"></div>
  </div>
</div>
<script>
$(document).ready(function() {
  // 모달 관련 변수
  var $modal = $("#memberInfoModal");
  var $modalContent = $("#memberInfoContent");
  
  // 모달 닫기 버튼 클릭 이벤트
  $(".close").click(function() {
    $modal.fadeOut(200);
  });
  
  // 모달 외부 클릭시 닫기 이벤트
  $(window).click(function(event) {
    if ($(event.target).is($modal)) {
      $modal.fadeOut(200);
    }
  });
});
// 회원 정보 보기 함수 (전역 함수로 유지)
function viewMemberInfo(mb_id) {
  // AJAX로 회원 정보 가져오기
  $.ajax({
    url: 'ajax.member_info.php',
    type: 'POST',
    data: { mb_id: mb_id },
    dataType: 'json',
    success: function(data) {
      if (data.error) {
        alert(data.error);
        return;
      }
      
      // 회원 정보 표시
      var html = '<div class="member-detail">' +
                 '<div class="member-profile">' + data.mb_profile_img + '</div>' +
                 '<h3>' + data.mb_nick + ' (' + data.mb_name + ')</h3>' +
                 '<table class="member-info-table">' +
                 '<tr><th>이메일</th><td>' + (data.mb_email || '미입력') + '</td></tr>' +
                 '<tr><th>휴대폰</th><td>' + (data.mb_hp || '미입력') + '</td></tr>' +
                 '<tr><th>가입일</th><td>' + data.mb_datetime + '</td></tr>' +
                 '</table>' +
                 '</div>';
      
      $("#memberInfoContent").html(html);
      $("#memberInfoModal").fadeIn(200);
    },
    error: function(xhr, status, error) {
      alert("오류가 발생했습니다: " + error);
    }
  });
}
</script>
<style>
/* 회원 목록 스타일 */
.member-list-container {
  max-width: 1000px;
  margin: 0 auto;
  padding: 20px;
}
.member-list-title {
  text-align: center;
  margin-bottom: 30px;
}
.member-search-wrap {
  margin-bottom: 20px;
  text-align: right;
}
.member-search select,
.member-search input[type="text"],
.member-search button {
  padding: 8px;
  border: 1px solid #ddd;
}
.member-table {
  width: 100%;
  border-collapse: collapse;
}
.member-table th,
.member-table td {
  padding: 12px;
  text-align: center;
  border: 1px solid #e1e1e1;
}
.member-table th {
  background-color: #f8f8f8;
  font-weight: bold;
}
.profile-img img {
  width: 50px;
  height: 50px;
  border-radius: 50%;
  object-fit: cover;
}
.member-view-btn {
  padding: 5px 10px;
  background-color: #4a89dc;
  color: white;
  border: none;
  border-radius: 3px;
  cursor: pointer;
}
.member-view-btn:hover {
  background-color: #3a70b8;
}
/* 모달 스타일 */
.modal {
  display: none;
  position: fixed;
  z-index: 1000;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0,0,0,0.5);
}
.modal-content {
  background-color: #fefefe;
  margin: 10% auto;
  padding: 20px;
  border: 1px solid #888;
  width: 80%;
  max-width: 500px;
  border-radius: 5px;
  position: relative;
}
.close {
  position: absolute;
  right: 15px;
  top: 10px;
  color: #aaa;
  font-size: 28px;
  font-weight: bold;
  cursor: pointer;
}
.close:hover {
  color: black;
}
.member-detail {
  text-align: center;
}
.member-profile {
  margin-bottom: 15px;
}
.member-profile img {
  width: 100px;
  height: 100px;
  border-radius: 50%;
  object-fit: cover;
}
.member-info-table {
  width: 100%;
  border-collapse: collapse;
  margin-top: 15px;
}
.member-info-table th,
.member-info-table td {
  padding: 8px;
  text-align: left;
  border-bottom: 1px solid #ddd;
}
.member-info-table th {
  width: 30%;
  background-color: #f8f8f8;
}
.pagination {
  margin-top: 20px;
  text-align: center;
}
</style>
<?php
include_once(G5_PATH.'/tail.php');
?>


2) 회원 정보 상세 처리 페이지

* /page/ajax.member_info.php


<?php
include_once('../common.php');
// 회원만 이용 가능
if (!$is_member) {
  die(json_encode(array('error' => '회원만 이용 가능합니다.')));
}
// 파라미터 검증
$mb_id = isset($_POST['mb_id']) ? clean_xss_tags(trim($_POST['mb_id'])) : '';
if (!$mb_id) {
  die(json_encode(array('error' => '회원 정보가 존재하지 않습니다.')));
}
// 회원 정보 조회
$sql = " select mb_id, mb_name, mb_nick, mb_email, mb_homepage, mb_tel, mb_hp, 
                mb_point, mb_datetime, mb_level
         from {$g5['member_table']}
         where mb_id = '{$mb_id}' ";
$mb = sql_fetch($sql);
if (!$mb['mb_id']) {
  die(json_encode(array('error' => '존재하지 않는 회원입니다.')));
}
// 프로필 이미지
$mb_profile_img = get_member_profile_img($mb_id);
// 실제 사용시 개인정보 보호 설정 적용 필요
$data = array(
  'mb_id' => $mb['mb_id'],
  'mb_name' => $mb['mb_name'],
  'mb_nick' => $mb['mb_nick'],
  'mb_email' => $mb['mb_email'],
  'mb_hp' => $mb['mb_hp'],
  'mb_tel' => $mb['mb_tel'],
  'mb_level' => $mb['mb_level'],
  'mb_datetime' => substr($mb['mb_datetime'], 0, 10),
  'mb_profile_img' => $mb_profile_img
);
echo json_encode($data);
?>

로그인된 회원만 접근할 수 있는 전용 회원 목록 페이지를 구현하시어,

회원이 목록에서 다른 회원의 닉네임과 기본 정보를 확인할 수 있도록 하시면,

목록의 각 항목을 클릭 시 AJAX 기반의 팝업 또는 별도 상세 페이지로 전환되어

이메일, 전화번호 등 추가 정보가 노출되는 방안을 제안합니다.

 

아래는 그누5.6.10의 예시로, 로그인 세션 검증 후 회원 전용 목록을 출력하고,

AJAX를 통해 상세정보(이메일, 전화번호, 닉네임 등)를 반환하는 예입니다.

이 예는 회원 전용 페이지를 /bbs/member_list_custom.php로 두고, 회원 항목 클릭 시

/bbs/member_info_ajax.php가 JSON 형식의 데이터를 반환하도록 구성한 예입니다.

 

https://address-book.glitter.kr/bbs/member_list_custom.php ( ID: test , Pass: test 초기값 입력됨 )

  -- 회원 DB 정보 실시간 반영 --

 

★/bbs/member_list_custom.php 생성 ===

<?php

include_once('./_common.php');

 

// 비회원 접근 차단: 로그인하지 않은 경우 로그인 후 주소 페이지로 이동

if (!$is_member) {

    alert('회원만 이용 가능합니다.', G5_BBS_URL.'/login.php?url='.urlencode(G5_BBS_URL.'/member_list_custom.php'));

}

 

// sql_escape 함수가 없을 경우 간단히 정의 (보안상 addslashes()는 완벽하지 않으므로, 추후 DB 연결 객체에 맞게 교체 필요)

if (!function_exists('sql_escape')) {

    function sql_escape($value) {

        return addslashes($value);

    }

}

 

// 현재 로그인한 회원 정보는 _common.php에서 $member 배열로 제공됨

$g5['title'] = '회원 주소록';

include_once(G5_PATH.'/head.sub.php');

 

// 현재 로그인한 회원을 제외한 회원 목록 조회

$sql = " SELECT mb_id, mb_nick, mb_profile

        FROM {$g5['member_table']}

        WHERE mb_id != '" . sql_escape($member['mb_id']) . "' ";

$result = sql_query($sql);

?>

 

<div class="container">

    <h2>회원 주소록</h2>

    <table class="table table-bordered">

        <thead>

            <tr>

                <th>프로필 사진</th>

                <th>닉네임</th>

            </tr>

        </thead>

        <tbody>

            <?php while($row = sql_fetch_array($result)) { ?>

              <tr>

                <td>

                    <?php

                        // 회원 프로필 이미지가 있으면 사용, 없으면 기본 이미지 사용

                        $profile_img = trim($row['mb_profile']) !== ''

                                      ? "/data/member_image/" . htmlspecialchars($row['mb_profile'])

                                      : "/img/no_profile.gif";

                    ?>

                    <img src="<?php echo $profile_img; ?>" alt="프로필" width="50">

                </td>

                <td>

                    <a href="#" class="member-link" data-mbid="<?php echo htmlspecialchars($row['mb_id']); ?>">

                        <?php echo htmlspecialchars($row['mb_nick']); ?>

                    </a>

                </td>

            </tr>

            <?php } ?>

        </tbody>

    </table>

</div>

 

<!-- 부트스트랩 Modal -->

<div class="modal fade" id="memberModal" tabindex="-1" role="dialog" aria-labelledby="memberModalLabel">

  <div class="modal-dialog" role="document">

    <div class="modal-content">

      <div class="modal-header">

        <h4 class="modal-title" id="memberModalLabel">회원 정보</h4>

      </div>

      <div class="modal-body">

        <p>이메일:   <span id="modalEmail"></span></p>

        <p>핸드폰:   <span id="modalPhone"></span></p>

        <p>닉네임:   <span id="modalNick"></span></p>

      </div>

      <div class="modal-footer">

        <button type="button" class="btn btn-default" data-dismiss="modal">닫기</button>

      </div>

    </div>

  </div>

</div>

 

★ /bbs/member_info_ajax.php 생성 ===

<?php

include_once('./_common.php');

 

if (!function_exists('sql_escape')) {

    function sql_escape($value) {

        return addslashes($value);

    }

}

 

header('Content-Type: application/json');

 

// 비회원 접근 차단

if ($is_guest) {

    echo json_encode(['success' => false, 'error' => '회원만 이용 가능합니다.']);

    exit;

}

 

// POST로 전달된 회원 아이디 검증 (알파벳, 숫자, 밑줄만 허용)

$mb_id = isset($_POST['mb_id']) ? preg_replace('/[^a-zA-Z0-9_]/', '', $_POST['mb_id']) : '';

if (!$mb_id) {

    echo json_encode(['success' => false, 'error' => '잘못된 요청입니다.']);

    exit;

}

 

// 회원 정보 안전 조회 – sql_escape() 함수 사용

$sql = " SELECT mb_nick, mb_email, mb_hp

        FROM {$g5['member_table']}

        WHERE mb_id = '" . sql_escape($mb_id) . "' ";

$result = sql_query($sql);

 

// 쿼리 실행에 실패하면 MySQLi 에러 로그 기록

if (!$result) {

    error_log("SQL 오류: " . mysqli_error($g5['connect_db']));

    echo json_encode(['success' => false, 'error' => 'SQL 오류 발생']);

    exit;

}

 

$row = sql_fetch_array($result);

 

if ($row) {

    echo json_encode([

        'success' => true,

        'mb_nick' => $row['mb_nick'],

        'mb_email' => $row['mb_email'],

        'mb_phone' => $row['mb_hp']

    ]);

} else {

    error_log("POST로 전달된 mb_id: " . $mb_id);

    echo json_encode(['success' => false, 'error' => '회원 정보를 찾을 수 없습니다.']);

}

?>

 

★ /theme/basic/head.sub.php 스타일/스크립트 코드 추가 ===

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">

<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>

<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

<script>

$(document).ready(function(){

    $('.member-link').click(function(e){

        e.preventDefault();

        var mb_id = $(this).data('mbid');

        $.ajax({

            url: '<?php echo G5_BBS_URL; ?>/member_info_ajax.php',

            type: 'POST',

            data: { mb_id: mb_id },

            dataType: 'json',

            success: function(data) {

                if(data.success){

                    $('#memberModalLabel').text(data.mb_nick + "의 정보");

                    $('#modalEmail').text(data.mb_email);

                    $('#modalPhone').text(data.mb_phone);

                    $('#modalNick').text(data.mb_nick);

                    $('#memberModal').modal('show');

                } else {

                    alert('회원 정보를 불러오는데 실패했습니다.');

                }

            },

            error: function(){

                alert('서버와의 통신에 실패했습니다.');

            }

        });

    });

});

</script>

 

붙임

위 예시 코드에서 사용된

"/css/bootstrap.min.css", "/js/jquery-1.12.4.min.js", "/js/bootstrap.min.js" 파일들은

부트스트랩과 제이쿼리의 미니파이드 버전으로,

일반적으로 해당 파일들은 공식 사이트에서 다운로드 받아

서버의 웹 루트 내 적절한 디렉토리(예, /css, /js)에 저장해 두거나

CDN(Content Delivery Network)을 통해 제공받을 수 있습니다.

회원명부라는 게시판을 하나 만들고 
모든 회원들이 그곳에서 글을 하나만 작성할 수 있게 하고 작정하지 않은 회원은 작성해야만 사이트를 이용할 수 있도록 한 다음 사이드뷰를 통해서 자기소개, 쪽지 보내기 홈페이지 등 여러가지를 할 수 있을 것입니다.
보기 권한을 2 등급 이상으로 하면 회원들만 볼 수 있게 될 것입니다.
 

https://sir.kr/g5_skin/61781

 

위 내용은 참고만 하시고요

아무리 침목사이트라도 보안이 중요하니 

그누보드 관리자에 보면 회원 레벨 지정 하는 것이 있거든요 

거기에서 주소록에 보여줘두되는 분들을 6레벨로 지정해서 그분들만 뿌려주는 주고

보이는 페이지도 6레벨 이상회원이 접속했을때만 작동되게 하는 것을 추천합니다

그리고 사실 이런것은

 

https://sir.kr/request

의뢰하시면 5~10만원에 1일 해주실분 많아요 

늘 행복하세요

답변을 작성하시기 전에 로그인 해주세요.
전체 29
QA 내용 검색

회원로그인

(주)에스아이알소프트 / 대표:홍석명 / (06211) 서울특별시 강남구 역삼동 707-34 한신인터밸리24 서관 1402호 / E-Mail: admin@sir.kr
사업자등록번호: 217-81-36347 / 통신판매업신고번호:2014-서울강남-02098호 / 개인정보보호책임자:김민섭(minsup@sir.kr)
© SIRSOFT