Synology NAS에서 PHP와 MySQL을 활용하여 웹 애플리케이션을 구축하는 과정에서 발생한 다양한 문제를 해결,,
구체적으로, 업무 데이터를 관리하기 위해 PHP로 작성된 index.php 파일에 검색 기능을 추가하고,
그 과정에서 발생한 문제들을 해결하는 방법을 다뤘습니다.
주요 내용:
- MariaDB 설정 및 MySQL 연결:
- Synology NAS에서 MariaDB 설정과 root 계정으로의 접근 문제를 해결했습니다.
- MySQL에 접속하고 데이터를 조회하는 방법을 설명했습니다.
- 검색 기능 구현:
index.php파일에 검색 기능을 추가하기 위해 HTML 폼과 PHP 코드를 결합했습니다.- 검색어 입력 시 유효성 검사를 수행하는 JavaScript 코드를 추가했습니다.
- PHP에서 검색어를 받아 SQL 쿼리에 반영하여 결과를 필터링하는 방법을 설명했습니다.
- SQL 쿼리 디버깅:
- SQL 쿼리에서
WHERE절이 두 번 추가되어 발생한 오류를 해결했습니다. - 검색어와 필터링 조건이 제대로 작동하도록 SQL 쿼리를 수정했습니다.
- SQL 쿼리에서
- 검색 창의 위치 조정:
- 검색 창을 페이지의 오른쪽에 배치하는 방법을 설명했습니다.
float: right;속성과flex레이아웃을 활용해 검색 창의 위치를 조정했습니다.
- 코드 통합:
- 최종적으로
index.php파일에 검색 기능을 통합하여 사용자가 특정 키워드를 입력해 데이터를 검색할 수 있도록 했습니다. - 검색 필드와 함께 카테고리 및 관련 기관 선택 필터링 기능을 유지하면서도 검색 기능을 추가했습니다.
- 최종적으로
MySQL 데이터베이스 및 테이블 생성
phpMyAdmin에 로그인합니다. (MySQL root 계정으로 로그인)- 왼쪽 패널에서
새 데이터베이스를 클릭하고, 데이터베이스 이름을 “행정사_업무”로 입력한 후생성버튼을 클릭합니다. - 데이터베이스가 생성되면, 왼쪽 패널에서 “행정사_업무”를 선택하고
SQL탭을 클릭합니다. - 아래의 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. 카테고리 데이터 입력
- 왼쪽 패널에서
카테고리테이블을 선택합니다. - 상단 메뉴에서
삽입탭을 클릭합니다. - 각 카테고리에 대해
이름필드에 카테고리 이름을 입력하고실행버튼을 클릭합니다.
예를 들어, 다음과 같이 입력합니다:
- 정부지원사업
- 위치정보사업
- 기업·기술·제품인증
- 식약처인증
- 부동산행정
- 조달청업무
- 스마트팜
- 비영리단체설립
- 출입국관리
- 행정심판
- 각종인허가
- 행정기장자문
4. 성공사례 데이터 입력
- 왼쪽 패널에서
성공사례테이블을 선택합니다. - 상단 메뉴에서
삽입탭을 클릭합니다. - 성공사례 데이터를 입력합니다. 예를 들어:
카테고리_id: 1 (해당 카테고리 ID)제목: 성공사례 제목1설명: 성공사례 설명1파일경로: /path/to/file1.png
- 데이터를 입력한 후
실행버튼을 클릭합니다.
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>
주요 사항:
- 검색 기능:
search_query변수를 통해 사용자가 입력한 검색어를 처리합니다.- 검색 조건을 SQL 쿼리에 반영하여 제목과 설명에서 검색어를 찾습니다.
- 폼 및 JavaScript:
- 검색어 유효성 검사를 위한 JavaScript 코드를 추가했습니다.
- 검색어 입력 필드와 서브밋 버튼을 페이지 상단에 배치하여 사용자가 쉽게 접근할 수 있도록 했습니다.
- 기타 필터링:
- 카테고리 및 관련 기관 선택 필터링 기능도 유지하면서 검색 기능을 함께 사용할 수 있습니다.
