본문 바로가기
Language/php

PHP 개발 참고 사항

by 잘먹는 개발자 에단 2025. 1. 31.

1. 

한 php 파일에서 폼처리 + db연결 + 쿼리

 

2. 

별도의 php 파일에서 db 관련 기능을 함수로 분리해서 사용하기 

 

 

3. 

mysql_connect()란 

- 이 연결방식은 오래된 방식이라서 보안문제 때문에 지금은 mysqli나 pdo가 많이 대체로 사용된다.

- 다음과 같은 특징을 가진다.

    1. 연결 성공 시에 연결 id를 반환한다, 실패하면 false를 반환한다.

    2. mysql_select_db()로 사용할 데이터베이스를 선택해야한다.

    3. 쿼리 실행은 mysql_query()로 한다.

    4. mysql_fetch_assoc() 함수로 결과를 가져온다.

    5. php 7부터는 제거되었음

 

 

4. form 을 통해서 api 호출하기 

php 5.3.6에서 form을 통해 api를 호출하는 방식

- form을 사용하면 사용자가 입력한 데이터를 post 방식으로 서버에 보낼 수 있음.

- api를 호출하는 방식은 기본적으로 cURL을 이용하거나 file_get_contents()를 사용하는 방법이 있다. 

- php 5.3.6은 오래된 버전이라 json_encode(), json_decode()를 지원하지만 최신 http 클라이언트(guzzle emd)는 사용할 수 없으므로 curl을 사용해야한다. 

 

 

form을 사용하면 기본적으로 POST 방식이다. method = "post"를 지정하면 $_POST 로 데이터를 받을 수 있다. 

예를 들어서 이런식으로 전송하게 된다면 

<form action="process.php" method="post">
    <input type="text" name="name">
    <button type="submit">전송</button>
</form>

 

아래와 같이 받을 수 있다. 

$name = $_POST['name'];

 

 

 

다음은 쿼리 파라미터로 보내는 방식이다. 쿼리 파라미터로 보내면 이것은 GET 방식이다.

URL에 데이터를 포함해서 요청하는 방식이다.

<a href="process.php?name=John">이름 전달</a>

 

위와 같이 보내면 아래와 같이 받는다.

$name = $_GET['name'];

 

구분 GET POST
전송방식 URL 쿼리파라미터 HTTP 본문(body)
데이터노출 URL에 보인다. 숨겨진다.
보안 민감한 데이터에는 부적합 상대적으로 안전
길이제한 있다. URL에 길이 제한이 있음 없음
캐싱 브라우저가 캐싱가능 캐싱되지 않음
사용예시 검색, 필터링, 단순한 데이터조회 로그인, 회원가입, 데이터변경요청

 

form을 사용하면 기본적으로 POST 방식이지만 get 방식도 가능하다. 

<form action="process.php" method="get">
    <input type="text" name="name">
    <button type="submit">전송</button>
</form>

이렇게 하면 process.php?name=입력값 형태로 요청이 간다. 

 

 

 

 

 

5.  한 파일에서 api 요청 처리하기

 

그럼 다음으로 한 파일에서 api 요청을 처리하는 예제를 살펴보자. 

이렇게 한 파일로 구현하게 되면 

- 구현이 간단하다. 한 파일에서 폼 제출과 api 호출을 처리하므로 유지보수가 쉽다.

- 빠른 테스트가 가능하다. 별도 파일을 만들 필요 없이 빠르게 api 요청을 보낼 수 있다.

하지만

- 가독성이 떨어진다. 모든 로직이 한 파일에 몰려있어서 코드가 복잡해질 수 있다.

- 재사용성이 낮다. API 호출 부분을 다른 곳에서 재사용하기 어렵다. 

// 한 파일에서 form을 통해 데이터를 받고 같은 파일 내에서 API를 호출하는 구조

<?php
if($_SERVER["REQUEST_METHOD"] == "POST"){
	$name = isset($_POST['name']) ? $_POST['name'] : '';
    
    $api_url = "https://~~!~~~~~~";
    
    // cURL 초기화
    $ch = curl_init($api_url);
	
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query(['name' => $name]));
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'Content-Type: application/x-www-form-urlencoded'
    ]);
    
    $response = curl_exec($ch);
    curl_close($ch);
    
    echo "API Response".htmlspecialchars($response);
}
?>

<!DOCTYPE html>
<html>
<head>
    <title>API Form (Single File)</title>
</head>
<body>
    <form method="post">
        <label>이름: <input type="text" name="name" required></label>
        <button type="submit">API 호출</button>
    </form>
</body>
</html>

 

 

6. api 요청을 다른 파일에서 처리하기

 

이렇게 하면 다음과 같은 장점이 있다. 

- 모듈화가 가능하다. process.php가 api 호출을 전담하기 때문에 여러곳에서 재사용할 수 있다.

- 가독성이 향상된다. form.html과 process.php가 분리되어있어서 유지보수가 용이하다.

- 보안이 향상된다. api 호출을 위한 로직이 별도 php 파일에 있어서 form.html을 직접 수정할 필요가 없다.

하지만

- 파일관리가 필요해진다. 단순히 파일 수가 많아 지기 때문에 관리안하면 나중에 복잡해질 수 있다.

- 조금 더 복잡하다. 때문에 단순 테스트용도로는 적합하지 않다.

 

예를 들어서 이런 폼이 있다고 쳐보자. 

form.html

<!DOCTYPE html>
<html>
<head>
    <title>API Form (Separate File)</title>
