PHPプログラミング

入門

第12章 独自の関数

この章では、自分で「関数」を定義する方法を学びます。よく使うコードを関数にしておくと、別の場所で同じ処理をしたいときも使い回すことができ、コードの無駄を削ることができて非常に便利です。

目次

関数について

「関数」自体は今までにいくつか使用してきました。
変数の中身を見るためのvar_dump関数や、日付や時刻を取得するためのdate関数、変数が存在しているかをチェックするisset関数など。
これらの便利な関数は、PHPがもともと用意してくれている内部関数(ビルトイン関数)です。

上記の内部関数はほんの一部に過ぎず、実際には全てを使うことがないぐらいの膨大な関数が用意されています。
しかし、いざシステム構築しようとコードを書いていると、同じような処理をするコードが複数の場所で必要になることがあり、そのシステム独自の「こんな関数があったら便利なのにな」といった場面に必ず遭遇すると思います。
そんなときのために、自分で独自の関数を定義する仕組みもちゃんと用意されています。

メッセージを出力するだけの関数

まずはシンプルな関数を定義してみましょう。
次の「code12-1.php」を入力し、実行してみてください。

code12-1.php

<?php
// 関数の定義
function echo_message()
{
	echo "こんにちは!";
}

// 定義した関数の呼び出し
echo_message();

本当にシンプルに「こんにちは!」と挨拶だけしてくれる関数を定義しました。
3行目〜6行目までは関数の定義を行なっており、最後の9行目で定義した関数を呼び出しています。
当然ですが、9行目のコードが無い場合は、定義した関数も呼び出されることなく終了となります。

3行目の関数定義部分をもう少し詳しくみていくと、先頭についているfunctionで「関数を定義します」という宣言になります。そして、半角スペースを空けて後ろに付いている「echo_message」が関数の名前です。

関数の名前はアルファベットの大文字を使うこともできますが、慣習としてファルファベットの小文字を使用し、複数の単語が連なる場合は「_(アンダースコア)」で繋ぎます。
上のコードでは「echo」と「message」という単語を「_」で繋いで関数名にしています。
これがもし日付を取得する関数を定義したいとなった場合には「get」と「date」を繋げてget_dateのようになります。

上のコードは練習用としては良いものの、残念ながらほとんど役に立たないコードです。もう少し実用的な関数を定義してみましょう。

2つの数値の合計値を取得する関数

次に宣言する関数は、2つの値を引数として渡すと合計値を返す関数です。
早速コードを打っていきましょう。

code12-2.php

<?php
function add_numbers( $num1, $num2)
{
	return $num1 + $num2;
}

$num = add_numbers( 5, 10);
echo $num;

実行すると、add_numbers関数に渡した「5」と「10」の値を足した結果が出力されます。
数を「20」「30」と変えれば、その数値を足した結果が出力されます。
コードを分解して見ていきましょう。

まずは2行目の関数宣言部分です。function add_numbers( $num1, $num2)で「add_numbers」という関数名と、「$num1」、「$num2」という2つの引数を取ることを定義しています。
{}内では2つの引数を足し、returnで計算結果の値を呼び出し元(上のコードでは7行目)へ返します。
7行目では、受け取った計算結果の値を$numへ代入し、8行目でその値を出力して終了です。

returnで関数の呼び出し元に返す値のことを「返り値(戻り値)」と言います。そのまんまですね。

デフォルト引数

もし、add_numbersへ2つの値を渡さず、1つだけ渡したらどうなるでしょうか。
実行してみると分かりますが、引数が足りないためにエラーとなってしまいます。

開発時はエラーが出たら修正すれば良いだけの話しなのですが、リリース(公開)した後にこのようなエラーで実行が止まってしまうのは致命的です。
そこで、もし渡されない可能性のある引数がある場合は、「デフォルト引数」を指定するようにします。
先ほどの「code12-2.php」を、次のように修正してください。

code12-2.php(修正)

<?php
function add_numbers( $num1=0, $num2=0)
{
	return $num1 + $num2;
}

$num = add_numbers( 5, 10);
echo $num;

ここで、7行目のadd_numbers関数を呼び出している箇所の引数を、「5」と1つだけにして実行してみてください。
修正する前ではエラーで止まってしまったところが、今度はしっかりと最後まで実行されて値が出力されるようになりました。

