DB검색 기능 포함한 웹페이지

Synology NAS에서 PHP와 MySQL을 활용하여 웹 애플리케이션을 구축하는 과정에서 발생한 다양한 문제를 해결,, 구체적으로, 업무 데이터를 관리하기 위해 PHP로 작성된 […]

Synology NAS에서 PHP와 MySQL을 활용하여 웹 애플리케이션을 구축하는 과정에서 발생한 다양한 문제를 해결,,

구체적으로, 업무 데이터를 관리하기 위해 PHP로 작성된 index.php 파일에 검색 기능을 추가하고,

그 과정에서 발생한 문제들을 해결하는 방법을 다뤘습니다.

주요 내용:

  1. MariaDB 설정 및 MySQL 연결:
    • Synology NAS에서 MariaDB 설정과 root 계정으로의 접근 문제를 해결했습니다.
    • MySQL에 접속하고 데이터를 조회하는 방법을 설명했습니다.
  2. 검색 기능 구현:
    • index.php 파일에 검색 기능을 추가하기 위해 HTML 폼과 PHP 코드를 결합했습니다.
    • 검색어 입력 시 유효성 검사를 수행하는 JavaScript 코드를 추가했습니다.
    • PHP에서 검색어를 받아 SQL 쿼리에 반영하여 결과를 필터링하는 방법을 설명했습니다.
  3. SQL 쿼리 디버깅:
    • SQL 쿼리에서 WHERE 절이 두 번 추가되어 발생한 오류를 해결했습니다.
    • 검색어와 필터링 조건이 제대로 작동하도록 SQL 쿼리를 수정했습니다.
  4. 검색 창의 위치 조정:
    • 검색 창을 페이지의 오른쪽에 배치하는 방법을 설명했습니다.
    • float: right; 속성과 flex 레이아웃을 활용해 검색 창의 위치를 조정했습니다.
  5. 코드 통합:
    • 최종적으로 index.php 파일에 검색 기능을 통합하여 사용자가 특정 키워드를 입력해 데이터를 검색할 수 있도록 했습니다.
    • 검색 필드와 함께 카테고리 및 관련 기관 선택 필터링 기능을 유지하면서도 검색 기능을 추가했습니다.

MySQL 데이터베이스 및 테이블 생성

  1. phpMyAdmin에 로그인합니다. (MySQL root 계정으로 로그인)
  2. 왼쪽 패널에서 새 데이터베이스를 클릭하고, 데이터베이스 이름을 “행정사_업무”로 입력한 후 생성 버튼을 클릭합니다.
  3. 데이터베이스가 생성되면, 왼쪽 패널에서 “행정사_업무”를 선택하고 SQL 탭을 클릭합니다.
  4. 아래의 SQL 스크립트를 입력하고 실행 버튼을 클릭하여 테이블을 생성합니다:
sql코드 복사CREATE TABLE 카테고리 (
    id INT AUTO_INCREMENT PRIMARY KEY,
    이름 VARCHAR(255) NOT NULL
);

CREATE TABLE 성공사례 (
    id INT AUTO_INCREMENT PRIMARY KEY,
    카테고리_id INT,
    제목 VARCHAR(255) NOT NULL,
    설명 TEXT,
    파일경로 VARCHAR(255),
    FOREIGN KEY (카테고리_id) REFERENCES 카테고리(id)
);

3. 카테고리 데이터 입력

  1. 왼쪽 패널에서 카테고리 테이블을 선택합니다.
  2. 상단 메뉴에서 삽입 탭을 클릭합니다.
  3. 각 카테고리에 대해 이름 필드에 카테고리 이름을 입력하고 실행 버튼을 클릭합니다.

예를 들어, 다음과 같이 입력합니다:

  • 정부지원사업
  • 위치정보사업
  • 기업·기술·제품인증
  • 식약처인증
  • 부동산행정
  • 조달청업무
  • 스마트팜
  • 비영리단체설립
  • 출입국관리
  • 행정심판
  • 각종인허가
  • 행정기장자문

