include 'header.php'; wykonuje kod innego pliku PHP w tym miejscu skryptu, tak jakby został tam wklejony. require 'header.php'; robi to samo, ale jeśli pliku nie da się wczytać, require zatrzymuje skrypt krytycznym błędem, a include tylko wypisuje ostrzeżenie i działa dalej. Zwykle pierwszym zastosowaniem jest nagłówek i stopka wspólne dla wszystkich stron.
Blok najpierw zapisuje header.php i footer.php, żeby było co dołączać. Uruchom i spójrz na zakładkę Page:
Dołączone pliki to zwykłe pliki PHP: mogą zawierać HTML ze znacznikami <?= ?> i widzą zmienną $title ustawioną przed require. Zmień tytuł i uruchom ponownie; każda strona, która dołącza nagłówek, odebrałaby zmianę w tym jednym pliku.
include vs require
Jedyna różnica to zachowanie, gdy pliku brakuje lub nie da się go odczytać. include wypisuje dwa ostrzeżenia, daje false, a skrypt działa dalej:
Warning: include(sidebar.php): Failed to open stream: No such file or directory in /home/index.php on line 2
Warning: include(): Failed opening 'sidebar.php' for inclusion (include_path='.:/usr/share/php83') in /home/index.php on line 2
require wypisuje to samo ostrzeżenie, a potem rzuca Error, który kończy skrypt, jeśli nic go nie złapie:
PHP Warning: require(config.php): Failed to open stream: No such file or directory in /home/index.php on line 2
PHP Fatal error: Uncaught Error: Failed opening required 'config.php' (include_path='.:/usr/share/php83') in /home/index.php:2
Dlatego używaj require dla wszystkiego, bez czego strona nie zadziała (konfiguracja, biblioteki funkcji, pliki klas), a include dla części opcjonalnych. Dla części, której może zgodnie z założeniem brakować, najpierw sprawdź jej obecność, zamiast polegać na ostrzeżeniu:
Wynik:
Spring sale: 20% off
banner.php included, include returned int(1)
sidebar.php not found, skipped
include_once i require_once
Plik definiujący funkcję lub klasę można wczytać tylko raz: drugie wczytanie to błąd krytyczny, bo funkcja już istnieje.
Fatal error: Cannot redeclare greet() (previously declared in /home/helpers.php:2) in /home/helpers.php on line 2
Dzieje się tak, gdy tylko dwa pliki wykonają require 'helpers.php'. require_once i include_once pamiętają, które pliki zostały już wczytane, i za drugim razem je pomijają, zwracając true:
Wynik:
int(1)
bool(true)
bool(true)
Hello, Ada
Używaj form _once dla plików, które coś deklarują, a zwykłego include dla szablonów, które chcesz wypisać więcej niż raz. W projektach używających Composera autoloader wczytuje pliki klas za ciebie, więc wywołania require_once dla klas w większości znikają; zobacz Composer.
Zwracanie wartości z dołączonego pliku
return na najwyższym poziomie dołączonego pliku zatrzymuje ten plik i oddaje wartość wyrażeniu include lub require. Daje to czysty plik konfiguracyjny: bez zmiennych globalnych, tylko wartość, którą przypisujesz do dowolnej nazwy.
Wynik:
My Shop
shop
bool(false)
Tak działają pliki konfiguracyjne Laravela (config/app.php, config/database.php i pozostałe).
Zmienne i zasięg w dołączonych plikach
Dołączony kod wykonuje się w zasięgu linii, która go dołącza. Na górze skryptu widzi każdą zmienną globalną; wewnątrz funkcji widzi tylko zmienne lokalne tej funkcji. Na tej drugiej zasadzie działa malutki renderer szablonów: funkcja, której zmienne lokalne to dokładnie te zmienne, które ma widzieć szablon.
Zakładka Page pokazuje obie listy, wyrenderowane z jednego pliku szablonu. Ponieważ include wykonuje się wewnątrz render(), szablon widzi $heading i $products, ale nie $secret. Forma foreach ... endforeach użyta w szablonie to składnia alternatywna, którą PHP oferuje dla szablonów HTML.
Ścieżki dołączania i DIR
Ścieżka taka jak 'helper.php' nie jest rozwiązywana względem pliku zawierającego include. PHP przeszukuje ustawienie include_path (które zwykle zaczyna się od ., bieżącego katalogu roboczego), a dopiero potem własny folder pliku dołączającego. Dlatego wewnątrz partials/nav.php include 'helper.php' może wczytać zupełnie inny helper.php z katalogu głównego projektu. __DIR__, katalog bieżącego pliku, usuwa zgadywanie:
Wynik:
loaded the root helper.php
loaded partials/helper.php
__DIR__ in nav.php is partials
Pisz każde dołączenie jako __DIR__ . '/relative/path.php'. Katalog roboczy zależy od tego, jak uruchomiono skrypt (serwer WWW, zadanie cron, wiersz poleceń z innego folderu), a __DIR__ nigdy się nie zmienia.
Nigdy nie dołączaj pliku wskazanego przez użytkownika
Częsty pierwszy router czyta nazwę strony z adresu URL: include $_GET['page'] . '.php';. Pozwala to odwiedzającemu wybrać, który plik na serwerze się wykona, na przykład ?page=../../config (local file inclusion), a przy starych ustawieniach nawet plik z innego serwera. Zamiast tego przypisz dozwolone nazwy do plików. Uruchom blok i klikaj linki: każde kliknięcie uruchamia skrypt ponownie z innym $_GET['page'].
Do require mogą trafić tylko trzy nazwy z $pages; link ../secret dostaje stronę „Not found”. Bezpieczny odczyt wartości z żądania opisuje strona _POST.
Najczęściej zadawane pytania
Czym różni się include od require w PHP?
Oba wczytują i wykonują inny plik PHP. Jeśli pliku nie da się wczytać, require zatrzymuje skrypt krytycznym błędem, a include wypisuje ostrzeżenie, zwraca false i pozwala skryptowi działać dalej. Używaj require dla plików, bez których strona nie zadziała, takich jak konfiguracja i biblioteki funkcji.
Kiedy używać require_once zamiast require?
Używaj require_once dla plików, które definiują funkcje, klasy lub stałe. Dwukrotne wczytanie takiego pliku to błąd krytyczny (Cannot redeclare), a require_once pomija plik, jeśli został już wczytany. Szablony, które chcesz wypisać kilka razy, dołączaj zwykłym include.
Czy dołączony plik PHP może zwrócić wartość?
Tak. return na najwyższym poziomie dołączonego pliku kończy go i staje się wartością wyrażenia include lub require: $config = require 'config.php'; z return ['debug' => true]; w config.php. Bez return include daje 1.
Czy dołączony plik ma dostęp do moich zmiennych?
Tak. Dołączony kod wykonuje się w zasięgu linii, która go dołącza: na górze skryptu widzi zmienne globalne, a wewnątrz funkcji widzi jej zmienne lokalne i nic poza nimi. Zmienne, które tworzy, trafiają do tego samego zasięgu.
Pisać include('file.php') czy include 'file.php'?
Oba działają, bo include i require to konstrukcje języka, a nie funkcje; nawiasy tylko otaczają ścieżkę. Większość przewodników stylu pisze require 'file.php'; bez nich.