Friction River Software

  • お問い合わせ

CakePHP5入門【PHP言語の文法編④】関数

B美

文法編の最後は「関数」についてです

A子

あれ?
これまでの中にもちょこちょこ「関数」が出てきてたよね?

C菜

ですです~

print_rプリントアール」や「file_get_contentsファイルゲットコンテンツ」なんかを覚えてますよ~

B美

一番最初に登場したのは「phpinfoピーエイチピーインフォ」だけどね(苦笑)

それはともかく、「関数」とは何か?
はい、C菜!

C菜

何か一連の処理をまとめておいて、必要に応じて呼び出せる仕組みだと思うです~

A子

だよね

Excelのsum関数countif関数をよく使うけど、そんな感じだと思う

B美

まぁ良いでしょう
もっと細かいイメージとしては

ブラックボックス化した箱の中に処理対象となるデータを投入すると、箱の中で何らかの処理が行われ、最終的には処理結果であるデータが出力される

…って感じかな

Excelのsum関数って、入力するのは「合計したい数値が入っているセルの範囲」で、出力されるのは「その範囲にある数値の合計」よね?

C菜

あ!ボックス(箱)だから「函数かんすう」なんですか~?

函館はこだての「はこ」は「箱」って意味ですよね~?

B美

正解!

関数かんすう」がもともと「函数かんすう」と表記されてたってこと、よく知ってたわね
えらいえらい

A子

入力と出力って絶対に必要なの?

Excelの関数は基本的にそうだけど…

B美

いいえ、入力も出力も必須じゃないわ

入力の無い関数や出力の無い関数もあるわよ

C菜

そういえば「phpinfoピーエイチピーインフォ」はカッコ内に何も記述してませんでしたね~

<?php
phpinfo();
?>

これって入力値が何もないってことですよね~?

B美

その通り!
あと、用語なんだけど

・入力値…「引数ひきすう
・出力値…「もど」または「かえ

と呼びます

A子

かえ」って「かえ」みたいよね

B美

不穏なこと言ってんじゃないわよ

ただまぁ、そう感じる人は割と多いみたいで、一般的には「もど」のほうを使う人が多い気がする(苦笑)

C菜

上の図の例としては~

「20と30という引数を入れると、130という戻り値が出力される」ってことですか~?

B美

それでも良いんだけど…
「20と30という引数を渡すと、130という戻り値が得られる
のほうが一般的かな

引数ひきすうって「渡す」ものだからね

A子

ふーん、なるほどねぇ

あ、そういえばPHPの関数って、どのくらい用意されてるの?
前に出てきたやつだけじゃないわよね?

B美

もちろん!
大量にあるわよ

詳しくはここを見てね
(クリックすると別ウィンドウで開きます)

A子

ちょっ、何この量…

あ、「file_existsファイルイグジスト」や「file_get_contentsファイルゲットコンテンツ」もあるね

B美

関数の詳細仕様を知りたければ、関数名自体をクリックしてね

例えば、file_get_contentsをクリックすると…

C菜

意味がよくわからないです~

B美

Webページの下のほうに実際に使用するときの例が載ってるから、それを参考にすれば何とかなると思うわよ

B美

ちなみに、前々回に使ったコードがこれ

file_get_contents関数の二つの引数については、$filenameと$use_include_pathを指定しただけね
(FILE_USE_INCLUDE_PATHという定数を使わないから、第2引数にはfalseを渡しています)

<?php

$test_file = 'test1.php';

if (file_exists($test_file)) {
  $info_file = file_get_contents($test_file, false);
  $result = htmlspecialchars($info_file, ENT_QUOTES);
  echo nl2br($result);
}

?>

戻り値はそのファイルの中身で、$info_fileという変数に代入されるってわけ

A子

自分で新たな関数を作ることってできるの?

B美

もちろんよ
それじゃ、今回の学習内容として、新たな関数を作ってみましょうか

ホームディレクトリの下の「html」ディレクトリを開いて、「test4.php」を右クリックしてから「L3afpadリーフパッドで開く」を選択します
(もちろん「Plumaで開く」でも良いわよ)

B美

それを以下のように書き換えてちょうだい
ちなみに、赤字で表示している部分が関数の定義よ

<?php

$test_file = 'test1.php';
$result = myfile_read($test_file);
echo $result;

function myfile_read($filename) {
  $result = "";

  if (file_exists($filename)) {
    $info_file = file_get_contents($filename, false);
    $result = htmlspecialchars($info_file, ENT_QUOTES);
    $result = nl2br($result);
  }

  return $result;
}


?>

打ち込み終わったらファイル名を「test9.php」で保存して、ブラウザで確認してみてね
(URLは「localhost/test9.php」)

A子

ん?これって、「echo $result;」のあとに「function …」が実行されるの?

B美

違う違う!

定義した関数はどこかで呼び出されない限り、勝手に実行されることは無い
(「$result = myfile_read($test_file);」の部分が関数呼び出しよ)

つまり、このプログラムは「echo $result;」が実行されれば終了するってこと