4. 성공사례 데이터 입력

  1. 왼쪽 패널에서 성공사례 테이블을 선택합니다.
  2. 상단 메뉴에서 삽입 탭을 클릭합니다.
  3. 성공사례 데이터를 입력합니다. 예를 들어:
  • 카테고리_id: 1 (해당 카테고리 ID)
  • 제목: 성공사례 제목1
  • 설명: 성공사례 설명1
  • 파일경로: /path/to/file1.png
  1. 데이터를 입력한 후 실행 버튼을 클릭합니다.

5. 파일 저장 및 경로 설정

성공사례에 관련된 PNG 파일은 시놀로지 서버의 공유 폴더에 저장하고, 해당 파일의 경로를 데이터베이스에 입력합니다. 예를 들어, 파일 경로는 /volume1/shared/folder/file1.png와 같이 설정할 수 있습니다.

6. 데이터 조회 및 관리

phpMyAdmin을 이용하여 데이터 조회 및 관리가 가능합니다. 각 테이블을 선택하고 검색 탭을 이용하여 데이터를 조회하거나, SQL 탭을 이용하여 직접 쿼리를 실행할 수 있습니다.

7. 웹 인터페이스 구축 (선택 사항)

보다 편리하게 데이터를 관리하기 위해 웹 인터페이스를 구축할 수 있습니다. PHP와 MySQL을 이용하여 CRUD(Create, Read, Update, Delete) 기능을 제공하는 웹 애플리케이션을 만들면 더욱 효율적으로 업무를 처리할 수 있습니다.

예를 들어, 간단한 PHP 스크립트를 사용하여 성공사례를 조회하는 페이지를 만들 수 있습니다:

<?php
$servername = "your_server_ip";
$username = "your_username";
$password = "your_password";
$dbname = "행정사_업무";

$conn = new mysqli($servername, $username, $password, $dbname);

if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
}

$sql = "SELECT * FROM 성공사례";
$result = $conn->query($sql);

if ($result->num_rows > 0) {
    while($row = $result->fetch_assoc()) {
        echo "ID: " . $row["id"]. " - 제목: " . $row["제목"]. " - 설명: " . $row["설명"]. " - 파일경로: " . $row["파일경로"]. "<br>";
    }
} else {
    echo "0 results";
}
$conn->close();
?>

전체 index.php 코드 (검색 기능 포함)

아래는 당신이 제공한 코드를 기반으로 검색 기능을 추가한 최종 코드입니다:

php코드

<?php
include 'config.php';

// 카테고리 데이터를 불러오기
$category_sql = "SELECT * FROM 카테고리";
$category_result = $conn->query($category_sql);

// SQL 에러 체크
if ($conn->error) {
echo "Category SQL Error: " . $conn->error;
}

// 관련기관 데이터를 불러오기
$departments = [
"기획재정부", "교육부", "외교부", "과학기술정보통신부", "통일부", "법무부", "국방부", "행정안전부", "문화체육관광부",
"농림축산식품부", "산업통상부", "보건복지부", "환경부", "고용노동부", "여성가족부", "국토교통부", "해양수산부",
"중소벤처기업부", "국세청", "관세청", "조달청", "통계청", "검찰청", "병무청", "방위사업청", "경찰청", "소방청",
"문화재청", "농촌진흥청", "산림청", "특허청", "질병관리청", "기상청", "행정중심복합도시건설청", "새만금개발청",
"해양경찰청", "식품의약품안전처"
];

// 선택된 카테고리 ID와 관련기관, 검색어를 확인
$selected_category_id = isset($_GET['category_id']) ? intval($_GET['category_id']) : '';
$selected_department = isset($_GET['department']) ? $_GET['department'] : '';
$search_query = isset($_GET['stx']) ? $_GET['stx'] : '';

// 성공사례 데이터를 불러오기
$case_sql = "SELECT 성공사례.id, 성공사례.제목, 카테고리.이름 AS 카테고리, 성공사례.관련기관
FROM 성공사례
JOIN 카테고리 ON 성공사례.카테고리_id = 카테고리.id";

