Kintarou'sBlog

プログラミング学習中。学習内容のアウトプットや読書で学んだことなど随時投稿!

【PHP】基礎文法(関数関連)

こんにちは😊Kintarouです。

現在エンジニア転職を目指してTECH CAMPにてプログラミング学習中です👨‍🎓
夢はフリーランスエンジニアになって働く人が働きやすいシステムを作ること!
と、愛する妻と海外移住すること🗽

プログラミングや読んでいる本のことなど、ブログに書いていきます!
twitter : https://twitter.com/ryosuke_angry


今回参考にさせて頂いたサイト様🙇‍♂️ dotinstall.com


処理をfunctionでまとめる

同じ様な処理をまとめる場合に、関数というものを使います。

<?php

function check()
{
  $i = 1;
  if ($i === 1){
    echo 'OK!' . PHP_EOL;
  }else{
    echo 'oh...' . PHP_EOL;
  }
}

check();

#=> OK!

※関数名の後に()をつけるようにしましょう。
※function外で$iを定義出来れば便利ですが、それは出来ません。(スコープという考え方があるためです)
※もしfunction外でfunction内に使う変数$iを定義したい場合、function内でglobal $iとするか↓の引数を使いましょう。

関数に引数を渡す

関数に引数を渡します。

<?php

function check($num)
{
  if ($num === 1){
    echo 'OK!' . PHP_EOL;
  }else{
    echo 'oh...' . PHP_EOL;
  }
}

$i = 1;
check($i);

#=> OK!

$i = 0;
check($i);

#=> oh...

※1度目のcheckでは$iに1を代入したので(実引数)function内の$numが1となり(仮引数)$num === 1がtrueとなってOK!が出力されました。2度目のcheckでは$iに0が代入されているので$num === 1はfalseとなり、oh...が出力されました。

出力ではなく、戻り値として受け取る

戻り値として受け取る場合はreturnを使います。

<?php

function sum($a, $b, $c)
{
  return $a + $b + $c;

  echo 'Hi!';
}

echo sum(100, 200, 300) . PHP_EOL;

#=> 600

※仮引数に渡された100, 200, 300がfunction内で足し合わされた結果をreturnにより戻り値として返され、結果が出力されています。 ※returnを利用した場合、その時点で戻り値が決定されるのでそれ以降の処理は無視されます。そのためHi!は出力されません。

関数自体を値として扱う

関数自体を変数に代入して出力できます。無名関数(クロージャー)と言います。

<?php

$sum = function ($a, $b, $c) {
  return $a + $b + $c;
};

echo $sum(100, 200, 300) . PHP_EOL;

#=> 600

※無名関数の場合はfunctionの後にスペースを入れること、{波括弧の前に改行しない、}波括弧閉じの後に ; セミコロンをつけます(こちらは変数として定義されているため)。

関数内に条件をつける

関数内に条件式を入れる事も出来ます。条件は、条件演算子で記述する事もできます。

<?php

$sum = function ($a, $b, $c) {
  $total = $a + $b + $c;
  if ($total < 0) {
    return 0;
  } else {
    return $total;
  }
};

echo $sum(100, 200, 300) . PHP_EOL;

#=> 600

条件演算子を使った場合

<?php

$sum = function ($a, $b, $c) {
  $total = $a + $b + $c;
  return $total < 0 ?
      0
    : $total;
};

echo $sum(100, 200, 300) . PHP_EOL;

#=> 600

引数に型を指定する

仮に以下のように、点数(数値)を渡したい引数に文字列を渡しても出力されてしまいます。

<?php

$scoreShow = function ($name, $score) {
  return "$name さんは $score 点です。";
};

// echo $scoreShow("Kintarou", 50) . PHP_EOL;
echo $scoreShow("Kintarou", "ごじゅっ") . PHP_EOL;

#=> Kintarou さんは ごじゅっ 点です。

もし引数の型を指定する場合は、仮引数の前に型を記述します。

<?php

$scoreShow = function (string $name, int $score) {
  return "$name さんは $score 点です。";
};

echo $scoreShow("Kintarou", "ごじゅっ") . PHP_EOL;

#=> Fatal error: Uncaught TypeError: Argument 2 passed to {closure}() must be of the type int, string given, called in /home/dotinstall/main.php on line 7 and defined in /home/dotinstall/main.php:3
Stack trace:
#0 /home/dotinstall/main.php(7): {closure}('Kintarou', '\xE3\x81\x94\xE3\x81\x98\xE3\x82\x85\xE3\x81\xA3')
#1 {main}
  thrown in /home/dotinstall/main.php on line 3

must be of the type int, string giben, つまりintが入るべきところにstringが入ってますよというエラーが表示されます。

※実はこの状態では"ごじゅっ" → "50"とすると"50"はstring型ですがエラーは出ずに実行されます。これはPHPが数字らしきものを数字として取り扱う仕様があるためです。
※厳密にチェックして欲しい場合は、functionの前にdeclare(strict_types=1)を記述する事で厳密に型をチェックしてくれます。

<?php

declare(strict_types=1)

$scoreShow = function (string $name, int $score) {
  return "$name さんは $score 点です。";
};

echo $scoreShow("Kintarou", "50") . PHP_EOL;

#=> Fatal error: strict_types declaration must not use block mode in /home/dotinstall/main.php on line 3

型がnullの場合も許容する

先の例で、仮に点数が未採点でnullの状態であった場合どうなるでしょうか。

<?php

declare(strict_types=1);

$scoreShow = function (string $name, int $score) {
  return "$name さんは $score 点です。";
};

echo $scoreShow("Kintarou", null) . PHP_EOL;

#=>Fatal error: Uncaught TypeError: Argument 2 passed to {closure}() must be of the type int, null given, called in /home/dotinstall/main.php on line 9 and defined in /home/dotinstall/main.php:5
Stack trace:
#0 /home/dotinstall/main.php(9): {closure}('Kintarou', NULL)
#1 {main}
  thrown in /home/dotinstall/main.php on line 5

int型にnull型が入っているとされるためエラーとなります。
もしint型だけではなくnull型も表示して欲しい場合は、型名の頭に?をつけると「nullか指定の型」となります。

<?php

declare(strict_types=1);

$scoreShow = function (string $name, ?int $score) {
  return "$name さんは $score 点です。";
};

echo $scoreShow("Kintarou", null) . PHP_EOL;

#=> Kintarou さんは  点です。

intの前に?をつけたことによってnullも許容され、無事出力されました。

※ただし、現状int型かstring型だったり、string型かbool型という2択は出来ないそうです。その場合はそもそも型を指定しないということですね。

本日は以上です!
どなたかの参考になれば幸いです😊