プログラミングを進めていくと、「あれ、この処理、さっきも書いたな…」と同じようなコードを何度も書いてしまうことがあります。これは非効率的で、修正があった場合にすべての箇所を直さなければならず、バグの原因にもなります。
この問題を解決するのが「関数」です。関数とは、一連の処理を一つのパッケージにまとめ、名前を付けて再利用できるようにしたものです。
今回は、PHPで独自の関数を自作する方法を、基本から応用までステップバイステップで解説します。「同じことを二度書かない(Don’t Repeat Yourself – DRY)」という、プログラミングの重要な原則を身につけましょう。
1. 関数の基本(定義と呼び出し)
関数を使うには、「定義(definiton)」と「呼び出し(call)」の2つのステップがあります。
1.1. 関数の作り方と使い方
まずは、htmlspecialchars()
という頻繁に使う処理を、もっと短く書けるように関数化してみましょう。
<?php
// 関数の「定義」
// htmlspecialcharsを短く書くためのラッパー(包む)関数
function h(string $str): string
{
return htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
}
$html_string = "<h1>こんにちは</h1>";
// 関数の「呼び出し」
$escaped_string = h($html_string);
echo $escaped_string; // 出力: <h1>こんにちは</h1>
- 引数(ひきすう):
($str)
の部分。関数に渡す情報(データ)です。 - 戻り値(もどりち):
return
で返される値。関数が処理した結果です。 - 型宣言:
(string $str): string
の部分。引数と戻り値のデータ型を事前に指定することで、予期せぬエラーを防ぎ、コードの可読性を高めます。(PHP 7以降のモダンな書き方です)
1.2. 複数の引数と戻り値
関数は、複数の引数を受け取ったり、複数の値を配列として返すこともできます。
<?php
// 2つの数値を受け取り、合計と差を計算して返す関数
function get_sum_and_diff(int $num1, int $num2): array
{
$sum = $num1 + $num2;
$diff = $num1 - $num2;
return [$sum, $diff]; // 配列として2つの値を返す
}
// 戻り値を配列デストラクチャリングで受け取る
[$total, $difference] = get_sum_and_diff(10, 3);
echo "合計は: " . $total . "<br>"; // 合計は: 13
echo "差は: " . $difference . "<br>"; // 差は: 7
[$total, $difference] = ...
のように書くと、配列の要素を直接それぞれの変数に代入でき、コードがスッキリします。
1.3. デフォルト引数
引数には、あらかじめデフォルトの値を設定できます。これにより、関数呼び出し時にその引数を省略することが可能になります。
<?php
function show_members(string $member1, string $member2, string $leader = "田中")
{
echo "今回のメンバーは{$member1}さんと{$member2}さんです。<br>";
echo "リーダーの{$leader}さんが現場を管理します。";
}
// 第3引数を省略すると、デフォルト値の「田中」が使われる
show_members("高橋", "小林");
2. 変数のスコープを理解する
関数を扱う上で非常に重要な概念が「スコープ」です。スコープとは、その変数が有効な範囲のことを指します。
原則: 関数内で定義された変数は、その関数の中でしか使えない(ローカル変数)。関数の外で定義された変数は、関数の中では直接使えない(グローバル変数)。
関数は「独立した部屋」のようなもので、外の世界(グローバルスコープ)と中の世界(ローカルスコープ)は基本的に隔離されています。
<?php
$global_var = "グローバル変数";
function check_scope(string $param)
{
$local_var = "ローカル変数";
echo "関数の中:<br>";
var_dump($param); // OK: 引数は使える
var_dump($local_var); // OK: 関数内で定義した変数は使える
// var_dump($global_var); // NG: Noticeエラー(未定義の変数)
}
check_scope("引数");
echo "関数の外:<br>";
var_dump($global_var); // OK: グローバル変数は使える
// var_dump($param); // NG: Noticeエラー
// var_dump($local_var); // NG: Noticeエラー
この「隔離」の仕組みのおかげで、関数内の変数が意図せず外の変数に影響を与えたり、その逆が起きたりするのを防ぐことができ、安全なプログラムを書くことができます。
3. 実践:関数を別ファイルにまとめる
Webアプリケーションを開発していると、様々なページで共通して使いたい関数(HTMLエスケープ、データベース接続など)がたくさん出てきます。これらを一つのファイルにまとめておくと、管理が非常に楽になります。
3.1. functions.php
の作成
よく使う関数をまとめたfunctions.php
というファイルを作成します。
【functions.php
】
<?php
/**
* HTMLエスケープ処理のラッパー関数
*/
function h(string $str): string
{
return htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
}
/**
* POSTデータを安全に取得する関数
*/
function get_post(string $key): string
{
return trim($_POST[$key] ?? '');
}
/**
* データベース接続(PDO)を取得する関数
*/
function get_db_connection(): PDO
{
try {
$dsn = 'mysql:dbname=php_learning_db;host=localhost;charset=utf8mb4';
$user = 'root';
$password = '';
$dbh = new PDO($dsn, $user, $password);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $dbh;
} catch (PDOException $e) {
echo "接続失敗: " . $e->getMessage();
die();
}
}
3.2. require_once
で関数を読み込む
他のPHPファイル(index.php
など)の先頭で、require_once
を使ってfunctions.php
を読み込みます。これにより、そのファイル内で定義されたすべての関数が使えるようになります。
【index.php
】
<?php
// 関数ファイルを読み込む
require_once 'functions.php';
// データベースに接続
$dbh = get_db_connection();
// POSTデータを取得
$username = get_post('username');
// HTMLに表示
?>
<p>ようこそ、<?php echo h($username); ?>さん</p>
このようにファイルを分割することで、コードの見通しが良くなり、同じ関数を複数のページで簡単に再利用できるようになります。
まとめ
- 関数は、処理をまとめて再利用するための強力な仕組み。
- 引数で関数に情報を渡し、**
return
**で結果を受け取る。 - スコープの概念により、関数内外の変数は安全に隔離されている。
- 共通の関数は別ファイルに分割し、
require_once
で読み込むのが実践的な使い方。
繰り返し現れるコードを見つけたら、「これは関数にできないか?」と考える癖をつけることが、効率的でメンテナンス性の高いコードを書くための第一歩です。