$conditions = [];
if ($selected_category_id) {
$conditions[] = "성공사례.카테고리_id = $selected_category_id";
}
if ($selected_department) {
$conditions[] = "성공사례.관련기관 = '$selected_department'";
}
if ($search_query) {
$conditions[] = "(성공사례.제목 LIKE '%$search_query%' OR 성공사례.설명 LIKE '%$search_query%')";
}

if (count($conditions) > 0) {
$case_sql .= " WHERE " . implode(' AND ', $conditions);
}

$case_result = $conn->query($case_sql);

// SQL 에러 체크
if ($conn->error) {
echo "Case SQL Error: " . $conn->error;
}
?>
<!DOCTYPE html>
<html>
<head>
<title>성공사례 목록</title>
<style>
/* 메뉴 스타일 */
.navbar {
display: flex;
justify-content: space-around;
background-color: #333;
}
.navbar a {
color: white;
padding: 14px 20px;
text-decoration: none;
text-align: center;
}
.navbar a:hover {
background-color: #ddd;
color: black;
}
.dropdown {
position: relative;
display: inline-block;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #f9f9f9;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
}
.dropdown-content a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
text-align: left;
}
.dropdown-content a:hover {
background-color: #f1f1f1;
}
.dropdown:hover .dropdown-content {
display: block;
}

/* 표 스타일 */
table {
width: 90%; /* 테이블 너비 */
margin: 20px auto; /* 가운데 정렬 */
border-collapse: collapse; /* 셀 간의 간격 없애기 */
}

table, th, td {
border: 1px solid #ddd; /* 선 색상 및 굵기 조절 */
}

th, td {
padding: 12px; /* 셀 패딩 */
text-align: center; /* 텍스트 정렬 */
font-size: 10pt; /* 글자 크기 조절 */
}

th {
background-color: #f2f2f2; /* 헤더 배경색 */
}

tr:nth-child(even) {
background-color: #f9f9f9; /* 짝수 행 배경색 */
}

tr:hover {
background-color: #f1f1f1; /* 행 마우스 오버 시 배경색 */
}

/* 하이퍼링크 밑줄 제거 */
a.no-underline {
text-decoration: none;
color: inherit; /* 링크 색상을 상속받도록 설정 */
}
</style>
</head>
<body>
<h1>성공사례 목록</h1>

<a href="creat.php">성공사례 추가</a>

<!-- 검색 기능 추가 -->
<div class="hd_sch_wr">
<fieldset id="hd_sch">
<legend>사이트 내 전체검색</legend>
<form name="fsearchbox" method="get" action="index.php" onsubmit="return fsearchbox_submit(this);">
<input type="hidden" name="sfl" value="wr_subject||wr_content">
<input type="hidden" name="sop" value="and">
<label for="sch_stx" class="sound_only">검색어 필수</label>
<input type="text" name="stx" id="sch_stx" maxlength="20" placeholder="검색어를 입력해주세요">
<button type="submit" id="sch_submit" value="검색"><i class="fa fa-search" aria-hidden="true"></i><span class="sound_only">검색</span></button>
</form>

<script>
function fsearchbox_submit(f)
{
if (f.stx.value.length < 2) {
alert("검색어는 두글자 이상 입력하십시오.");
f.stx.select();
f.stx.focus();
return false;
}

// 검색에 많은 부하가 걸리는 경우 이 주석을 제거하세요.
var cnt = 0;
for (var i=0; i<f.stx.value.length; i++) {
if (f.stx.value.charAt(i) == ' ')
cnt++;
}

if (cnt > 1) {
alert("빠른 검색을 위하여 검색어에 공백은 한개만 입력할 수 있습니다.");
f.stx.select();
f.stx.focus();
return false;
}

return true;
}
</script>
</fieldset>
</div>

