More than 1 year has passed since last update.

この記事は一人PHP総復習 Advent Calendar 20165日目の記事です!

型について書こうと思っていたのですが、既に丁寧に解説している方がいらっしゃいました!

-> PHPの型と型安全について(PHP7からのPHPプログラミング)

型ってどんなときに意識するの〜ってことで、関数について書きます!

ユーザ定義関数まとめの項がさっと読める方は読まなくて大丈夫です!笑


関数とは

変数は値を入れておく箱でしたが、関数は幾つかの処理をまとめて入れておくものです。

最初から用意されている「組み込み関数」と、自分で定義する「ユーザ定義関数」があります。


関数の読み方・書き方


組み込み関数

例えばisset()という関数の場合。PHPマニュアル

$result = isset($name);

$nameがセットされているかどうかを調べて、boolean型のtruefalseを返す関数です。

関数に渡す値(ここでは$name)を「引数」、返ってくる値を「返り値(または戻り値)」と言います。

上記のような書き方をすることで、返り値が$resultに格納されます。

ここで返り値がboolean型だとわかっているので、次の処理で

// もしtrueだったら

if ($result) {
・・・
}

という処理を続けることが出来るわけですね。

組み込み関数はisset()substr()explode()などなど、覚えきれないほどあります。

覚えるのではなく、使う前にPHPマニュアルなどで引数と返り値(後述)の型をチェックします。


ユーザー定義関数

自分で作る関数も「引数」、「返り値」の考え方は同様です。幾つかの処理をして、結果を返します。


基本の書き方

<?php

// greetingという名前をつけた関数
function greeting($name) {
$message = 'Hello, '. $name. '!'; // 処理

return $message; // 結果を返す
}

$message = greeting('Tom');
echo $message; // 'Hello, Tom!'

returnで結果を返すと、そこで処理は終了します。

<?php

function greeting($name) {
$message = 'Hello, '. $name. '!';
return $message;

$message .= 'Nice to meet you.'; // この部分は実行されない
}

$message = greeting('Tom');
echo $message; // 'Hello, Tom!'

ちなみに初心者の頃理解しがたかったのですが、関数内の$messageと返り値を格納している$messageは別物です。

関数内での変数はローカルスコープ(関数内でのみ参照できる)です。

<?php

function greeting($name) {
$message = 'Hello, '. $name. '!';

return $message;
}

$greeting = greeting('Tom');

echo $greeting; // 'Hello, Tom!'
echo $message; // 宣言されていないのでエラーになる

よく分からない方は、変数のスコープの部分を参照してみてください!


引数を複数渡す

引数をいくつか渡す場合は左から順に第一引数、第二引数・・と呼びます。関数を呼ぶときも左から順番に渡すので注意しましょう

<?php

function greeting($time, $name) {
$message = 'Good '. $time. ', ' $name;

return $message;
}

$message = greeting('morning', 'Tom');

echo $message; // 'Good morning, Tom';

ここでは$timeが第一引数、$nameが第二引数です。


配列を返す関数

配列を使って複数の値を返すこともできます。その際、返り値はlist()か配列で受け取ります。

<?php

function children() {
return ['Tom', 'Bob', 'Emily'];
}

$children = children();
list($elder, $younger, $sister) = children();

echo $children[0]; // 'Tom'
echo $elder; // 'Tom'


返り値のない関数

また返り値がない場合もあります。

<?php

function greeting($name) {
$message = 'hello, '. $name. '!';

echo $message;
}

greeting('Tom'); // 'hello, Tom!'と表示される

関数内で$messageをechoしているので、返り値を受け取らなくても出力されます。


型をコメントに明記する

ユーザー定義関数も、返ってくる値が何かわからないと困るので、型をコメントに明記するのがよいです。(PHPDocと言います)

<?php

/**
* @param string $name
* @return string
*/

function greeting($name) {
$message = 'Hello, '. $name. '!';

return $message;
}

$message = greeting('Tom');
echo $message; // 'Hello, Tom!'

@paramは引数、@returnは返り値を示します。PHPマニュアル

※コメントについては後日まとめたいと思います!


型宣言

さらに、引数の型宣言(タイプヒンティング)ができます。(※PHPの古いバージョンではできない/挙動が違うので注意)

<?php

function greeting(string $name) :string {
$message = 'Hello, '. $name. '!';

return $message;
}

この場合、$nameにstring以外の型が渡ってくるとエラーになります。


引数にデフォルト値をセットする

引数にデフォルト値をセットしておくことができます。引数が渡ってこなくてもエラーにならない処理を作る時などに有用です。

<?php

function greeting($name = 'guest user') {
$message = 'Hello, '. $name. '!';

return $message;
}

echo greeting('Tom'); // 'Hello, Tom!'
echo greeting(); // 'Hello, guest user!'

予期せぬエラーを防止するために、型を意識することが重要です!


ユーザ定義関数まとめ

<?php

/**
* @param string $name
* @param array $date
* @return string
*/

function greeting(string $name = 'guest user', array $date) :string {
$message = 'Hello, '. $name. '!';
$message .= 'It's '. $date[0]. ' '. $date[1];

return $message;
}

$user = 'Tom';
$today = ['
December', '5th'];

echo greeting($user, $today); // 'Hello, Tom!It's December 5th'

ここまで理解できると気持ちいいですね!


ユーザー定義関数の書き方いろいろ


関数宣言

ここまで紹介してきた呼び出して使う関数の書き方です。

<?php

function FUNCTION_NAME() {
// 処理

return VALUE;
}

FUNCTION_NAME();

関数名は大文字と小文字を区別しません。


無名関数

PHP5.3からは無名関数が使えるようになりました。文字通り名前をつけない関数です。

<?php

$greeting = function($name) {
$message = 'hello, '. $name. '!';

return $message;
}

echo $greeting('Tom');

また無名関数に変数を引き継ぐこともできます。

<?php

$time = 'morning';

$greeting = function($name) use ($time) {
$message = 'Good '. $time. ', '. $name;

return $message;
}

echo $greeting('Tom'); // 'Good morning, Tom'

一度しか使わないことがわかっている関数などは、無名関数で書いてあげるとコードの冗長化が防げると思います!

実際にはDBのトランザクション処理などでよく使います。

プログラミングを始めたばかりの頃、型を理解していなくて何となく書いてよく分からないエラーが起きる、ということが多かったので、しっかり理解しておくとよいです!

最近は型宣言が出来るので気持ちよいですね( 厂˙ω˙ )厂