file_get_contents('notes.txt')는 파일 전체를 읽어 문자열 하나로 반환합니다. 파일을 읽을 수 없으면 false를 반환합니다. 쓰려면 파일을 만들거나 안의 내용을 대체하는 file_put_contents('notes.txt', $text)를 쓰세요.
출력:
Buy milk
Call Ada
Write docs
29 bytes
3 lines
이 블록은 작업할 파일이 있도록 먼저 notes.txt를 쓴 다음 다시 읽습니다. 'notes.txt' 같은 경로는 현재 작업 디렉터리를 기준으로 합니다. 웹 앱에서는 __DIR__ . '/notes.txt'처럼 스크립트 자신의 폴더로부터 경로를 만드세요.
file_put_contents()로 쓰기와 이어 쓰기
file_put_contents()는 쓴 바이트 수를 반환하고, 실패하면 false를 반환합니다. 기본적으로 파일을 덮어씁니다. FILE_APPEND 플래그는 대신 끝에 덧붙이며, 간단한 로그가 이렇게 동작합니다. LOCK_EX는 두 요청이 같은 순간에 쓰는 것을 막습니다.
출력:
Wrote 8 bytes
started
step 1 done
step 2 done
replaced
abc
5 bytes
배열을 저장했다가 배열로 다시 얻으려면 json_encode()로 JSON을 쓰고 json_decode()로 읽으세요.
file()로 파일을 한 줄씩 읽기
file()은 파일을 요소마다 한 줄인 배열로 읽습니다. FILE_IGNORE_NEW_LINES를 넘기지 않으면 각 줄 끝에 줄바꿈이 남고, FILE_SKIP_EMPTY_LINES는 빈 줄을 버립니다(FILE_IGNORE_NEW_LINES와 함께일 때만 동작합니다).
출력:
string(9) "Buy milk
"
1. Buy milk
2. Call Ada
3. Write docs
3 tasks
file()과 file_get_contents()는 파일 전체를 메모리에 불러옵니다. 설정 파일이나 몇 메가바이트짜리 로그에는 괜찮습니다. 수백 메가바이트 파일이라면 대신 fopen()과 fgets()로 한 번에 한 줄씩 읽으세요.
읽기 전에 파일이 있는지 확인하기
파일이 없으면 file_get_contents()는 false를 반환하고 PHP가 경고를 출력합니다.
Warning: file_get_contents(missing.txt): Failed to open stream: No such file or directory in /home/index.php on line 2
먼저 is_file()(디렉터리가 아닌 존재하는 파일)이나 file_exists()(파일이나 디렉터리)로 확인하고, 빈 파일은 역시 거짓으로 취급되는 ""를 반환하므로 결과는 항상 === false와 비교하세요.
출력:
empty.txt exists file
missing.txt missing
. exists directory
Cannot read missing.txt, using defaults
bool(false)
bool(true)
0 bytes
@file_get_contents()로 경고를 숨기지 마세요. 먼저 확인하거나 false를 처리하면 다른 무언가가 잘못되었을 때 에러가 계속 보입니다.
파일의 일부 읽기
네 번째와 다섯 번째 인수는 시작할 바이트 오프셋과 읽을 바이트 수입니다. 음수 오프셋은 파일 끝에서부터 셉니다. 이름 있는 인수를 쓰면 그 사이의 두 인수를 건너뛸 수 있습니다.
출력:
HEADER
line 2
last line
오프셋은 문자가 아니라 바이트를 셉니다. UTF-8에서 일본어 문자(한글도)는 3바이트이므로, 그 중간의 오프셋은 문자를 반으로 자릅니다. 문자 단위로 작업하려면 문자열 전체를 읽고 mb_substr()를 쓰세요.
웹 페이지에 텍스트 파일 보여 주기
파일 내용은 텍스트이고, HTML에 출력하는 텍스트는 이스케이프해야 합니다. 그렇지 않으면 파일 속 <가 태그가 됩니다. htmlspecialchars()가 이스케이프하고 nl2br()가 줄바꿈을 <br> 태그로 바꿉니다. 실행하고 Page 탭을 보세요.
htmlspecialchars()를 지우고 다시 실행해 보세요. 이제 페이지가 "v1.2: Fixed"에서 끝납니다. 브라우저가 <title>을 진짜 태그로 읽고 그 뒤의 모든 것을 페이지 제목으로 삼켜 버리기 때문입니다. 사용자가 쓸 수 있는 모든 것에서 이것이 왜 중요한지는 htmlspecialchars() 페이지에서 다룹니다.
file_get_contents()로 URL 읽기
allow_url_fopen이 켜져 있으면(php.ini의 기본값) file_get_contents()는 URL도 읽고 응답 본문을 반환합니다. 스트림 컨텍스트로 메서드, 헤더, 본문, 시간 제한을 추가합니다.
<?php
$html = file_get_contents('https://example.com/');
$context = stream_context_create([
'http' => [
'method' => 'POST',
'header' => "Content-Type: application/json\r\n",
'content' => json_encode(['name' => 'Ada']),
'timeout' => 5,
'ignore_errors' => true, // return the body of 4xx/5xx responses too
],
]);
$response = file_get_contents('https://api.example.com/users', false, $context);
if ($response === false) {
// DNS failure, timeout, or a refused connection
}
재시도, 제한이 있는 리다이렉트, 명확한 에러 코드에는 cURL이나 Guzzle 같은 HTTP 클라이언트 라이브러리가 더 나은 도구입니다.
file_get_contents, file(), fopen() 비교
| 원하는 것 | 사용 | 메모리 |
|---|---|---|
| 파일 전체를 문자열 하나로 | file_get_contents() | 파일 전체 |
| 줄을 배열로 | file($path, FILE_IGNORE_NEW_LINES) | 파일 전체 |
| 한 번의 호출로 파일 쓰기나 대체 | file_put_contents() | 쓰는 데이터 |
| 로그에 한 줄 추가 | file_put_contents($path, $line, FILE_APPEND | LOCK_EX) | 한 줄 |
| 큰 파일을 한 줄씩 읽기, 또는 CSV 행 | fgets()나 fgetcsv()와 함께 fopen() | 한 줄 |
| 열린 같은 파일을 읽고 쓰기 | r+, a+, c+와 함께 fopen() | 읽은 만큼 |
한 번 호출로 끝나는 함수는 파일을 열고, 읽거나 쓰고, 닫는 일을 대신 해 주므로 올바른 기본 선택입니다. 파일이 너무 커서 메모리에 담을 수 없거나 작업 사이에 열어 둬야 할 때 fopen()을 쓰세요.
자주 묻는 질문
PHP에서 파일을 문자열로 읽으려면 어떻게 하나요?
file_get_contents('path/to/file.txt')를 호출하세요. 파일 전체를 문자열로 반환하고, 파일을 읽을 수 없으면 false를 반환하므로 쓰기 전에 결과를 === false와 비교하세요.
PHP에서 파일에 이어 쓰려면 어떻게 하나요?
FILE_APPEND 플래그를 넘기세요: file_put_contents('log.txt', "new line\n", FILE_APPEND);. 이것이 없으면 file_put_contents()는 파일 전체를 대체합니다. 여러 요청이 동시에 쓸 수 있다면 LOCK_EX를 추가하세요(FILE_APPEND | LOCK_EX).
PHP에서 파일을 한 줄씩 읽으려면 어떻게 하나요?
작은 파일이라면 file('data.txt', FILE_IGNORE_NEW_LINES)가 요소마다 한 줄인 배열을 반환합니다. 큰 파일이라면 fopen()으로 열고 while 반복문에서 fgets()로 한 번에 한 줄씩 읽으세요. 메모리에는 한 줄만 유지됩니다.
file_get_contents가 false를 반환하는 이유는 무엇인가요?
파일이 없거나, 경로가 생각과 다른 디렉터리를 기준으로 하거나, PHP에 읽을 권한이 없기 때문입니다. PHP는 Failed to open stream: No such file or directory 같은 경고도 출력합니다. is_file()과 is_readable()로 확인하고, 경로는 __DIR__로부터 만드세요.
file_get_contents로 URL을 읽을 수 있나요?
php.ini에서 allow_url_fopen이 켜져 있으면 가능합니다: file_get_contents('https://example.com/')는 응답 본문을 반환합니다. 헤더, POST 데이터, 시간 제한에는 stream_context_create()의 컨텍스트를 넘기고, 더 복잡한 경우에는 cURL이 에러 처리가 더 좋습니다.