PHP의 개념과 특징

  • PHP (Hypertext Preprocessor)는 서버 측에서 실행되는 스크립트 언어로, 주로 웹 개발에 사용됩니다. 동적 웹 페이지를 생성하거나 데이터베이스와 상호작용하는 데 적합합니다.
  • 특징
    - 서버 측 실행: 클라이언트가 아닌 서버에서 처리되어 보안성이 높음
    - 플랫폼 독립적: Windows, Linux, macOS 등 다양한 운영 체제에서 실행 가능
    - 오픈 소스: 무료로 사용 가능하며 커뮤니티 지원이 풍부
    - HTML 내장 가능: HTML 코드 안에 PHP 코드를 삽입해 동적 콘텐츠 생성
    - 다양한 데이터베이스 지원: MySQL, PostgreSQL, SQLite 등과 쉽게 연동
    - 간단한 학습 곡선: 초보자도 쉽게 접근 가능

 

PHP 기본 문법과 변수

  • 기본 문법
    - PHP 코드는 <?php로 시작하고 ?>로 끝남 (종료 태그는 생략 가능)
    - 문장은 세미콜론(;)으로 끝남
    - 주석: 한 줄 주석(// 또는 #), 여러 줄 주석(/* */)
  • 변수
    - 변수는 $로 시작하며, 선언 시 데이터 타입을 명시하지 않음 (동적 타이핑)
    - 예: $name = "홍길동"; $age = 30
    - 변수 이름은 대소문자 구분하며, 숫자로 시작할 수 없음
  • 스코프
    - 지역 변수: 함수 내에서만 유효
    - 전역 변수: global 키워드 또는 $GLOBALS 배열로 접근
    - 정적 변수: static 키워드로 함수 호출 간 값 유지
  • 예제
<?php
$name = "홍길동";
$age = 30;
echo "이름: $name, 나이: $age";
?>

 

 

함수의 정의와 사용

  • 함수 정의
    - function 키워드로 정의하며, 매개변수와 반환값은 선택적
  • 기본 문법
function 함수명(매개변수) {
    // 코드
    return 값; // 선택적
}
  • 예제
<?php
function add($a, $b) {
    return $a + $b;
}

$result = add(3, 5);
echo $result; // 출력: 8
?>
  • 특징
    - 기본값 매개변수: function greet($name = "Guest") { ... }
    - 가변 인자: ...$args를 사용해 가변 개수의 인자 처리
    - 익명 함수: Closure로 사용 가능
$sayHello = function($name) {
    return "Hello, $name!";
};
echo $sayHello("홍길동"); // 출력: Hello, 홍길동!

 

 

폼 데이터 처리

  • PHP는 HTML 폼 데이터를 $_GET, $_POST, $_REQUEST 배열로 처리
    - GET: URL 쿼리 문자열로 데이터 전송 (보안 낮음, 데이터 크기 제한)
    - POST: HTTP 바디로 데이터 전송 (보안 높음, 대용량 가능)
  • 예제
<!-- form.html -->
<form action="process.php" method="post">
    이름: <input type="text" name="name">
    나이: <input type="number" name="age">
    <input type="submit" value="제출">
</form>
<!-- process.php -->
<?php
if ($_SERVER["REQUEST_METHOD"] == "POST") {
    $name = $_POST["name"];
    $age = $_POST["age"];
    echo "이름: $name, 나이: $age";
}
?>

 

 

데이터베이스와의 연동

  • PHP는 PDO 또는 mysqli 확장을 사용해 데이터베이스와 연동
  • PDO 예제 (MySQL 연동)
<?php
// PHP 코드의 시작을 나타내는 태그

$host = "localhost";
// 데이터베이스 서버의 호스트 주소를 설정 (여기서는 로컬 서버를 의미)

$dbname = "mydb";
// 연결하려는 데이터베이스의 이름을 지정

$username = "root";
// 데이터베이스에 접근하기 위한 사용자 이름 (기본적으로 MySQL의 루트 사용자)

$password = "";
// 데이터베이스 사용자 계정의 비밀번호 (여기서는 비밀번호 없음)

try {
// 예외 처리를 시작하여 데이터베이스 관련 오류를 캐치하기 위한 블록

    $pdo = new PDO("mysql:host=$host;dbname=$dbname", $username, $password);
    // PDO 객체를 생성하여 MySQL 데이터베이스에 연결 (DSN 문자열로 호스트와 데이터베이스 이름 지정)

    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    // PDO의 오류 모드를 예외 모드로 설정하여 오류 발생 시 예외를 던지도록 함

    // 데이터 조회
    $stmt = $pdo->query("SELECT * FROM users");
    // users 테이블에서 모든 데이터를 조회하는 SQL 쿼리를 실행하고 결과를 $stmt에 저장

    while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
    // 조회된 결과를 한 행씩 연관 배열(PDO::FETCH_ASSOC) 형태로 가져와 반복

        echo "ID: {$row['id']}, 이름: {$row['name']}<br>";
        // 각 행의 id와 name 값을 출력하고 줄바꿈(<br>) 추가

    }

    // 데이터 삽입
    $stmt = $pdo->prepare("INSERT INTO users (name, age) VALUES (:name, :age)");
    // users 테이블에 name과 age 값을 삽입하는 준비된 문장(prepared statement)을 생성

    $stmt->execute(['name' => '홍길동', 'age' => 30]);
    // 준비된 문장에 name과 age 값을 바인딩하여 실행 (홍길동, 30 삽입)

} catch (PDOException $e) {
// PDO 관련 예외가 발생하면 이를 캐치하여 처리

    echo "에러: " . $e->getMessage();
    // 예외 메시지를 출력하여 어떤 오류가 발생했는지 표시

}
?>
// PHP 코드의 종료를 나타내는 태그 (생략 가능)

 

  • mysqli 예제
