1. php document에서 php 닫는 태그를 사용하지 않는 이유
php document를 parser하는 php parser에게 php 닫는 태그는 선택적(옵션)이다.→ 닫는 태그를 작성해도 되고, 안해도 된다는 의미 그러나 닫는 태그를 사용한다면(사용할 경우) 닫는 태그 다음에 오는 공백(whitespace)그 공백이 개발자, 사용자, 또는 FTP 애플리케이션이 추가한 것이든(introduced?) 상관없이원치 않는 출력, php 에러 또는 php 오류가(the latter) are suppressed(억제된 경우, 억제된다면)빈 화면을 유발할 수 있다. *** the latter are suppressed: php 오류가 억제된 경우 → php 오류가 숨겨진 경우
php 문서에서 php 닫는 태그 뒤에 공백이나 줄바꿈이 있는 상태에서 php가 헤더를 보내기 전에 공백을 출력해버리면
header() 함수에서 "headers already sent" 오류가 발생하고, 만약 오류 출력이 꺼져 있다면(error_reporting(0) 같은 경우)화면에는 아무것도 안 보이고, 브라우저에 빈 화면만 나올 수 있다. 문제는 있지만 사용자 입장에서 그저 빈 페이지로 보인다.
2. php 프로그램 폴더 구조
[project root]
└ public -------- root directory?
└ index.php /* 어플리케이션 진입점 /*
└ src
└ index.php /* 실제 앱 로직 */
└ vendor // 설치된 외부 라이브러리들
└ autoload.php /* composer가 자동 생성하는 파일, 클래스를 자동으로 로딩해주는 역할 */
composer.json /* 패키지 설정 파일 */
composer.lock /* 실제 설치된 버전 기록 */
root project/public 디렉토리는 웹 브라우저가 직접 접근할 수 있는 유일한 폴더다.
public 디렉토리 안에는 보편적으로 index.php, CSS, JS, image 파일(프론트엔드 리소스)과 같은 문서들이 존재한다.
서버(Apache) 설정은 public/을 루트 디렉토리로 지정한다.
src, vendor 같은 민감한 코드가 적힌 문서들을 갖는 디렉토리는 외부에서 접근할 수 없도록 public 바깥에 둔다.
src는 source의 줄임말, 실제 어플리케이션 코드(클래스, 컨트롤러, 모델 등)가 위치한다.
Composer의 PSR-4 오토로딩 규칙에 따라 여기에 네임스페이스별로 폴더가 구성된다.
*** Composer의 PSR-4 오토로딩과 네임스페이스별로 폴더가 구성된다는 말의 의미를 찾아보기
예를 들면 src/Controller/HomeController.php 와 같이 말이다.
vendor/ 폴더는 composer install 또는 composer update시 생성된다.
php 패키지 관리자 Composer가 설치한 모든 외부 라이브러리들이 여기에 있다.
절대 수정하지 말아야 하는 영역이다.
project/public/index.php
// php 코드의 시작을 알리는 php 열린 태그, 이 태그를 선언해주어야 브라우저나 php 엔진이 php 코드라고 인식한다.
<?php
// 해당 파일(지금 이 document) 안에서 함수에 전달되는 인자의 타입을 엄격하게 검사한다.
// 엄격한 타입 검사는 현재 파일에서 정의된 함수와 메서드에만 적용된다.
// php가 자동 형변환을 하지 않고, 선언된 매개변수 타입과 전달된 인자의 타입이 일치하지 않으면
// TypeError 예외를 발생시킨다.
// strict typing
declare(strict_types=1);
// composer를 사용한 프로젝트라면 이 줄은 필수다.
// vendor/autoload.php는 Composer가 자동으로 생성하는 autoloader 파일이다.
// autoload.php 파일이 composer로 설치한 외부 라이브러리들을 자동으로 로드하도록 설정한다.
// 외부 패키지를 use만 해도 바로 쓸 수 있도록 만들어준다.
require '../vendor/autoload.php';
require '../src/index.php'; // src/index.php 파일을 현재 스크립트에 포함(include)시킨다.
// src/index.php는 애플리케이션의 핵심 로직이나 라우터, 컨트롤러 실행 코드를 포함하고 있다.
declare(strict_types=1); 을 작성했을 때,
이 코드가 작성된 문서 내에 선언된 함수들이 프로그램에서 실행될 때
해당 함수들이 전달 받는 인자의 타입을 엄격하게 검사해서
실수 잘못된 타입이 전달되는 경우를 방지할 수 있고,
코드에 적은 대로 어떤 타입의 인자가 전달될 것이라는 예측 가능성이 증가함으로써
코드의 명확성 또한 분명해지는 이점이 있다.
이 선언문은 해당 php 파일 안에서 정의된 함수나 메서드가 실행될 때,
매개 변수(인자)의 타입을 엄격하게 검사하도록 지시한다.
→ 함수에 선언된 매개변수의 타입과 인자의 타입이 정확히 일치하지 않는다면
php는 자동 형변환을 하지 않고, TypeError 예외를 발생시킨다.
*** 코드의 명확성이라는 것은 함수 시그니처만 봐도 전달받을 매개변수 타입, 개수, 순서를 알 수 있다는 것이라고 이해함.
3. Thread-Safe의 의미
4. php 내장 웹 서버를 실행시키고, 서버의 주소를 localhost:8000으로 지정, 루트 디렉토리(public)를 지정하기