</head>
<body>
    <form action="process.php" method="post">
        <label>이름: <input type="text" name="name" required></label>
        <button type="submit">API 호출</button>
    </form>
</body>
</html>

process.php에 post 요청을 보내는데 body에 name 파라미터를 required로 보낸다.  

 

process.php

<?php
if ($_SERVER["REQUEST_METHOD"] == "POST") {
    $name = isset($_POST['name']) ? $_POST['name'] : '';

    // API URL 설정
    $api_url = "https://example.com/api";

    // cURL 초기화
    $ch = curl_init($api_url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query(['name' => $name]));
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'Content-Type: application/x-www-form-urlencoded'
    ]);

    // API 호출
    $response = curl_exec($ch);
    curl_close($ch);

    echo "API Response: " . htmlspecialchars($response);
}
?>

 

 

 

7. 쿼리 날리기 ( 한 파일에서 ) 

<?php
// MySQL 연결 정보
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "test_db";

// MySQL 연결
$conn = new mysqli($servername, $username, $password, $dbname);

// 연결 확인
if ($conn->connect_error) {
    die("연결 실패: " . $conn->connect_error);
}

if ($_SERVER["REQUEST_METHOD"] == "POST") {
    $name = isset($_POST['name']) ? $_POST['name'] : '';

    // SQL 삽입 (SQL Injection 방지를 위해 Prepared Statement 사용)
    $stmt = $conn->prepare("INSERT INTO users (name) VALUES (?)");
    $stmt->bind_param("s", $name);
    
    if ($stmt->execute()) {
        echo "데이터 저장 성공!";
    } else {
        echo "오류 발생: " . $stmt->error;
    }

    $stmt->close();
}

$conn->close();
?>

<!DOCTYPE html>
<html>
<head>
    <title>MySQL Form (Single File)</title>
</head>
<body>
    <form method="post">
        <label>이름: <input type="text" name="name" required></label>
        <button type="submit">저장</button>
    </form>
</body>
</html>

 

 

8. 쿼리 날리기 ( 쿼리 날리는 부분은 다른 파일로 처리 ) 

<!DOCTYPE html>
<html>
<head>
    <title>MySQL Form (Separate File)</title>
</head>
<body>
    <form action="process.php" method="post">
        <label>이름: <input type="text" name="name" required></label>
        <button type="submit">저장</button>
    </form>
</body>
</html>

 

<?php
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "test_db";

// MySQL 연결
$conn = new mysqli($servername, $username, $password, $dbname);

// 연결 확인
if ($conn->connect_error) {
    die("연결 실패: " . $conn->connect_error);
}
?>

 

<?php
require 'db.php'; // DB 연결 파일 포함

if ($_SERVER["REQUEST_METHOD"] == "POST") {
    $name = isset($_POST['name']) ? $_POST['name'] : '';

    // SQL 삽입 (Prepared Statement 사용)
    $stmt = $conn->prepare("INSERT INTO users (name) VALUES (?)");
    $stmt->bind_param("s", $name);

    if ($stmt->execute()) {
        echo "데이터 저장 성공!";
    } else {
        echo "오류 발생: " . $stmt->error;
    }

    $stmt->close();
}

$conn->close();
?>

 

 

 

9. DB 연결 시에 include와 require의 차이점은? 

 

PHP 에서 다른 파일을 불러올 때 include와 require를 사용할 수 있다.

 

둘다 비슷하지만, 오류가 발생하였을 때 동작이 다르다.

구분 include require
파일 불러오기 파일을 포함. 없어도 코드는 계속 실행된다.  파일을 포함. 없으면 실행이 중단된다.
파일이 없을 때  warning 발생 후 나머지 코드를 실행 Fatal Error 발생 후 코드 중단
실행흐름 오류가 발생해도 코드는 계속 실행된다. 오류 발생 시 코드 즉시 중단
사용예시 선택적으로 포함할 때  반드시 필요한 파일일 때 

 

 

10. .inc 와 .php의 차이점은?

 

확장자 용도 보안
*.php php 코드 포함, 실행가능 웹서버가 php로 실행해서 내용이 보이지 않는다.
*.inc php 코드 포함, 주로 설정 파일로 사용한다. 직접 접근하면 코드가 그대로 노출될 위험이 있다. 

 

그렇다면 inc 파일을 사용했을 때 보안 위험이 있을까?

- *.inc 파일은 php가 아닌 일반 텍스트 파일처럼 취급된다.

- 웹서버가 설정되어있지 않으면, 브라우저에서 직접 열었을 때 코드가 그대로 노출될 가능성이 있다.

예를 들어서 다음과 같은 .inc 파일이 있다고 하자. config.inc

<?php
$db_user = "root";
$db_pass = "secret";
?>

 

만약에 https://example.com/config.inc로 접근하면 소스코드가 그대로 노출될 수 있다. 

 

그렇다면 이렇게 데이터베이스 설정은 어떻게 해야 보안적으로 안전할까?

1. 파일명을 .php로 변경한다. ( config.inc.php )

- php 파일이면 직접 접근해도 실행이 되기 때문에 코드가 노출되지 않는다.

- require 'config.inc.php'; 처럼 사용하면 된다.

 

2. .inc 파일을 웹 루트 외부에 저장하는 것이다.

- public_html (웹루트) 밖에 파일을 두면 브라우저에서 직접 접근할 수 없다.

 

3. .htaccess 설정으로 .inc 파일을 차단한다.

- apache 서버에서 .inc 파일을 차단하면 접근 불가능하다.

<Files "*.inc">
Order allow,deny
Deny from all
</Files>