PHP入門 ユーザー定義関数の基本

最終更新日

ユーザー定義関数は、function命令で定義できます。以下の構文はユーザー定義関数の基本的な構文です。

構文:function命令

function 関数名(仮引数, ・・・・・){
  //任意の処理
  return 戻り値;
}

ユーザー定義関数は、「関数名(引数名,…)」のように呼び出せます。

<?php
function getTriangleArea($base, $height){
  return $base * $height / 2;
}

$area = getTriangleArea(8, 10);
print "三角形の面積は{$area}です。"

関数名

関数名の命名について、addElementのようにcamelCase記法で表します。また、ネーミングとしては「動詞+名詞」の形式で命名することをお勧めします。

関数名でよく利用する動詞

動詞役割
add追加
get取得
insert挿入
begin開始
start開始
open開く
read読み込み
send送信
oreate生成
is~であるか
動詞役割
remove/delete削除
set設定
replace置換
end終了
stop終了
close閉じる
write書き込み
receive受信
initialize、init初期化
can~できるか

仮引数と実引数

引数とは、メソッドの中で参照可能な変数のことです。関数を呼び出す際に、呼び出し側からメソッドに値を引き渡すために利用されます。呼び出し元から渡される値のことを実引数、受取側の変数のことを仮引数と区別して呼びます。

戻り値

関数が処理した結果を表します。return命令によって表します。

構文:return命令

return 戻り値;

return命令は関数の途中にも記述できますが、その場合はreturn命令以降の処理は実行されません。一般的には、末尾に置くか、ifなどの条件分岐構文とセットで利用します。ただ「return」とした場合は、戻り値を返さず、ただ処理を終了しないさいという意味になります。

function getTriangleArea($base, $height){
   if($base <= 0 || $height <= 0){
     return;
   }
   return $base * $height /2;
}

戻り値が存在しない場合は、明確にnullを返す

function getTriangleArea($base, $height){
   if($base <= 0 || $height <= 0){
     return null;
   }
   return $base * $height /2;
}

引数/戻り値の型宣言

関数の引数/戻り値には、明示的に型を指定することもできます。これを型宣言と言います。型宣言を利用することで、関数に不正な型が渡されるのを未然に防げます。

<?php
function getTriangleArea(float(引数の型) $base, float(引数の型) $height): float(戻り値の型){
  return $base * $height /2;
}
$area = getTriangleArea(8, 10);
print "三角の面積は{$area}";

型宣言で利用できる型(「*」は戻り値でのみ利用可能)

型名概要
bool真偽値
float浮動小数点数
int整数
string文字列
array配列
iterable配列/Traversal型(=foreach命令で利用できる型)
callableコールバック関数
object任意のオブジェクト
クラス/インターフェース名指定されたクラス/インターフェース
mixed任意の型※8.0
*voidなにも返さない
self現在のクラス
*static最初に呼び出したクラス※8.0

型宣言では、意図していない型が渡された場合にも、最大限、宣言された型に変換しようと試みます。この寛容さを回避する場合は、ファイルの先頭に次のコードを追加します。

<?php
declare(strict_types=1);

declare命令は、実行エンジンに対して、スクリプトの処理方法を指示するための仕組みです。strict_typesディレクティブに1を与えることで、厳密な型チェックを有効にします。ただし、declare命令はあくまで関数の呼び出し側で宣言しなければなりません。

複合的な型宣言

null許容型

型名の先頭に「?」を付与することで、nullを許容する型を表現できます。例えば、以下の例であれば引数$value(int型)はnullを許容します。

function test(?int $value) : void {
  var_dump($value);
}

test(100);   //結果:int(100)
test(null);  //結果:NULL
test();      //結果:エラー

Union型

PHP8以降であれば、「|」区切りで「int|bool」(int、boolいずれか)のような型を表すことも可能です。このような型をUnion型と呼びます。

function getTriangleArea(String|float $base,string|float $height): float
{・・・}

PHP8ではmixed型(なんでもあり)も利用できるようになっています。Union型では潜在的なバグを防ぐため以下のような重複はエラーとしています。

  • 名前の重複(int|bool|INTなど)
  • object型とクラス型の重複(object|Personなど)
  • iterable型とarray/Traversableの重複
  • bool型とfalse疑似型の重複

false疑似型(PHP8.0)

false疑似型は、Union型でのみ利用できる型で、「int|false」のように表します。たとえばmb_strpos関数は、指定の文字列が見つかった位置をint値で、見つからなかった場合にfalseを返します。

function mb_strpos(string $haystack, string $needle ,int $offset = 0, 
                    string $encoding = mb_internal_encoding()): int|false{…}

PHPでは、歴史的に失敗を意味する値として、falseを利用する機会が多いことから、このような表現を許容しています。その性質上、false疑似型を独立した型、false、?false(false|null)として利用することはできません。

void型の戻り値

voidは、戻り値としてのみ利用できる型です。たとえ、nullであっても値を返すのは不可。

スクリプトの外部化

ユーザー定義関数は、その性質上、複数のスクリプトで共有することが多いです。再利用性を高めるという意味で、このようなユーザー定義関数は別ファイルとして保存しておき、それぞれのスクリプトから必要に応じてインクルードします。外部ファイル(.phpファイル)を現在のスクリプトにインクルードするには、require、include、require_once、include_once命令を利用します。

構文:require_once命令

require_once $path
$pathインクルードするスクリプトファイルのパス

require命令とinclude命令との違いは、指定したファイルが見つからなかった場合の挙動にあります。require命令はFatal Errorを発生させ、その場でスクリプトを中断するが、include命令はWarning(警告)を発するだけで、スクリプトの処理は継続します。require_once/include_once命令は、require/include命令の「一度きり」版です。指定されたファイルがすでに読み込み済みである場合は、require_once/include_once命令はスクリプトを読み込まず、処理をスキップします。可能な限り、require_once/include_once命令を使用します。

included.php

<?php
function getTriangleArea(float $base, float $height): float{
  return $base * $height /2;
}
<?php
require_once 'included.php';
$area = getTriangleArea(8,10);
print "三角形の面積は{$area}です";

インクルードするファイルは、インクルード元のファイルと同一フォルダー、またはinclude_pathパラメーターで設定されたパスに配置してください。

外部ファイルは絶対パスを利用する

require/include系の命令を利用するさいに、原則、相対パスの利用はさけましょう。

以下のようにします。__DIR__は、現在のファイルが格納されているフォルダーを表す定数です。

require_once__DIR__.'/func1.php';

関数を定義する位置

関数は、基本的にどこに定義してもかまいません。関数定義のコードが関数呼び出しよりも先にある必要はありません。ただし、例外もあります。

1、条件分岐の中で関数が定義されている場合

<?php
$area = getTriangleArea(8,10);
if(true){
  function getTriangleArea(float $base, float $height): float{
    return $base * $height /2;
  }
}

この場合は、関数が条件式を満たした場合のみに定義されます。つまり、条件式が評価されるまで関数は定義されません。

2、関数内関数である場合

関数は、関数の中で定義することもできます。

<?php
//test()
$area = getTriangleArea(8,10);
print "三角形の面積は{$area}です。";

function test() {
  function getTriangleArea(float $base, float $height): float{
    return $base * $height /2;
  }
}

関数内関数は、実行時に親の関数が呼び出されるまで認識しません。

関数が有効になっているかあいまいなケースでは、function_exists関数を利用することで、あらかじめその関数が存在するか調べることもできます。

if(function_exists('getTriangleArea')){
  print 'getTriangleArea関数は定義済みです。';
}