<?php
// PHP 코드의 시작을 나타내는 태그

$conn = new mysqli("localhost", "root", "", "mydb");
// mysqli 객체를 생성하여 MySQL 데이터베이스에 연결 (호스트: localhost, 사용자: root, 비밀번호: 없음, 데이터베이스: mydb)

if ($conn->connect_error) {
// 데이터베이스 연결이 실패했는지 확인 (connect_error 속성에 오류 메시지가 있으면 실패)

    die("연결 실패: " . $conn->connect_error);
    // 연결 실패 시 오류 메시지를 출력하고 스크립트 실행을 종료

}

// 데이터 조회
$result = $conn->query("SELECT * FROM users");
// users 테이블에서 모든 데이터를 조회하는 SQL 쿼리를 실행하고 결과를 $result에 저장

while ($row = $result->fetch_assoc()) {
// 조회된 결과를 한 행씩 연관 배열 형태로 가져와 반복

    echo "ID: {$row['id']}, 이름: {$row['name']}<br>";
    // 각 행의 id와 name 값을 출력하고 줄바꿈(<br>) 추가

}

$conn->close();
// 데이터베이스 연결을 종료하여 리소스를 해제

?>
// PHP 코드의 종료를 나타내는 태그 (생략 가능)

 

 


다음과 같은 내용에 도전해봅시다.

 

1. php 설치 후 apache, MYSQL과 연결해보기

sudo apt install php libapache2-mod-php php-mysql -y

php -v

 

1-1. PHP와 Apache, MySQL 연동 테스트

테스트 PHP 파일 생성

sudo nano /var/www/html/test.php

 

PHP 코드 입력

<?php
phpinfo();
?>

 

브라우저에서 ip/test.php 접속하여 PHP 정보 페이지 확인

 

 

1-2. MySQL 연동 테스트

1-2-1. MySQL 데이터베이스 및 테이블 생성

sudo mysql -u root -p
CREATE DATABASE mydb;
USE mydb;
CREATE TABLE users (id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100), age INT);
INSERT INTO users (name, age) VALUES ('홍길동', 30);

 

