【PHP入門】PHPの関数とは

## はじめに
こちらは、[PHP5上級試験/準上級試験まとめ](https://qiita.com/chimayu/items/36d6152134464856ac0d) の一環として、PHPの関数について順を追って解説した記事です。
試験対象はPHP5ですが、PHP7くらいまでなら対応できるよう汎用的内容を記載しています。
初心者向けの内容ですが、四則演算やechoやif文くらいまで理解しているとより読みやすいかと思います。内容に間違いがある場合はご指摘ください。
なお2021年秋には [PHP8技術者認定上級試験](https://www.phpexam.jp/2020/12/11/php8/) が始まる予定ですので、最新情報は公式ページよりご確認ください。

## 関数とは
関数とは、**処理のかたまり**、**ひとまとまりのプログラム**のことです。
関数は再利用でき、名前を付けて一度書いてしまえば次に使うときは名前に基づいて呼び出すだけなので、短い記述で繰り返し同じものを使うことができます。

## 関数の書き方
```function 名前(){}``` のような書式で記述し、```{}``` の中に処理を入れます。
PHPでは通常、行の終わりにセミコロンを付けますが、関数の ```{}``` の後ろにセミコロンは不要です。

```php:関数の定義
function functionName(){
    // 何らかの
    // 処理を
    // 書く
}
```

```php:関数の呼び出し
functionName();  // この1行だけで↑の関数（処理のまとまり）を実行できる
```

## パラメータ（仮引数）と返り値

関数において入力を受ける変数を**パラメータ（仮引数：かりひきすう）**、関数からの出力を**返り値**といいます。
パラメータは丸カッコの中に書く事で、その下の ```{}``` の中で使用できるようになり、丸カッコに引数を書かないでその値を使用しようとするとエラーになります。
返り値は俗に、戻り値、リターンなどと呼ばれることもあります。 ```return $val``` のように指定し、関数の作りによっては返り値がないものもあります。

```php
function functionName($num){ // ←この丸カッコの中の部分がパラメータ、仮引数
    // 何らかの処理
    $val = $num + 1; // ←ここで使用している$numが、丸カッコで受けたパラメータ
    return $val; // ←この部分が返り値
}
```

```php
function functionName(){ // ←丸カッコにパラメータ、仮引数が無い場合...
    // 何らかの処理
    $val = $num + 1; // ←ここの$numは「未定義の変数」を使おうとしていることになるため、
    return $val;
}
functionName(); // ←関数を呼び出した時点でエラーになる
// [エラー] Notice: Undefined variable: num in /sample/index.php on line 4
```

returnは関数内に複数記述できますが、最初に到達したreturnの内容だけが、関数の呼び出し元に返ります。

```php:関数内にreturnが複数ある例
function functionName($num){
    $val = $num + 1;
    $va2 = $num + 2;
    return $val1; // ←この時点で返り値が返されるので
    return $val2; // ←この部分の返り値は無効となる
}
```

```php
function functionName($num){
    if($num === 0){
        return 0; // $numが0の時は、この時点で返り値が返される
    }
    if($num === 1){
        return 1; // $numが1の時は、この時点で返り値が返される
    }
}
```

途中で関数の実行を停止して呼び出し元の処理に戻りたい場合は、返す値なしでreturnキーワードを書くこともできます。また、関数の一番最後のreturnは省略することができます。

```php
function functionName($num){
    if($num === 0){
        return; // $numが0の場合、即座に関数の実行を終了する
    }
    if($num === 1){
        return 1; // $numが1の時は、この時点で返り値が返される
    }
    return; // 省略可能
}
```

返り値は常に一つの値だけを返却できます。カンマを用いて複数の値を返すことはできません。

```php:エラーになるパターン
function functionName(){
    return 1, 2, 3;
}
functionName();
// [エラー] Parse error: syntax error, unexpected ',' in /sample/index.php on line 3
```

値を複数返却したい場合は配列にします。

```php
function functionName(){
    return array(1, 2, 3);
}
var_dump(functionName());
// array(3) { [0]=> int(1) [1]=> int(2) [2]=> int(3) }
```

<details>
<summary>returnについてもっと詳しく</summary>
return には、プログラムの制御を呼び出し元に戻す働きがあります。 呼び出し側のモジュールでは、呼び出しの次の式から続行します。
関数内にreturn文を書くと、即座にその関数の実行を停止し、**引数**を「関数の値」として返します。
ここで言う「引数」とは、return文の後ろに書く式や値のことです。```return $val``` とした場合は ```$val``` が引数です。returnは関数ではなく「言語構造」というものに当たるので、 引数を丸カッコで囲う必要はありません。
[ > PHPマニュアル - return](https://www.php.net/manual/ja/function.return.php)
</details>

## ユーザ定義関数と組み込み関数

大別すると関数には2種類あり、自分で好きなように作って利用する関数を**ユーザ定義関数**、PHPに元々用意されている関数（自分でわざわざ作らなくても利用できる関数）を**組み込み関数**といいます。

## 関数の呼び出し

関数を呼び出すときは、関数の名前と、その関数のパラメータに対して**値（実引数）**を書いてあげます。

```php
$val = 1;
functionName($val); // 関数呼び出し時、丸カッコの中が値（実引数）となる
functionName(1); // 値は変数や、数値や文字列などでもよい
```

## 関数定義と関数呼び出しの順序

なお次のように、関数定義より前に関数呼び出しを行っても問題なく動きます。

```php
$num1 = 5;
functionName($num1); // 10が返ってくる

function functionName($num1, $num2 = 2){
    $num = $num1 * $num2;
    return $num;
}
```

## パラメータの数やデフォルト値の色々なパターン

関数の作りによっては、パラメータが不要な場合や、パラメータにデフォルト値が設定されていて省略可能なもの、逆にパラメータを複数指定することができるものもあります。

↓パラメータも返り値もない関数の例。100 と出力される。
※出力の有無と、返り値の有無は分けて考える。

```php
function echoNum(){
    echo 100;
}
```


↓パラメータがひとつあり、返り値がない関数の例。
$count の変数に100が代入されていれば、 100 と出力される。

```php
function echoNum($count){
    echo $count;
}
```

↓パラメータがひとつあり、返り値がある関数の例。
$count の変数に100が代入されていれば、 100 と出力された上で、関数の呼び出し元に 1 の値が返る。

```php
function echoNum($count){
    echo $count;
    return 1;
}
```

↓パラメータがふたつあり、返り値がある関数の例。
変数```$num1```と```$num2```の足し算の計算結果が、関数の呼び出し元に返る。
```$num1```に10、```$num2```に20が代入されていた場合、30 の値が返ることになる。

```php
function calcNum($num1, $num2){
    $num = $num1 + $num2;
    return $num;
}
```

↓パラメータがふたつあり、パラメータの2個目にだけデフォルト値が設定されていて、返り値がある関数の例。
変数```$num1```と```$num2```の掛け算の計算結果が、関数の呼び出し元に返る。
```$num1```に5、```$num2```に3が代入されていた場合、15 の値が返ることになるが、関数呼び出しの際に二つ目の引数を省略した場合は 5 * 2 で 10 の値が返る。

```php
function calcNum($num1, $num2 = 2){
    $num = $num1 * $num2;
    return $num;
}
```

```php:関数呼び出し
$num1 = 5;
$num2 = 3;
calcNum($num1, $num2); // 15が返ってくる
calcNum($num1); // 10が返ってくる
```

上記のようにパラメータがデフォルト値を持つ場合は実引数の指定を省略できますが、ひとつ省略したらそれ以降の引数も省略する必要があります。

```php
function functionName($num1 = 1, $num2 = 2, $num3 = 3){
    return $num1 + $num2 + $num3;
}
echo functionName(2, , 10); // 途中の引数だけを省略することはできない
// [エラー] Parse error: syntax error, unexpected ',', expecting ')' in /sample/index.php on line 5
```


```php
// 二つ目の引数を省略する場合 // 二つ目以降の引数をすべて省略しなければならない 
function functionName($num1 = 1, $num2 = 2, $num3 = 3){
    return $num1 + $num2 + $num3;
}
echo functionName(2);
```


```php
// 一つ目の引数を省略する場合 // 一つ目以降すべてを省略しなければならない
function functionName($num1 = 1, $num2 = 2, $num3 = 3){
    return $num1 + $num2 + $num3;
}
echo functionName(); // 6
```

関数が求めるパラメータの数より多い実引数を与えても、多い分は無視されるだけで動作に影響ありませんが、関数が求めるパラメータより実引数が少ないとエラーになります。


```php:必要なパラメータの数より実引数が多いケース
function functionName($num1, $num2){
    return $num1 + $num2;
}
echo functionName(1, 3, 5); // 4 // 三つ目の引数が無視されて 1 + 3 = 4 の結果出力
```

実引数が少ない場合のエラーは、PHPのバージョンによって少し異なります。
PHP 5.4の場合だと、**警告**が出ますが処理は続行されます。

```php:必要なパラメータの数より実引数が少ないケース
function functionName($num1, $num2){
    return $num1 + $num2;
}
echo functionName(1);
```

```php:PHP5.4のエラー
// 引数が足りないことを示す「警告」が発せられる
Warning: Missing argument 2 for functionName(), called in /sample/index.php on line 6 and defined in /sample/index.php on line 2
// この行のエラーは足りない引数である$num2を関数の中で使用しているために出ている
Notice: Undefined variable: num2 in /sample/index.php on line 3

1 // 引数を一つだけ使用して出力には成功
```
PHP 5.4だと**警告**は出ますが処理は続行されるため、引数が足りない分はその回数分エラーが発せられます。

```php:必要なパラメータの数より実引数が少ないケースその２
function functionName($num1, $num2){
    return $num1 + $num2;
}
echo functionName();
```


```php:PHP5.4のエラー
Warning: Missing argument 1 for functionName(), called in /sample/index.php on line 7 and defined in /var/www/html/test/index.php on line 2

Warning: Missing argument 2 for functionName(), called in /sample/index.php on line 7 and defined in /var/www/html/test/index.php on line 2

Notice: Undefined variable: num2 in /sample/index.php on line 3

Notice: Undefined variable: num1 in /sample/index.php on line 3
0
```

PHP 7.1以降になると、ユーザ定義関数に渡す引数が足りない場合は、**致命的なエラー**として即座に処理が中断されます。

```php
Fatal error: Uncaught ArgumentCountError: Too few arguments to function functionName(), 1 passed in /sample/index.php on line 6 and exactly 2 expected in /sample/index.php:2 Stack trace: #0 /sample/index.php(6): functionName(1) #1 {main} thrown in /sample/index.php on line 2
```

[PHPマニュアル: 下位互換性のない変更点 - 関数に渡す引数が少ない場合の挙動](https://www.php.net/manual/ja/migration71.incompatible.php)
>これまでのバージョンでは、ユーザー定義の関数に渡す引数が足りない場合は warning が発生していました。PHP 7.1 以降では、warning ではなく Error 例外が発生するようになります。 この変更はユーザー定義の関数に対してだけのもので、 内部関数には影響を及ぼしません。

## 関数のパラメータの数が決まっていない場合
パラメータの数が不特定のときは**可変パラメータ**が利用可能です。
可変パラメータを扱うための組み込み関数があるので、そちらを併用します。

#### 可変パラメータを扱うための組み込み関数
```func_num_args()``` …与えられた引数の数を返す。
```func_get_arg()``` …指定した位置の引数を返す。
```func_get_args()``` …与えられた全ての引数を配列で返す。

使用例は以下の通りです。

```php:func_num_argsで引数の数を得る
function functionName(){
    $count = func_num_args();
    echo "引数の数: 全部で $count 個\n";
}
functionName(5, 3, 1); // 引数の数: 全部で 3 個
```

```php:func_get_argで指定した位置の引数を得る
function functionName(){
    $arg0 = func_get_arg(0);
    echo "最初の引数：$arg0\n";
}
functionName(5, 3, 1); // 最初の引数：5
```

```php:func_get_argsで引数のすべてを配列で得る
function functionName(){
    $args = func_get_args();
    $count = count($args);
    for ($i = 0; $i < $count; $i++) {
        $num = $i + 1;
        echo "{$num}個目の引数 → " . $args[$i] . "\n";
    }
}
functionName(5, 3, 1); // 1個目の引数 → 5 // 2個目の引数 → 3 // 3個目の引数 → 1

// 以下のようにしても同じ結果が得られます
function functionName2(){
    $args = func_get_args();
    foreach ($args as $key => $val) {
        $num = $key + 1;
        echo "{$num}個目の引数 → " . $val . "\n";
    }
}
functionName2(5, 3, 1); // 1個目の引数 → 5 // 2個目の引数 → 3 // 3個目の引数 → 1
```

## 関数の入れ子構造
関数の中にさらに関数を書くこともでき、これは**入れ子**や**ネスト**と呼ばれます。
入れ子になった内部の関数を呼び出すためには、それを含む外側（親にあたる方）の関数を呼び出すことで、内部の入れ子になった関数が定義されて呼び出せるようになります。

```php
function parent(){
    function child(){
        echo 'child';
    }
}

child(); // この時点では親が呼び出されていないので子も呼び出せない
parent(); // これ以降からchild()を呼び出せるようになる
```

## 関数の副作用
関数の中で、「返り値を計算して関数の呼び出し元に返り値を返す」ということ**以外の**動作を含む場合、その関数は**副作用**を持つということになります。
例えば関数内の return で返り値を返す前に、echo で出力しているとか、ファイルを削除するとかの動作のことです。

## 関数の命名規則
PHPマニュアルの中で言われているのは以下です。
> 関数名として有効な 形式は、まず文字かアンダースコアで始まり、その後に任意の数の文字・ 数字・あるいはアンダースコアが続くものです。正規表現で表すと、 ^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*$. となります。

要するに関数の名前は、**半角英数字**、または、**アンダースコア**、または、**日本語**なども使用可能ということです。
一文字目に数字は使えませんが、二文字目以降は数字も使用可能です。
また、正規表現に「\x7f-\xff」とあるので、文字コードがUTF-8であればひらがな、カタカナ、漢字なども使用することができます。

（ただし関数名に日本語を使うことの是非は議論の余地があるので、実際の開発では現場のルールに従ってください。例えばシステムにおいてメインで使用されるコード、ビジネスロジックやプロダクトコードと呼ばれる類のものに日本語は使用しないのが通常ですが、テスト用のコードであれば日本語の関数名を採用しているという現場もあります。）

関数名の大文字と小文字は**区別されません**。

```php
// これらの関数は全て同じ関数名だと判断されるため、二つ目以降の関数はエラーとなる
function functionName(){
    // 何らかの処理
}
function Functionname(){
    // 何らかの処理
}
function FUNCTIONNAME(){
    // 何らかの処理
}
// [エラー] Fatal error: Cannot redeclare Functionname() (previously declared in /var/www/html/test/index.php:3) in /sample/index.php on line 7
```
```php
function functionName(){
    // 何らかの処理
}

FunctionName(); // functionName() を呼び出せる
Functionname(); // functionName() を呼び出せる
FUNCTIONNAME(); // functionName() を呼び出せる
```

## スコープについて
関数ではなく変数の話になりますが、ある変数がコード上のどの場所で使えるかの有効範囲のことを**スコープ**といい、変数がどの位置で宣言されたかによって**グローバルスコープ**と**関数レベルスコープ**の2種類に分けられます。

### グローバルスコープ
グローバルスコープは、関数の外で宣言された変数のスコープです。
変数の有効範囲はスクリプト内すべての場所となり、どこからでも使えるのが基本ですが、関数内からグローバルスコープ変数を使う場合は ```global``` キーワードで変数を指定した後に使用する必要があります。

```php
function functionName(){
    echo $val;
}
$val = 1;
functionName(); // 関数内からグローバルスコープの変数を呼べないためエラー
```

globalキーワードを使用しなかった場合は下記のようなエラーになります。 ```Undefined variable``` とは「変数が未定義である」というエラーの内容です。

```php
Notice: Undefined variable: val in /sample/index.php on line 3
```

globalキーワードを使用すれば、関数内からグローバル変数を利用してもエラーにはなりません。

```php
function functionName(){
    global $val; // globalキーワードで変数を指定
    echo $val;
}
$val = 1;
functionName(); // 1
```

### 関数レベルスコープ
関数レベルスコープは、関数の中で宣言された変数のスコープです。
関数内で宣言された変数を関数外で使おうとするとエラーになります。

```php
function functionName(){
    $val = 1;
}
echo $val;
// [エラー] Notice: Undefined variable: val in /sample/index.php on line 5
```

試しに一度関数を呼んでから変数を使ってみても、同じエラーになります。

```php
function functionName(){
    $val = 1;
}
functionName();
echo $val;
// [エラー] Notice: Undefined variable: val in /sample/index.php on line 6
```

関数内で宣言された変数を関数外で使いたい場合は、returnでその変数の値を返せば同等のことが可能です。

```php
function functionName(){
    $val = 1;
    return $val;
}
$num = functionName();
echo $num; // 1
```

ただし、関数の呼び出しが終わると、関数の中で宣言された変数も消えてしまいますので、変数の値を保持したい時は ```static``` キーワードを使用します。

```php:staticなし
// 通常は関数呼び出しごとに内部の変数の値は消えるので
// 今回の場合だと何度呼び出しても結果は同じになる
function functionName(){
    $val = 0;
    $val = $val + 1;
    return $val;
}
echo functionName(); // 1
echo functionName(); // 1
```

```php:staticあり
// 変数にstaticキーワードを付けると値の保持が可能になり
// 2回目の関数呼び出し時は1回目の結果を引き継いだ状態からスタートする
function functionName(){
    static $val = 0;
    $val = $val + 1;
    return $val;
}
echo functionName(); // 1
echo functionName(); // 2
```
上記の例だと2回目の関数呼び出し時にも ```static $val = 0;``` で変数を初期化しているので、毎回変数が0に初期化されてしまうように見えますが、staticキーワードを使用した変数代入は1回目の関数呼び出しのときだけ行われるため、毎回初期化されるということにはならないのです。

また、static付きの変数は「数値や文字列などの値そのもの」（リテラルという）や定数で初期化することができますが、変数などの式で初期化することはできません。

```php
function functionName($num){
    static $val = $num; // 変数で初期化
    $val = $val + 1;
    return $val;
}
echo functionName(1);
// [エラー] Fatal error: Constant expression contains invalid operations in /sample/index.php on line 3
```

## 変数の値渡しと参照渡しについて

**値渡し**と**参照渡し**には、その変数の**値のコピー**を渡すか、その**変数そのもの**を渡すか、という違いがあります。
関数のパラメータ（仮引数）でも、値渡しと参照渡しが可能です。
通常よく使用するのは値渡しの方で、これまで記載した関数の例と同様です。
こちらの値渡しの方法だと、あくまで値のコピーに対して操作をしているので、元の変数の値が変わるということはありません。

```php:パラメータの値渡し
function functionName($num){
    $num++;
    echo $num;
}
$count = 0;
echo functionName($count); // 1
echo functionName($count); // 1
```

パラメータを参照渡しにしたい場合は ```&```（アンパサンド）記号をパラメータの前に付けます。

```php:パラメータの参照渡し
function functionName(&$num){ // パラメータの頭にアンパサンドを追加
    $num++;
    echo $num;
}
$count = 0;
echo functionName($count); // 1
echo functionName($count); // 2
```

参照渡しの場合は、コピーではなく変数そのものに対して操作を行うという意味になるので、上記では ```$count``` の値に変化が生じています。

また、参照渡しは元の変数を見に行こうとするため、パラメータが参照渡しになっている関数に対し実引数では変数を与えない、ということをするとエラーになります。

```php
function functionName(&$num){
    $num++;
    echo $num;
}
echo functionName(0); // 変数ではなく数値を実引数として与える
// [エラー] Fatal error: Only variables can be passed by reference in /sample/index.php on line 6
```

参照渡しの場合でも、関数のパラメータにデフォルト値を指定することが可能です。

```php
function functionName(&$num = 0){
    $num++;
    echo $num;
}
echo functionName(); // 1
```

## 返り値の参照
通常、返り値は値のコピーが関数から返されますが、関数名を ```&関数名``` として定義して呼び出すと、返り値を参照で返すようになります。

```php
// 参照で値を返す時は関数名の先頭に&を付ける
function &functionName(&$a){
    return $a;
}
$num = 2;
$val = &functionName($num); // 引数の参照渡しは関数定義時のみでよい
$num = 5;
echo $val; // 5 // 返り値を参照にしているので、現在の$numの値が返されている
```

## 可変関数について

可変関数とは関数名を変数に代入したもので、条件分岐させながら関数を呼び出したいときなどに便利です。変数の後ろに丸カッコを付けてあげれば、ユーザ定義関数と組み込み関数のどちらでも呼び出せます。


```php:ユーザ定義関数を可変関数で呼び出す
function test(){
    echo 'test関数です';
}
$name = 'test';
$name(); // test関数です
```

```php:組み込み関数を可変関数で呼び出す
$name = 'count';
$arr = array(1, 2, 3);
echo $name($arr); // 3
```

```php:条件によって異なる関数を可変関数で呼び出す
function morning(){
    echo 'おはよう';
}
function afternoon(){
    echo 'こんにちは';
}
function night(){
    echo 'こんばんは';
}
$time = 10;
if($time > 6 && $time < 12){
    $functionName = 'morning';
} elseif($time >= 12 && $time < 18) {
    $functionName = 'afternoon';
} else {
    $functionName = 'night';
}
$functionName(); // おはよう
```

可変関数は指定した名前の関数がなければエラーになってしまうため、その関数が存在するかどうかは ```function_exists()``` で事前に調べることができます。

[function_exists — 指定した関数が定義されている場合に true を返す](https://www.php.net/manual/ja/function.function-exists.php)

```php:function_existsで関数の存在をチェックする
function morning(){
    echo 'おはよう';
}
function night(){
    echo 'こんばんは';
}

$res = function_exists('night');
var_dump($res); // bool(true)

$res = function_exists('afternoon');
var_dump($res); // bool(false)
```

なお```echo``` ```isset``` ```print``` などは関数ではなく言語構造なので、可変関数では呼び出せません。下記のPHPマニュアルのページに載っているものは全て同様となります。

[PHPマニュアル - キーワードのリスト](https://www.php.net/manual/ja/reserved.keywords.php)

## 匿名関数について

一時的に関数を作成する際は ```create_function()``` という組み込み関数を用いて**匿名関数**を作ることができます。一時的な用途というのは例えば、関数の引数として用いるための関数（コールバック関数）を作成したい時などです。
匿名関数の関数名はほかの関数とかぶらないランダムな名前が自動的に付与されるので、関数名を考えるという労力も必要ありません。
```create_function()``` の第一引数には、作成する匿名関数に与えたいパラメータ、第二引数には処理の内容をセミコロン含めて記述します。

[PHPマニュアル: create_function — 匿名関数 (ラムダ形式) を作成する](https://www.php.net/manual/ja/function.create-function)

```php
$fc = create_function('$val','echo $val;');
$fc('hello'); // hello
var_dump($fc); // string(9) "lambda_1" // lambda_1 という名前が自動で振られている

$fc = create_function('$val','echo $val;');
$fc('bye'); // bye
var_dump($fc); // string(9) "lambda_2" // lambda_2 という名前が自動で振られている
```

ただし、この ```create_function()``` を用いた匿名関数の作成は、処理内容を第二引数に文字列で記載する必要があり可読性・保守性が良いとは言えず、**PHP 7.2.0 で非推奨**となり、**PHP 8.0.0 では削除**されました。
この問題を解決するため、PHP 5.3からはラムダ関数・無名関数が導入されています。
「関数名を付ける必要がない」「関数の引数として用いるための関数（コールバック関数）を作成するのに便利」という基本的な位置付けは匿名関数と同様です。

[PHPマニュアル - 無名関数（クロージャ）](https://www.php.net/manual/ja/functions.anonymous.php)

コールバック関数を引数に与えられる組み込み関数には、``` array_map()``` ```array_filter()``` ```array_walk()``` ```usort()``` などがあります。

[PHPマニュアル: array_map — 指定した配列の要素にコールバック関数を適用する](https://www.php.net/manual/ja/function.array-map.php)
[PHPマニュアル: array_filter — コールバック関数を使用して、配列の要素をフィルタリングする](https://www.php.net/manual/ja/function.array-filter)
[PHPマニュアル: array_walk — 配列の全ての要素にユーザー定義の関数を適用する](https://www.php.net/manual/ja/function.array-walk.php)
[PHPマニュアル: usort — ユーザー定義の比較関数を使用して、配列を値でソートする](https://www.php.net/manual/ja/function.usort.php)

ユーザ定義関数や、匿名関数、無名関数（ラムダ関数・クロージャ）を用いて、引数にコールバック関数を利用する例は以下の通りです。


```php:ユーザ定義関数をarray_mapの引数に使用する
function square($num)
{
    return $num * $num;
}
$arr = array(1, 2, 3);
$res = array_map('square', $arr);
print_r($res); // Array ( [0] => 1 [1] => 4 [2] => 9 )
```

```php:匿名関数をarray_mapの引数に使用する
$func = create_function('$num','return $num * $num;');
$arr = array(1, 2, 3);
$res = array_map($func, $arr);
print_r($res); // Array ( [0] => 1 [1] => 4 [2] => 9 )
```

無名関数を変数に代入する際は、関数の行末にセミコロンを付ける必要があります。

```php:無名関数をarray_mapの引数に使用する
$func = function($num) {
    return $num * $num;
}; // ←セミコロンが必要。ないとエラーになる。
$arr = array(1, 2, 3);
$res = array_map($func, $arr);
print_r($res); // Array ( [0] => 1 [1] => 4 [2] => 9 )
```

## PHPコード内でHTML等を出力させる時の小ネタ
PHPのコードの中に、PHPの終了タグ ```?>``` と開始タグ ```<?php``` が出てきた場合（終了タグ→開始タグの順序が大事）、タグに囲まれた部分はそのまま出力されます。
そのため、いちいちechoを書かなくてもテキストの出力をすることができます。
それを利用して、PHPの終了タグ ```?>``` と開始タグ ```<?php``` に囲まれたテキストを関数の中に挟むことによって、一度に大量のテキストを出力させる関数を作ることもできます。（あまり使う機会はないかもしれませんが）

```php
<?php
function echoText(){
?>
    <div class="contents1">
    ここに好きなテキストを書くと、
    </div>
    <div class="contents2">
    HTMLのタグも含めてそのまま出力される。
    </div>
<?php
}
?>
```

↑と↓のコードは同じ意味になります。何を出力させるかにもよりますが、↑の方がテキストの内容は読みやすいかもしれません。

```php
<?php
function echoText(){
    echo '<div class="contents1">'."\n";
    echo 'ここに好きなテキストを書くと、'."\n";
    echo '</div>'."\n";
    echo '<div class="contents2">'."\n";
    echo 'HTMLのタグも含めてそのまま出力される。'."\n";
    echo '</div>'."\n";
}
?>
```
#### 上のコードをもう少し詳しく解説

```php
<?php
// ↑PHPコード全体の開始タグ
function echoText1(){
// ↓PHPコード途中に現れる終了タグ
?>
    <div class="contents1">
    ここに好きなテキストを書くと、
    </div>
    <div class="contents2">
    HTMLのタグも含めてそのまま出力される。
    </div>
<?php
// ↑PHPコード途中に現れる開始タグ
}
// ↓PHPコード全体の終了タグ
?>
```
PHPコード全体の開始タグ、PHPコード全体の終了タグ、といった書き方はしましたが、1組目の ```<?php ?>``` でひとつのPHPコード、2組目の ```<?php ?>``` でまたひとつのPHPコードとなるため、計ふたつのPHPコードの間に、PHPではないただのテキストが挟まれている（そのテキストが関数の中身になっている）、と書いた方が分かりやすいかもしれません。

## PHPのコーディング規約について
試験の内容から外れるので完全に余談となりますが、**PHPだけが書かれたファイル**の場合、PHPコード全体の終了タグ ```?>``` は最近のコーディングの作法だと省略すべき、ということになっています。PHP終了タグの後ろに余計な空白などが入っているとプログラムが意図せぬ動きをする場合があるためです。

こういったコーディングの作法＝コーディング規約については、各社・各団体で様々な内容を規定している場合もありますが、主たるものは、PHP-FIG (Framework Interoperability Group)という団体が、推奨される標準規格『PSR (PHP Standards Recommendations)』の策定を行っているので一読してみてください。

■英語の原版はこちら
[PSR-2: Coding Style Guide](https://www.php-fig.org/psr/psr-2/)

■日本語訳をしてくれているページ
[PSR-2 コーディングガイド（日本語）](http://www.infiniteloop.co.jp/docs/psr/psr-2-coding-style-guide.html)

■PSR-2はPSR-1が前提になっていますので、PSR-1を確認したい人はコチラ
[PSR-1: Basic Coding Standard](https://www.php-fig.org/psr/)


#### 参考URL
[PHPマニュアル - return](https://www.php.net/manual/ja/function.return.php)
[PHPマニュアル - ユーザー定義関数](https://www.php.net/manual/ja/functions.user-defined.php)
[【PHP技術者】関数の命名規則、適切な出力文字エスケープ関数、フィルタ関数の動作ほか](https://hrzine.jp/article/detail/12)
[PHP - example of function or class name with \x7f-xff char](https://stackoverflow.com/questions/31501605/php-example-of-function-or-class-name-with-x7f-xff-char)
[PHP (プログラミング言語) - Wikipedia](https://ja.wikipedia.org/wiki/PHP_(%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E8%A8%80%E8%AA%9E))
[PHPの最後の終了タグ ?> は付けないでおこうねというお話](https://thesaibase.com/php/end-tag)
[PHPでラムダ式で関数を書く方法【初心者向け】](https://techacademy.jp/magazine/19139)