外部ファイル
プログラムが複雑になってくると、同じ処理が多く発生します。毎回同じコードを書いたり、コピー&ペーストするのは非効率なため、外部ファイルにして共通化します。
コンポーネント化
WebアプリではHTMLをたくさん記述しますが、内容が同じことも多くあります。そこで毎回同じことを書かずにコンポーネント(部品)化するのが効率的 です。 例えば、HTMLの headタグでタイトルやCSSの設定などをします。
ヘッダー部分が同じ
例えばHTMLのヘッダー部分が共通になったとき、1ファイルずつ記述するのは非効率です。
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?= $title ?></title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css"
rel="stylesheet">
</head>
外部ファイル読み込み方法
面倒な処理を共通化して、モデルファイルやモジュールといった外部ファイルを作成することが多くあります。外部ファイル読み込み方法はいくつかありますが、基本となるのが require と include です。
include
inclludeは指定されたファイルパスを外部ファイルを読み込みます。
include 'ファイルパス';
includeの方法
ファイル構成
├── head.php
└── main.php
「main.php」ファイルからHTMLのコンポーネントファイル「head.php」をincludeで読み込みます。
<?php
include 'head.php'
?>
require
requireにファイルパスを設定します。
require 'ファイルパス';
requireの方法
ファイル構成
├── functions.php
└── main.php
require 'functions.php';
require と include の違い
エラーレベル
「include」と「require」の違いの1つに、読み込みエラーレベルがあり、最終的にファイルが読み込めなかった時に、requireの方がエラーレベルが高くなります。
- include:E_WARNING
- require:E_ERROR
コンポーネントとライブラリ
「inlucde」はコンポーネントの読み込み、「require」は機能的なライブラリプログラムを読み込むときに利用する傾向があります。
include_once
include_once は、一度だけ include します。最初に読み込まれると、それ以降 include_once を実行しても結果は変わりません。
include_once 'ファイルパス';
表示結果がかわらないので注意
include_once でHTMLコンポーネントを読み込んでしまうと、表示内容や結果が変わった時に反映されないので注意が必要です。
require_once
require_once も、同様に一度だけ require します。
require_once 'ファイルパス';
不変の処理で利用
require_once はモデルやライブラリなど、一度だけ読んでも処理が変わらないファイルに対して利用します。
外部ファイルを使った処理
ファイル構成
main.php で、functions.php と head.php を読み込んでHTML表示します。
├── functions.php
├── head.php
└── main.php
HTMLヘッダ
head.php は HTML の headタグをコンポーネント化したファイルです。CSSは Bootstrap5 をCDNで読み込んでおり、HTMLのタイトルは変数 $title で表示します。
head.php
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?= $title ?></title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1"
crossorigin="anonymous">
</head>
モジュール作成
モジュールファイル「function.php」に、合計金額を計算する totalPrice() メソッドを実装します。
functions.php
<?php
function totalPrice($price, $amount)
{
$total_price = $price * $amount;
return $total_price;
}
functions.phpの読み込み
「main.php」から「functions.php」を読み込み、totalPrice() を実行します。またHTMLタイトルは「$title」で設定しました。
main.php
<?php
require_once 'functions.php';
$title = 'MyShop';
$price = 300;
$amount = 5;
$total_price = totalPrice($price, $amount);
?>
HTML表示
「head.php」を読み込み、headタグを共通化します。
main.php
<!DOCTYPE html>
<html lang="ja">
<?php include 'head.php' ?>
<body>
<div class="container">
<label class="fw-bold">価格</label>
<p><?= $price ?>円</p>
<label class="fw-bold">個数</label>
<p><?= $amount ?>個</p>
<label class="fw-bold">合計金額</label>
<p><?= $total_price ?>円</p>
</div>
</body>
</html>
インクルードパス
include や require のパスは、include_path の設定を利用 します。指定したファイルが include_path に見つからないときは、呼び出し元のディレクトリを探す仕様になっています。
get_include_path()
get_include_path は現在読み込みが可能なパスを取得します。
get_include_path();
現在のインクルードパスの確認
echo で現在のインクルードパスを確認します。
echo get_include_path();
結果
以下のフォルダが表示されました。※結果は環境によって異なります。
.:/usr/local/Cellar/php@7.4/7.4.21_1/share/php@7.4/pear
set_include_path()
set_include_path はインクルードするフォルダのパスを設定します。
set_include_path(フォルダパス);
__DIR__
__DIR__ は実行ファイルの現在のフォルダパスを取得します。インクルードパスに、現在のフォルダパスを新たに追加します。
set_include_path(get_include_path() . PATH_SEPARATOR . __DIR__);
結果
インクルードパスに現在のフォルダパスが追加されます。
.:/usr/local/Cellar/php@7.4/7.4.21_1/share/php@7.4/pear:現在のフォルダパス
my_shop の作成
my_shop プロジェクトを以下のファイル構成で作成します。ログイン画面、ユーザホーム画面をコンポーネントなど複数のファイルを読み込んでみましょう。
ファイル構成
app/views/ にはHTMLのメインコンテンツ、レイアウト、コンポーネントなどのViewファイルを格納します。login/、user/ にはメインファイル、env.php は環境設定ようのファイルです。
my_shop
├── app
│ └── views //Viewファイル
│ ├── components
│ │ ├── head.php
│ │ └── nav.php
│ ├── layouts
│ │ └── app.view.php
│ ├── login
│ │ └── index.view.php
│ └── user
│ └── index.view.php
├── env.php //環境設定ファイル
├── login
│ └── index.php //メインファイル
└── user
└── index.php //メインファイル
環境設定ファイル
環境設定ファイル env.php にインクルードパスに現在のフォルダのパスを追加します。インクルードパスを追加すると require_oncd や include に相対パスを記述して読み込めます。
<?php
set_include_path(get_include_path() . PATH_SEPARATOR . __DIR__);
レイアウトファイル
HTMLのレイアウトファイルを作成します。$template で指定した Viewファイルを include で読み込み、bodyタグにメインコンテンツを表示します。また、headタグは、app/views/components/head.php ファイルを読み込みます。
app/views/layouts/app.view.php
<!DOCTYPE html>
<html lang="ja">
<?php include 'app/views/components/head.php' ?>
<body>
<?php include $template ?>
</body>
</html>
headタグ
app/views/components/head.php
HTMLの head タグは各ページで共通化します。
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?= $title ?></title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1"
crossorigin="anonymous">
</head>
ログイン画面(Viewファイル)
ログイン画面の body の中身をHTML記述します。
app/views/login/index.view.php
<div class="container">
<h2 class="h2 text-center p-3">ログイン</h2>
<form action="auth.php" method="post">
<div class="form-floating mb-3">
<input class="form-control" type="email" name="email">
<label for="">メールアドレス</label>
</div>
<div class="form-floating mb-3">
<input class="form-control" type="password" name="password">
<label for="">パスワード</label>
</div>
<div class="text-center m-3">
<button class="btn btn-primary">ログイン</button>
</div>
</form>
</div>
ログイン画面(メインファイル)
メインファイル login/index.php は最初に env.php を読み込みます。$template に表示コンテンツのパスを指定して、include でレイアウトファイルを表示します。
login/index.php
<?php
require_once '../env.php';
//表示コンテンツ
$template = 'app/views/login/index.view.php';
//レイアウトファイル
include 'app/views/layouts/app.view.php';
演習
問題1
ユーザページをHTML表示してみましょう。
追加ファイル
- user/index.php
- app/views/user/index.view.php
問題2
ユーザページ上部のメニューは、HTMLコンポーネント化してみましょう。
- app/views/components/nav.view.php