<form method="GET" action="index.php">
<label for="category_id">카테고리 선택:</label>
<select name="category_id" id="category_id" onchange="this.form.submit()">
<option value="">전체</option>
<?php
if ($category_result && $category_result->num_rows > 0) {
while($category = $category_result->fetch_assoc()) {
$selected = ($category['id'] == $selected_category_id) ? 'selected' : '';
echo "<option value='{$category['id']}' $selected>{$category['이름']}</option>";
}
}
?>
</select>
<label for="department">관련 기관 선택:</label>
<select name="department" id="department" onchange="this.form.submit()">
<option value="">전체</option>
<?php
foreach ($departments as $department) {
$selected = ($department == $selected_department) ? 'selected' : '';
echo "<option value='$department' $selected>$department</option>";
}
?>
</select>
</form>
<!-- 메뉴 -->
<div class="navbar">
<div class="dropdown">
<a href="#">업무분야</a>
<div class="dropdown-content">
<a href="index.php">정부지원사업</a>
<a href="#">위치정보사업</a>
<a href="#">기업기술제품인증</a>
<a href="index.php">식약청인증</a>
<a href="#">토지개발보상</a>
<a href="#">조달청업무</a>
<a href="#">스마트팜</a>
<a href="#">비영리단체설립</a>
<a href="#">출입국관리</a>
<a href="#">행정심판</a>
<a href="#">각종인허가</a>
<a href="#">행정(자문)기장</a>
</div>
</div>
<div class="dropdown">
<a href="#">성공사례</a>
<div class="dropdown-content">
<a href="index.php">성공사례</a>
<a href="#">계약현황</a>
<a href="#">행정서식</a>
</div>
</div>
<div class="dropdown">
<a href="#">참여마당</a>
<div class="dropdown-content">
<a href="#">온라인 상담</a>
<a href="#">업무제휴</a>
</div>
</div>
<div class="dropdown">
<a href="#">알림마당</a>
<div class="dropdown-content">
<a href="#">공지사항</a>
<a href="#">보도자료</a>
<a href="#">활동소식</a>
</div>
</div>
<div class="dropdown">
<a href="#">경영공시</a>
<div class="dropdown-content">
<a href="#">경영공시</a>
<a href="#">윤리경영</a>
<a href="#">사회공헌</a>
<a href="#">경영혁신</a>
</div>
</div>
<div class="dropdown">
<a href="#">구성원</a>
<div class="dropdown-content">
<a href="#">임원</a>
<a href="#">자문위원</a>
<a href="#">행정사</a>
<a href="#">직원</a>
<a href="#">직원안내</a>
</div>
</div>
<div class="dropdown">
<a href="#">회사소개</a>
<div class="dropdown-content">
<a href="#">인사말</a>
<a href="#">연혁</a>
<a href="#">찾아오시는길</a>
</div>
</div>
</div>

<table border="1">
<tr>
<th>번호</th>
<th>제목</th>
<th>카테고리</th>
<th>관련기관</th>
<th>Actions</th>
</tr>
<?php
if ($case_result && $case_result->num_rows > 0) {
$num = 1;
while($row = $case_result->fetch_assoc()) {
echo "<tr>
<td>{$num}</td>
<td><a class='no-underline' href='read.php?id={$row['id']}'>{$row['제목']}</a></td>
<td>{$row['카테고리']}</td>
<td>{$row['관련기관']}</td>
<td>
<a href='update.php?id={$row['id']}'>수정</a>
<a href='delete.php?id={$row['id']}'>삭제</a>
</td>
</tr>";
$num++;
}
} else {
echo "<tr><td colspan='5'>데이터가 없습니다.</td></tr>";
}
?>
</table>
</body>
</html>

주요 사항:

  1. 검색 기능:
    • search_query 변수를 통해 사용자가 입력한 검색어를 처리합니다.
    • 검색 조건을 SQL 쿼리에 반영하여 제목과 설명에서 검색어를 찾습니다.
  2. 폼 및 JavaScript:
    • 검색어 유효성 검사를 위한 JavaScript 코드를 추가했습니다.
    • 검색어 입력 필드와 서브밋 버튼을 페이지 상단에 배치하여 사용자가 쉽게 접근할 수 있도록 했습니다.
  3. 기타 필터링:
    • 카테고리 및 관련 기관 선택 필터링 기능도 유지하면서 검색 기능을 함께 사용할 수 있습니다.

댓글 달기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다