PHPでWebサイトを作っていると、こんなコードに出会うことがあります。
include 'header.php';
あるいは、
require 'config.php';
さらに、
require_once 'config.php';
……今度は何でしょう。
AIにPHPを書いてもらったら、いつの間にか入っていた。
WordPressや既存のPHPを触っていたら出てきた。
そんな人もいると思います。
でも、includeやrequireの役割はそれほど難しくありません。
一言でいえば、
「別のPHPファイルを、ここで読み込んで使う」
ための仕組みです。
今回は、なぜわざわざファイルを分けるのか、includeとrequireは何が違うのか、そして「読み込めない!」となったときにどこを確認すればいいのかを見ていきます。
事件発生:全ページのメニューを直すことになった
こんなWebサイトを作ったとします。
index.php
about.php
service.php
contact.php
4ページあります。
そして、それぞれに同じメニューを書いていました。
<nav>
<a href="/">ホーム</a>
<a href="/about.php">私たちについて</a>
<a href="/service.php">サービス</a>
<a href="/contact.php">お問い合わせ</a>
</nav>
ある日、
「メニューに料金ページを追加してください」
と言われました。
もちろん修正できます。
でも、このメニューを4ページ全部に直接書いていたら、
4ファイル全部を修正する必要があります。
10ページなら10ファイル。
100ページなら……。
かなり大変です。
そこで、
同じ部分を別ファイルにしておこう
という考え方が出てきます。
共通部分をheader.phpにしてみる
たとえばメニュー部分を、
header.php
というファイルにします。
中身はこんな感じです。
<nav>
<a href="/">ホーム</a>
<a href="/about.php">私たちについて</a>
<a href="/service.php">サービス</a>
<a href="/contact.php">お問い合わせ</a>
</nav>
そしてindex.phpでは、
<?php include 'header.php'; ?>
と書きます。
すると、その場所でheader.phpが読み込まれます。
イメージとしては、
index.php
上のHTML
↓ここで
include 'header.php';
↓header.phpの内容が入る
下のHTML
という感じです。
これならメニューを変更するとき、
header.phpを1ファイル修正するだけ
で済みます。
includeは「ファイルを読み込む」
まずは、
include 'header.php';
です。
難しく考えなくて大丈夫です。
「ここにheader.phpを読み込んでね」
くらいの意味です。
たとえば、
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>サンプルサイト</title>
</head>
<body>
<?php include 'header.php'; ?>
<main>
<h1>ホームページ</h1>
<p>ここが本文です。</p>
</main>
</body>
</html>
なら、includeを書いた場所にheader.phpの内容が読み込まれます。
じゃあrequireは何?
続いて、
require 'config.php';
です。
requireも基本的な役割は同じです。
別ファイルを読み込みます。
では、なぜ2種類あるのでしょう?
大きな違いは、
読み込みに失敗したときの扱い
です。
includeとrequireの違い
たとえば、
include 'header.php';
と書いたのに、header.phpが見つからなかったとします。
includeでは警告が出ても、その後の処理を続けようとします。
一方、
require 'config.php';
でconfig.phpが見つからなければ、そこで処理を続けられなくなります。
かなりざっくり表すと、
| 書き方 | 読み込み失敗時 |
|---|---|
include | 警告は出るが、その後も処理を続ける |
require | エラーになり、その先の処理を止める |
です。
どっちを使えばいいの?
ここで、
「じゃあ全部includeでよくない?」
と思うかもしれません。
でも、読み込めなかったら困るファイルがあります。
たとえば、
require 'config.php';
このconfig.phpに、プログラムが動くために必要な設定が入っているとします。
それが読み込めていないのに、そのまま処理を続けても困ります。
そんな、
「これがないと処理を続けられない」
というファイルにはrequireを使う考え方があります。
一方、サイトの一部分などで、読み込みに失敗しても後続処理自体は継続できる場合にはincludeが使われることがあります。
初心者のうちは、
必須ならrequire、失敗しても処理を継続できるならinclude
くらいで大丈夫です。
require_onceの「once」って何?
AIが作ったPHPでは、
require_once 'config.php';
を見ることも多いと思います。
onceは、
一度
という意味です。
つまり、
「このファイルは一度だけ読み込んでね」
という指定です。
なぜそんなものが必要なのでしょう。
同じファイルを2回読み込むと困ることがある
たとえばfunctions.phpに、
<?php
function sayHello()
{
echo 'こんにちは';
}
という関数を作ったとします。
そして何らかの理由で、
require 'functions.php';
require 'functions.php';
と2回読み込んでしまった。
するとPHPから見ると、
同じsayHello()をもう一度作ろうとしている
状態になります。
これがエラーの原因になることがあります。
そこで、
require_once 'functions.php';
を使います。
すでに読み込まれていれば、もう一度は読み込みません。
include_onceもある
同じ考え方で、
include_once 'header.php';
もあります。
つまり4種類あります。
| 書き方 | 意味 |
|---|---|
include | ファイルを読み込む |
require | 必須ファイルとして読み込む |
include_once | 一度だけincludeする |
require_once | 一度だけrequireする |
全部を使い分けられなくても大丈夫です。
まず、
「別ファイルを読み込んでいるんだ」
と分かれば十分です。
事件発生:header.phpが読み込めない!
ここからが実践です。
こんな構成だったとします。
public_html/
├─ index.php
├─ parts/
│ └─ header.php
└─ contact/
└─ index.php
トップページのindex.phpから、
include 'parts/header.php';
とした。
これは読み込めた。
ところがcontact/index.phpでも同じように、
include 'parts/header.php';
としたら、
読み込めない。
なぜでしょう?
また「パス」が出てきた
ここで以前勉強した、
相対パス
が戻ってきます。
contact/index.phpから見ると、
parts/header.php
は、
contact/
└─ parts/
└─ header.php
のような場所を探すことになります。
でも実際のpartsは、
public_html/
├─ parts/
│ └─ header.php
└─ contact/
└─ index.php
こちらです。
つまり、一度上へ戻る必要があります。
include '../parts/header.php';
となります。
「ファイルはあるのに読み込めない」が起こる
初心者のうちは、
header.phpはちゃんとサーバーにある!
となりがちです。
その通りです。
でも重要なのは、
「あるかどうか」だけではなく、「PHPが指定された場所から見つけられるか」
です。
この考え方は、第6回で扱った相対パス・絶対パスとまったく同じです。
PHPの記事がバラバラに存在しているのではなく、少しずつつながってきました。
__DIR__って何?
PHPを見ていると、こんなコードも出てきます。
require_once __DIR__ . '/config.php';
急に難しそうになりました。
でも、
__DIR__
は、
「このPHPファイル自身が置かれているディレクトリ」
を表すものです。
たとえば、
/home/example/public_html/app/index.php
というPHPの中で__DIR__を使えば、基本的にはそのファイルがある、
/home/example/public_html/app
を基準にできます。
そのため、
require_once __DIR__ . '/config.php';
なら、
「このPHPと同じ場所にあるconfig.phpを読み込む」
という意図が分かりやすくなります。
なぜAIは__DIR__をよく使うの?
相対パスは、
どの場所を基準に読み込まれるのか
で混乱することがあります。
そこで、
__DIR__
を使って、
「このファイルの場所を基準にする」
と明確にする書き方があります。
たとえば、
require_once __DIR__ . '/config.php';
をAIが書いてきたら、
「謎の記号だ!」
ではなく、
「config.phpの場所をはっきり指定しているんだな」
くらいに読めれば十分です。
読み込みエラーが出たら、エラー文を読む
たとえば、
require 'config.php';
で読み込めなかったとき、
環境によってはエラーに、
Failed to open stream
や、
Failed opening required
といった言葉が出ることがあります。
英語なので難しく見えますが、
「ファイルを開けなかった」
と考えれば、調査する方向が見えてきます。
まず、
- ファイル名は合っている?
- ファイルは存在する?
- フォルダは合っている?
../は必要?- 大文字・小文字は合っている?
を確認します。
AIに相談するときは「ファイル構成」を見せる
includeやrequireの問題では、コードだけでなく、
ファイルがどこにあるのか
が重要です。
だからAIへ、
header.phpが読み込めません。
だけではなく、
public_html/
├─ index.php
├─ parts/
│ └─ header.php
└─ contact/
└─ index.php
とファイル構成を見せて、
contact/index.phpからparts/header.phpを読み込みたいです。
と伝えると、かなり分かりやすくなります。
これは実際のWeb制作でも非常に役立ちます。
コードだけではなく、ファイル構成も情報のひとつ
です。
「全部1ファイル」から卒業するための仕組み
ここまでPHP学科では、ひとつのPHPファイルの中身を中心に見てきました。
でも実際のWebサイトやWebアプリでは、
header.php
footer.php
config.php
functions.php
send.php
など、複数のPHPファイルが協力して動くことがあります。
includeやrequireは、
複数ファイルでPHPを組み立てるための基本的な仕組み
のひとつです。
AIにWebサイトを作ってもらう場合でも、この考え方を知っていると、
「なんでこんなにPHPファイルがいっぱいあるの?」
から、
「役割ごとに分けて、必要な場所で読み込んでいるんだな」
へ変わります。
ここが今回の大事なところです。
今日の合格ライン
今回は4種類の書き方が登場しました。
でも全部暗記しなくて大丈夫です。
今日の合格ラインは、
include・requireは、別ファイルを読み込むために使う。
そして、
読み込めないときはパスを確認する。
さらに、
require_once
を見たら、
「必要なファイルを一度だけ読み込むんだな」
と分かる。
ここまでで十分です。
ワンポイント答え合わせ
次のファイル構成があります。
public_html/
├─ parts/
│ └─ header.php
└─ contact/
└─ index.php
contact/index.phpからheader.phpを読み込みたい。
どちらが正しいでしょう?
A
include 'parts/header.php';
B
include '../parts/header.php';
答えは、
Bです。
contactフォルダから一度、
../
で上の階層へ戻ってから、
parts/header.php
へ進みます。
以前勉強したパスの知識が、ここでも使えました。
PHPは新しいことを次々暗記するというより、
覚えた小さな知識を組み合わせて理解していく
と、だんだん見える範囲が広がっていきます。
AIにコードを書いてもらう場合も同じです。
コードを全部書けなくても、
「このファイルは何のためにある?」
「どこから読み込んでいる?」
が分かれば、トラブルが起きたときに調査できます。