1-2-2. PHP로 MySQL 연결 테스트

sudo nano /var/www/html/root_testdb.php

 

아래 php 코드 입력

<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

$conn = new mysqli("172.31.85.190", "root", "your_password", "mydb");

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

echo "MySQL 연결 성공!<br>";
$conn->close();
?>

 

실행 결과

 

위 사진처럼 error의 화면을 볼 수 있는데, 이러한 오류가 뜨는 이유는 root 계정이 localhost에서만 접속 가능하도록 설정되어 있어 오류가 발생합니다.

 

1-2-3. PHP로 MySQL 연결 테스트(다른 계정 생성하여 사용)

MySQL 접속

sudo mysql -u root -p

 

모든 호스트에서 접속 가능한 사용자 생성
CREATE USER 'testuser'@'%' IDENTIFIED WITH mysql_native_password BY 'testpassword';
GRANT ALL PRIVILEGES ON mydb.* TO 'testuser'@'%';
FLUSH PRIVILEGES;

 

사용자 확인

 - host가 %로 출력되어야 함

SELECT user, host FROM mysql.user WHERE user = 'testuser';

 
MySQL 네트워크 설정 수정
sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf

 

bind-address 설정 변경

[mysqld]
bind-address = 0.0.0.0

 

Mysql 재시작

sudo systemctl restart mysql

 

 

MYSQL 접속(testuser 사용자)

mysql -h 172.31.85.190 -u testuser -p

 

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

CREATE DATABASE IF NOT EXISTS mydb;
USE mydb;
CREATE TABLE IF NOT EXISTS users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(100),
    age INT
);
INSERT INTO users (name, age) VALUES ('김철수', 25), ('이영희', 30);

 

데이터 확인

SELECT * FROM users;

 

PHP 코드 작성

sudo nano /var/www/html/testdb.php

 

아래 PHP 코드 작성

<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

$conn = new mysqli("172.31.85.190", "testuser", "testpassword", "mydb");

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

echo "MySQL 연결 성공!<br>";

$result = $conn->query("SELECT * FROM users");
if ($result === false) {
    die("쿼리 오류: " . $conn->error);
}

while ($row = $result->fetch_assoc()) {
    echo "ID: {$row['id']}, 이름: {$row['name']}, 나이: {$row['age']}<br>";
}

$conn->close();
?>

 

실행결과

 

 

2. GET과 POST의 차이점 이해하기

 - GET과 POST는 HTTP 프로토콜에서 데이터를 서버로 전송하는 두 가지 주요 메서드입니다.

항목 GET POST
데이터 전송 방식 URL 쿼리 문자열에 포함 (?key=value&key2=value2) HTTP 요청 바디에 포함
보안성 데이터가 URL에 노출되어 보안 낮음 데이터가 바디에 숨겨져 있어 보안성 높음
데이터 크기 브라우저/서버 제한으로 소량 데이터 (약 2KB~4KB) 대용량 데이터 전송 가능 (서버 설정에 따라 다름)
용도 데이터 조회 (검색, 페이지 이동 등) 데이터 생성/수정 (폼 제출, 파일 업로드 등)
캐싱 브라우저에 캐싱 가능 (북마크 가능) 캐싱되지 않음
멱등성 멱등 (동일 요청 반복 시 동일 결과) 비멱등 (동일 요청이 다른 결과 초래 가능)
예제 <form method="get" action="search.php"> <form method="post" action="submit.php">

 

- 예제 코드
1. GET

get_test.html 파일 생성

sudo nano get_test.html

 

아래 HTML 코드 입력

<form method="get" action="search.php">
    <input type="text" name="query">
    <input type="submit" value="검색">
</form>

 

search.php 파일 생성

sudo nano search.php

 

아래 php 코드 입력

<!-- search.php -->
<?php
$query = $_GET['query'];
echo "검색어: $query";
?>

 

실행 결과

 - URL: search.php?query=1234

 