これは、add_numbersの宣言で引数を( $num1=0, $num2=0)とデフォルト引数に「0」を指定したためです。
その結果、引数をadd_numbers(5)と1つだけ渡した場合は$num1には「5」が代入され、値の渡されなかった$num2には「0」が自動的に代入され、「5 + 0」と計算されて返り値がくるようになりました。
もちろん、add_numbers()と1つも引数を渡さなかった場合も「0 + 0」が実行された結果が返ってきます。

これで、引数がちゃんと渡されるか分からない関数があったとしても、安心してコードを書くことが出来るようになりました。

関数の外部ファイル化

同じファイルに関数を宣言しても問題ありませんが、どうせなら他のコードからも同じ関数を利用できるようにした方が便利そうですよね。
その為には、独自の関数を定義したコード部分を別ファイルへ分け、どのコードファイルからもそのファイルを読み込むことで関数を利用できるようにします。
様々なコードで共通の関数を使えるメリット以外にも、独自で定義した関数ファイルに切り分けることでコードがシンプルになって読み易くなることから、メンテナンス性の向上にも繋がります。

早速、関数の外部ファイル化を実践してみましょう。先ほどの「code12-2.php」で定義したadd_numbers関数を新しいファイル「code12-3.php」へごっそり移動し、「code12-2.php」から読み込んで関数を呼び出してみます。

code12-3.php

<?php
function add_numbers( $num1=0, $num2=0)
{
	return $num1 + $num2;
}

code12-2.php(修正)

<?php
require_once('code12-3.php');

// add_numbers関数を削除

$num = add_numbers( 5, 10);
echo $num;

「code12-2.php」を実行してみてください。
6行目の関数呼び出し部分で引数を色々変えてみると、ちゃんと関数のファイル「code12-3.php」を読み込んで実行できていることを確認することができます。

「code12-3.php」は単純にadd_numbers関数を移動してきただけの内容です。
変更した「code12-2.php」では、元々定義されていた関数部分を削除したことに加え、2行目のrequire_once関数を使って外部ファイルの読み込みを行っています。

外部ファイルを読み込むための関数

上の「code12-2.php」ではrequire_once関数を使いましたが、同じように外部ファイルを読み込むためのinclude_once関数というものもあります。
この2つの関数の違いは、require_onceは読み込もうとしたファイルが見つからなかった場合にエラーを出して終了するのに対し、include_onceはファイルが見つからなくても処理を実行するという点です。

しかしinclude_once関数を使い、ファイルが見つからない状態で処理を実行したとしても、結局add_numberes関数を呼び出すところで関数が見つからなずにエラーとなってしまいます。
「関数」は引数と違い、使いたいファイルは必ず読み込めている必要があるため、基本的にはrequire_once関数を使うようにしましょう。

少し話しをややこしくしてしまうのですが、外部ファイルを読み込むための関数にはさらにrequire関数とinclude関数があります。
関数名に「_once」が付いているかの違いですが、付いている場合は同じファイルを1度しか読み込まないのに対し、「_once」無しの場合は複数の同じファイルを読み込む処理が書かれていても、その都度ファイルの読み込みを行います。
通常は「_once」付きを使うようにして、読み込むファイルの重複を防ぐようにしましょう。

require関数とinclude関数の違いは「_once」付きの関数と同じく、読み込むファイルが見つからなかった場合に処理を続けるか中断するか、という違いがあります。

まとめ

関数の定義方法、そして定義した関数を読み込む方法まで見てきました。
以上の仕組みを上手に利用することで、非常に拡張性の高いコードを書くことが可能になります。一度定義した関数は別プロジェクトでも使用できるので、作業効率やメンテナンス性も向上するでしょう。
自分の中で「この処理はよく書いてるな」と思うコードが出てきたら、ぜひ独自の関数を定義してください。

この章で学んだこと

  • 「関数」は必要に応じて独自に定義することができる
  • 関数は個別のファイルに定義しておくことで、複数のコードファイル間で共有できる
  • 外部ファイルの読み込みは、特別な理由がある場合を除きrequire_once関数を使用する
  • 宣言した関数の引数にはデフォルト引数を設定することができる

こちらの記事は役に立ちましたか?

ありがとうございます。
もしよろしければ、あわせてフィードバックや要望などをご入力ください。

ありがとうございます。
コメントを送信しました。