이 폴더내에서 php -S localhost:8000 명령어를 입력하면
"php 내장 웹 서버를 로컬에서 실행해라" 는 의미다.
- php: php 인터프리터(코드를 한 줄씩 번역/변환하는 역할을 수행하는 걸로 알고있다)를 실행
- -S: "Server" 모드로 실행 → php 내장 웹 서버를 사용한다.
- localhost:8000: 서버를 내 컴퓨터(로컬 호스트)에서 8000 포트로 열어라
php -S localhost:8000 -t htdocs
php 인터프린터한테 php 내장 웹 서버를 실행시키라고 하고,
내 컴퓨터의 8000번 포트에서 서버를 실행시키라고 명령하는 것.
-t 는 웹 서버의 문서 루트(document root)를 htdocs 폴더로 설정하는 것이다.
-t 옵션은 웹 서버의 문서 루트를 지정할 때 사용한다.
위의 구조로 보아 웹에서 직접 접근할 수 있는 폴더는 public이고,
public폴더에 index.php 파일이 있으므로 public폴더를 루트 디렉토리로 지정한다.
C:\php-8.4.11-Win32-vs17-x64>php -S localhost:8000 -t htdocs/public
# C:\php-8.4.11-Win32-vs17-x64/htdocs/public 디렉토리를 루트 디렉토리로 지정
웹 브라우저의 주소창에 localhost:8000 입력시 htdocs폴더의 index.php 파일이 실행된다.
순수 php파일의 경우 마지막 ?>(php 닫힌 태그)는 생략하는 것이 관례다.
5. composer란?
composer는 php에서 사용하는 의존성 관리 도구다.
내가 만든 php 프로젝트에서 사용하고 싶은 라이브러리(다른 사람이 만든 코드)를 자동으로 설치하고,
관리해주는 도구다. 외부 라이브러리를 사용하려면 .php 파일을 직접 다운받고 include/require로 관리해야 했다.
버전 관리가 어렵고, 라이브러리간의 충돌이 생기는 등 여러 불편함이 있었다.
composer는 명령어 한 줄로 필요한 라이브러리를 설치해주고,
해당 라이브러리가 의존하고 있는 라이브러리까지 자동으로 설치해주고,
라이브러리간 버전 충돌이 나지 않도록 각 라이브러리의 버전 요구사항을 분석해서 자동으로 조정해주고,
autoload.php 를 생성해서 클래스를 자동으로 로딩해주어 php 프로그램 작성을 용이하게 해주었다.
만들고자 하는 php 프로젝트에서 composer를 사용하려면
public, src 디렉토리가 존재하는(내가 직접 public, src 디렉토리 생성) 디렉토리 안에서
cmd 창을 켜고, composer init 명령을 입력하면, composer config generator가 시작된다.
composer 설정 값을 순차적으로 입력한다. package name (<vendor>/<name>)은
composer는 php 패키지를 <vendor>/<name> 형식으로 식별한다.
ex. { "name": "writer/framework" } → writer자리에는 공급자/제작자 이름을, framework위치에는 패키지 이름을 작성한다.
vendor는 패키지를 만든 사람이나 단체의 이름을 작성한다. 그 후로도 계속 질의응답이 나오는데 엔터를 계속 눌렀더니
src, vendor 폴더가 생성되고, composer.json 파일이 만들어짐. src 폴더를 직접 생성할 이유가 없었다.
composer.json --- 생성된 패키지 설정 파일
{
/* "name": Package name, including 'vendor-name/' prefix.
여기서 말하는 패키지 이름은 단순한 디렉토리 이름이 아니고,
composer가 인식하는 이 프로젝트(또는 라이브러리)의 고유한 이름(id)을 의미한다.
패키지는 지금 작업중인 php 프로젝트 전체를 composer에서는 하나의 "패키지"로 인식한다.
name은 지금 작성 중인 이 php 프로젝트의 식별자(id)인 셈이다.
*/
"name": "sungju/prj_1", /* composer 패키지의 고유한 이름(id) */
"autoload": {
"psr-4": { /* php 코드에서 사용되는 네임스페이스를 composer에게 알려주는 설정 */
/* "sungju\\Prj1\\" 이라는 네임스페이스는 실제 디렉토리 "src/"와 연결된다. */
"sungju\\Prj1\\": "src/"
}
}
}
그리고 src 디렉토리 내에 작성하는 .php 파일에 namespace를 sungju\Prj1으로 선언해준다.
6. composer로 라이브러리 설치하기
php에서 날짜와 시간을 다룰 때 가장 많이 사용되는 라이브러리 Carbon 설치하기
# composer.json 파일이 존재하는 디렉토리 안에서(루트 디렉토리)
# 하기 명령어를 입력하여 외부 라이브러리를 설치하기
composer require nesbot/carbon
외부 라이브러리를 설치했을 때 composer.lock 파일이 생기는 것을 확인할 수 있었다.
7. php문법
'<?php'와 '?>' 사이에 php 코드를 작성한다 → 선언(php 열린 태그와 닫힌 태그 사이) 후, php 코드 작성,
html 문법?과 함께 사용이 가능하다. php 코드만 작성하는 순수 php document인 경우 닫힌 태그 작성은 옵션이다.
php 문서에서 변수는 $기호로 시작한다.
php 문법으로 문자열을 연결할 때는 .(닷) 연산자를 사용할 것.
php 문법에서 변수를 바로 받아서 람다식으로 -> 화살표를 사용해서 함수를 호출하는 작업이 가능하다.
ex. echo "오늘은 ".$today -> format('Y-m-d H:i:s')." 입니다.";
var_dump($변수명); 코드는 변수의 상세한 정보(타입, 값, 구조 등)를 출력할 때 사용하는 디버깅 함수다.
문자열을 저장하고 있는 변수명의 경우 타입(문자열 길이) "실제값" 을 출력한다.
declare(strict_types=1); 선언은 php document 파일의 맨 위에 작성해야 한다.
strict_types declaration must be the very first statement in the script
define()으로 상수를 선언한다. ex. define("NAME", "name"); echo NAME;
상수를 정의하는 방법에는 const 키워드를 사용하는 방식도 가능하다. const NAME = "name";
상수는 한 번 정의하면 변경이 불가능하다. 코드를 실행하는 로직에 존재하는 경우에만 정의된다.
define()의 경우 조건에 따라 정의가 가능하며 정의된 상수는 해당 스크립트에서 계속 사용이 가능하다.→ 코드가 실제 실행될 때에 상수가 정의됨.echo 로 문자열을 출력한다.함수는 function 키워드로 정의하고, 매개변수의 기본 값을 정의할 수 있다.function greet($name="홍길동") : string { /*... */ } 여기서 string은 반환 값의 타입을 지정하는 것.
'공부기록용' 카테고리의 다른 글
| RESTful (0) | 2025.10.03 |
|---|---|
| php 관련 study 기록 (0) | 2025.08.29 |
| JVM이 관리하는 메모리(런타입 데이터 영역 - 프라이빗 메모리, 힙) (3) | 2025.08.25 |
| HashMap(일부 메서드를 직접 구현하며 이해하기, chatgpt 도움 받음, 아직도 잘 모르겠음) (4) | 2025.08.08 |
| IO - Input, Ouput(1) (2) | 2025.07.22 |