2. POST

post_test.html 파일 생성

sudo nano post_test.html

 

아래 HTML 코드 입력

<form method="post" action="submit.php">
    <input type="text" name="username">
    <input type="submit" value="제출">
</form>

 

 

실행결과

 - URL에 나타나지 않음

 

3. 파일 업로드 방법 이해하기

- PHP에서 파일 업로드는 HTML 폼과 $_FILES 배열을 사용해 처리합니다

upload.html 파일 생성

sudo nano upload.html

 

아래 HTML 코드 작성

 - enctype="multipart/form-data": 파일 업로드를 위해 필수
 - name="userfile": 서버에서 참조할 파일 입력 이름

<form action="upload.php" method="post" enctype="multipart/form-data">
    <input type="file" name="userfile">
    <input type="submit" value="업로드">
</form>

 

upload.php 파일 생성

sudo nano upload.php

 

아래 php 코드 작성

<!-- upload.php -->

// PHP 코드의 시작을 나타내는 태그
<?php

// HTTP 요청 메서드가 POST인지, 그리고 'userfile'이라는 이름의 파일이 업로드되었는지 확인
if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_FILES['userfile'])) {

    // 업로드된 파일 정보를 $_FILES 배열에서 가져와 $file 변수에 저장
    $file = $_FILES['userfile'];

    // 파일 정보
    // 업로드된 파일의 원본 이름을 $name 변수에 저장 (예: "example.jpg")
    $name = $file['name'];
    // 서버에 임시로 저장된 파일의 경로를 $tmp_name 변수에 저장 (예: "/tmp/php1234")
    $tmp_name = $file['tmp_name'];

    // 파일 업로드 중 발생한 오류 코드를 $error 변수에 저장 (0은 성공을 의미)
    $error = $file['error'];

    // 업로드된 파일의 크기를 바이트 단위로 $size 변수에 저장
    $size = $file['size'];

    // 업로드된 파일의 MIME 타입을 $type 변수에 저장 (예: "image/jpeg")
    $type = $file['type'];

    // 업로드 디렉토리
    // 파일을 저장할 서버 내 디렉토리 경로를 $upload_dir 변수에 설정 (예: "uploads/")
    $upload_dir = 'uploads/';

    // 업로드된 파일의 최종 저장 경로를 $upload_file 변수에 설정 (예: "uploads/example.jpg")
    $upload_file = $upload_dir . basename($name);

    // 오류 체크
    // 파일 업로드 오류가 없는지 확인 (UPLOAD_ERR_OK는 0, 즉 성공을 의미)
    if ($error == UPLOAD_ERR_OK) {

        // 파일 크기 제한 (예: 5MB)
        // 파일 크기가 5MB(5 * 1024 * 1024 바이트)를 초과하는지 확인
        if ($size > 5 * 1024 * 1024) {

            // 파일 크기가 제한을 초과하면 오류 메시지 출력
            echo "파일이 너무 큽니다.";
            
        // 임시 파일($tmp_name)을 지정한 경로($upload_file)로 이동 시도
        } elseif (move_uploaded_file($tmp_name, $upload_file)) {

            // 파일 이동이 성공하면 성공 메시지와 파일 이름을 출력
            echo "파일 업로드 성공: $name";

        // 파일 이동이 실패한 경우
        } else {

            // 파일 업로드 실패 메시지 출력
            echo "파일 업로드 실패.";


        }
    // 파일 업로드 중 오류가 발생한 경우
    } else {

        // 오류 코드와 함께 업로드 오류 메시지 출력 (예: "업로드 오류: 4"는 파일이 업로드되지 않음을 의미)
        echo "업로드 오류: " . $error;


    }
// 조건문 종료
}

// PHP 코드의 종료를 나타내는 태그 (생략 가능)
?>

 

업로드 디렉토리 설정

sudo mkdir /var/www/html/uploads
sudo chmod 777 /var/www/html/uploads

 

실행결과

 

+ Recent posts