C菜

えっと~
関数の定義は「function」から始まって、関数名を書いたらその後にカッコを書いて「引数」を記述して~

あとは波カッコの中に関数の中身を書けば良いんですかね~?

つまり
function 関数名(引数) {
 関数の中身
}

…ってことでしょうかぁ~?

B美

素晴らしい!
まさにその通りよ

あ、複数の引数を渡したい場合は、カンマ区切りで複数個書いても良いからね

A子

「return $○○;」って、$○○という変数の値を呼び出し元に返すってことだよね?
(上の例だと「$result」)

だったら、さっきの関数ってさー

<?php

$test_file = 'test1.php';
$result = myfile_read($test_file);
echo $result;

function myfile_read($filename) {
  if (file_exists($filename)) {
    $info_file = file_get_contents($filename, false);
    $result = htmlspecialchars($info_file, ENT_QUOTES);
    return nl2br($result);
  }
}

?>

…って書いちゃダメなの?

B美

それでも良いわよ

ただし、もしも存在しないファイルの名前を指定した場合、どうなると思う?

C菜

やってみるです~

「$test_file = 'test1.php';」の中の「test1.php」を例えば「test1.txt」に変えてっと~



C菜

ファイルが見つからないんだから、当然何も出ないです~

B美

エラーにはならないってところが特徴的な点なのよね
実はPHPの関数って、returnを実行せずに終了した場合、自動的に「nullヌル」が返ることになってるのよ

だからif文の中身が実行されていない(returnしていない)にもかかわらず、エラーが出なかったってわけ
(あ、でも他のプログラム言語ではエラーになりがちだから注意してね)

A子

nullヌル」って何なのさ

B美

何も無い」って意味よ

プログラム言語の一つである「C言語」とか「C++言語」では、また別の意味になるけどね

C菜

関数「myfile_read」の戻り値が「nullヌル」で、変数「$result」にそれ(nullヌル)が代入されて、その値(nullヌル)が表示されたってことですか~?

A子

「何も無い」を表示って、変な感じね(苦笑)

あ、あと変数「$result」が関数の外(呼出し側)と内(関数側)にあるけど、同じものじゃないわよね?

B美

もちろん別物よ
だからこそ戻り値を返しているわけだし…

そうねぇ
次のように書き換えてから「test10.php」というファイル名で保存してみて

<?php

$test_file = 'test1.php';
$result = '';
myfile_read($test_file, $result);

echo $result;

function myfile_read($filename, &$result) {
  if (file_exists($filename)) {
    $info_file = file_get_contents($filename, false);
    $result = htmlspecialchars($info_file, ENT_QUOTES);
    $result = nl2br($result);
  }
}

?>

C菜

関数を呼び出している側では戻り値を受け取っていませんし、そもそもその関数が戻り値をreturnしていませんよ~

B美

呼出し側で二つ目の引数として「$result」を指定してるわよね

でも、関数側ではその値を受け取っていないのよ

A子

ん?どういうこと?

それじゃ、いったい何を「渡した」ってのよ

B美

渡したのは「参照」よ

具体的には「$result」という変数の「場所情報」ってこと

C菜

変数の場所さえ分かれば、関数内でその中身を自由に書き換えられるってことでしょうか~?

B美

その通り!
さすがはC菜ね

で、どうすれば「参照」を渡せるかっていうと、関数側の定義において引数の前に「&」を付ければ良いだけなのよ
(呼出し側じゃなくて、関数側だからね)

ちなみに、用語だけど
・関数には「あたい」を渡す  → あたい渡し(Callコール byバイ Valueバリュー
・関数には「参照さんしょう」を渡す → 参照さんしょう渡し(Callコール byバイ Referenceリファレンス
と呼びます

A子

わざわざ戻り値を返してそれを変数に代入するなんて形よりも、「参照渡し」のほうがシンプルで分かりやすいじゃん

最初からこっちを説明しなさいよね

B美

ふふ、ここで重大な話をします

基本的に「参照渡し」は使用しないように!

A子

へ?
何でよ?

C菜

呼出し側に存在する変数の中身を関数内で勝手にいじくられると、わけが分からなくなるとか…ですか~?

B美

まさにその通り!

モジュール間結合度が強くなると、モジュールの独立性は低下するからね

A子

( ゚д゚)ポカーン

B美

とにかく、関数の基本が「値渡し」ってことを理解していれば大丈夫よ

「参照渡し」については、知識として持っておくだけでOK

A子

うーん、よく分からないけど分かったわ(てか、そういうものだと思うことにするわ)
要するに、「値渡し」では渡された値をどういじくろうが、呼出し元のほうには影響を与えない…ってことよね?

あ、そうか!
「参照渡し」だと、呼出し元と関数側が相互に影響しあっちゃうんだ!

それが「独立性の低下」って意味じゃない?

B美

お、自力でそこまで到達できたってのは、素晴らしい!
A子もなかなかやるじゃない

ちょっと見直したわ

A子

ちょっとかよ!