PHPを実践で使えるレベルまで押し上げるための初心者向け講座、第3回目は「関数」です。
第1回の変数、第2回の配列、そして今回の関数の3つをマスターできていれば、いざ業務に望んでも、ある程度通用すると思っておいて良いでしょう。
※オブジェクト指向やクラスの理解、データベースの知識など、実際に業務に望めば覚えなければいけないものは沢山あり、それが最低ラインという現場もあります。しかし、そういった壁を乗り越えるためにも、「初心者が最短でPHPを使えるようになるための実践的な学び方」講座では最低限しっかりと押さえておきたい3つの項目をピックアップして説明しています。
関数の理解については、多くの人が躓くポイントです。postageやドットインストールなどでWEB学習をしている人にとっても、理解が出来ずに挫折してしまう人が多いのではないでしょうか。
しかし、理解ができればプログラミングの世界は一気に広がります。より複雑なシステムを組むことができ、今まで苦労して記述していたコードがより簡潔に書けるようになります。
最後まで読んで関数の使い方を理解できれば、必ず大きなステップアップになりますので、是非諦めずに取り組んでみてください。
関数とは
では、まず関数とはどういったものなのかを理解していきましょう。
PHPを学び始めた多くの人が関数へ触れています。それは標準で準備されているものでvar_dumpなどが該当します。
関数を説明する際には色んな例えが用いられます。
例えの良さは確かにその物事を理解するためには役立ちますが、実際にプログラミングに置き換えた際の使い所がわからないものが多いので、今回は実際に使用できる関数も例に取り上げながら、関数の理解を深めていきましょう。
引数と戻り値
関数を理解していくために、引数(ひきすう)と戻り値(もどりち)という2つのワードを見ていきましょう。
引数(ひきすう)
「いんすう」と読んでしまう人も多い引数(ひきすう)です。ただこの単語を覚えようとするとこんがらがってしまうポイントなので、「あなたが準備(設定)できる値」だと理解しておいてください。
例えば、以下のような計算式があるとしましょう。
◯+20=■
あなたは、上記の式で◯に好きな数字を設定できる権限があるとします。
このとき、◯が「引数」と呼ばれるものです。○に100を入れるも、5を入れるもあなたの自由ですね。
もう少し正しい説明をすると、引数は関数外からあなたが指定できる値です。
戻り値(もどりち)
あなたが設定する値が引数であることがわかりました。設定するだけして、何も返ってこなかったら困りますよね。
ネットショップで決済をしたのに、商品が届かなかったらクレームを入れるのと同じです。
では先ほどの計算式を使って戻り値をみてみましょう。
◯+20=■
先ほどの説明で○が引数でした。その時、計算結果(あなたが欲しい値)である■が戻り値に該当します。
○は自由にあなたが設定できるのに対して、戻り値はあなたが入力した引数を「計算」というフィルターで加工して、戻り値を返してくれるのです。
そして、計算をするフィルター部分に該当する「+20=」の部分が関数なのです。
少しこんがらがってきた人もいるかも知れませんね。でも安心してください。
理解を深めていくために、軽く問題に挑戦してみましょう。小学生や中学生の頃に戻ったつもりで取り組んでみると良いでしょう。
引数と関数と戻り値はそれぞれどこに該当するでしょうか。◯と□と△はあなたが関数外から自由に設定できるとします。あなたが関数を使って求めたい(欲しい)値を■とします。
問題1
◯÷3=■
問題2
◯+△=■
問題3
■−(4+◯+△)=□
では、解答をみてみましょう。
赤色が引数、青色が戻り値、緑色が関数とします。
問題1の解答
◯÷3=■
問題2の解答
◯+△=■
問題3の解答
■−(4+◯+△)=□
全問正解できた人は、ある程度関数がどういったものかがわかっているようですね。自信をもって良いでしょう。
全問不正解だった人も、落ち込む必要は有りません。安心して次の項へ進んでください。
次の項では実際にPHPのユーザー定義関数を使って、関数の理解をしていきます。
そちらで関数の理解ができれば、再度上記の問題に挑んでみると、きっと簡単に解くことができるはずです。
活用例から学ぶ関数の動き
さり気なく「ユーザー定義関数」というワードを使用しました。無理に覚える必要はありませんので、簡単に説明しておきます。
ユーザー定義関数
最初に説明したように、var_dumpなどといったPHPが最初から準備してくれている関数があります。
それに対して、自分たちが作る自作の関数がユーザー定義関数です。
どちらも関数に違いがないので、名称が重複してはいけません。なので、あなたがvar_dumpという関数を作ることはできないということです。
それでは、実際に関数でどういったことができるのか、そういった動きをしているのかをみていきましょう。
関数を作って読み解く
それでは、実際に関数を作ってその動きを見ていきましょう。
例1
前項で使った計算式を関数にしてみましょう。
◯÷3=■
<?php
# ◯÷3=■
function keisan($a){
$val = $a / 3;
return $val;
}
echo keisan(12); #4
※#以降はコメントです
順番にみていきましょう。
まず、1行目のfunction keisan($a)についてです。
functionというのは「関数作るで!」という宣言です。※関西弁ですみません
なので、あなたが自作の関数を作りたい時はまずこのfunctionを忘れずにつけるようにしましょう。
次にkeisanの部分です。
これが関数の名称です。なので自由につけることができます。
ただ最初に説明したように、既に存在している関数名であるvar_dumpやcountなどはつけることができません。もちろん既にkeisanという関数が存在している場合は重複してしまうので、沢山作る時は注意してください。
次に($a)の部分です。
これが引数になります。というよりは、引数を格納するようの変数だと理解しておくほうが良いでしょう。
あなたが関数外から値を設定できるのが引数でしたね。引数に値をセットしたは良いものの、その値を関数内で使うためにはそれを受け取るための箱が必要なのです。
この変数もあなたが自由に設定することが出来ます。今回は$aという名称にしましたが、$bでも$hikisuu1でも構いません。
※変数の記述ルールに従う必要はあるので、頭に数字を使ったりすることはできません
function 変数名(引数)という設定方法がわかり、これで関数が宣言できました。では、その関数で実行する内容を{}を使って囲みます。これはforeachやifなどと同じです。
{}がなければ、関数がどこで終わればよいのかがわからなくなってしまいます。
それでは、関数の中身をみてみましょう。
$val = $a / 3;
これは、変数の説明でもやった通り、$valという変数に$a÷3の計算結果を入れるということです。
$aは引数が入った変数です。なので、関数の外部から入力された値がここに入ります。
今回のように12という値がセットされていた場合は、12(引数)÷3の計算結果である4が$valの中に入ります。
では、次の行を見てみましょう。
return $val;
$valに引数÷3の計算結果が入っています。しかし、関数内で作った変数に値を入れても、関数外でそれが使えるわけでは有りません。
関数外で使用するためには、作った値を返してあげる必要があるのです。これが戻り値です。
returnという宣言は、ここで処理が終わったということを宣言するために使用されます。
return;というように、返却する値を宣言しなければ、ただそこで処理が終了するだけになります。結果、戻り値はないのでnullが返却されます。
今回は、計算結果が知りたいのでreturn $val;といったように、計算結果の入った$valを戻り値として指定しています。
さて、関数の処理についてはわかりました。しかし、問題はその関数をどう使えばよいのかということです。
それでは最終行を見てみましょう。
echo keisan(12);
作成した変数を使用するには、関数名(引数)とするだけです。そして、今回はその結果をhtmlで書き出すためにechoを手前に付けました。
keisan(12)では、keisanという関数の引数に12を指定しているということになります。
こうすることで、先ほど作成した関数の引数用の変数である$aに12という値が入ります。
関数内で設定した戻り値は関数そのものに返ってくるため、keisan(12)自体が計算結果である4になります。
もう少しわかりやすく、変数への代入を例にすると
$result = keisan(12);
このようにすれば、$resultという変数の中に、計算結果である4が入るということです。
例2
では、問題2で使用した式を関数にしてみましょう。
◯+△=■
今回は◯と△の2つの引数があります。このように複数の値を関数にセットすることも可能です。
<?php
# ◯+△=■
function keisan2($a, $b){
$val = $a + $b;
return $val;
}
echo keisan2(10, 15); # 25
今回のように、引数を2つ使用したい場合は、($a, $b)のようにコンマ区切りで引数用の変数を準備するだけです。
そして、引数を設定する際も同じ様に
keisan2(10, 15);
というようにコンマ区切りで値をセットすればOKです。
ここで押さえておきたいポイントは、どの値がどの変数に格納されているかです。
上記のコードであれば、$aに10が入り、$bに15が入っています。
それでは関数を宣言する際、以下のように値を逆にするとどうでしょうか。
echo keisan2(15, 10);
最終行の部分で指定する引数の値を逆にしました。
こうすると、関数で準備した引数用の変数では$aに15、$bに10が入ります。
このように、指定する順番がそのまま関数に引数として渡されることがわかります。
1つ目の引数($a)を第1引数、2つ目の引数($b)を第2引数というように呼びます。
もちろん、この要領で3つ、4つと引数を増やしていくことができますが、多くなると指定する順番を間違えてしまったりと混乱してしまう可能性もあるので、注意しなければなりません。
今回例で取り上げた関数は足し算ですが、これが引き算だった場合は引数に入る値が逆になると、計算結果は異なりますね。
例3
では、問題2のように問題3も作ってみましょう。
■−(4+◯+△)=□
<?php
# ■−(4+◯+△)=□
function keisan3($a, $b, $c){
$val = (4 + $a + $b) + $c;
return $val;
}
echo keisan3(3, 5, 7); # 19
引数が3つになりました。
計算式にカッコがなくても足し算の計算だけなので必要ありませんが、問題の式と比べてわかりやすくするためにつけています。
今回の式であれば、◯を$a、△を$b、□を$cに置き換えて引数としています。
この様に入力で使用したい値の数だけ引数を準備してやれば良いだけです。
サンプルコードで関数を読み解く
3つの問題を関数に置き換えることができました。
また、他にも関数を使う上ではで覚えておきたいことが数点ありますので、以下の練習用サンプルコードを使って見てみましょう。
<?php
# 金をくれ
function kane_kure($basho, $tenki, $kingaku=1000000){
if($tenki === '晴れ'){
$message = $basho.'の大きな木の下に'.$kingaku.'円入ったバッグ置くんやで';
}else{
$message = $basho.'の屋根があるとこに'.$kingaku.'円入ったスーツケース置くんやで';
}
return $message;
}
echo kane_kure('すみれ小学校', '晴れ');
# 出力結果「すみれ小学校の大きな木の下に1000000円入ったバッグ置くんやで」
誘拐犯が身代金を要求する際に使用する関数です。全く実用的では有りませんが、書き出き内容によっては使いみちがあるので、これでいきましょう。
誘拐犯のお仕事は、その名の通り誘拐ですね。誘拐する目的はお金なので、誘拐をすればお金を要求しなければなりません。
しかし、毎回毎回要求するメッセージを考えるのは面倒なので、場所と天気と金額だけを決めたら、あとは自動でメッセージを作ってくれるような関数を作りました。
まずは、身代金を置く場所を第1引数で指定しなければなりません。今回は「すみれ小学校」にしましょう。
雨の中、外で待たれるとせっかくのお金が濡れてしまいます。それは困るので、第2引数では天気も入力できるようにしておきます。今回は快晴なので、「晴れ」を指定します。
要求する金額ですが、大体は100万円を要求します。身代金にしてはリーズナブルな気がしますね。
こちらは毎回金額を設定すると面倒なので、初期値として1000000という数値を設定しておきます。
それでは、関数の内容を見てみましょう。
function kane_kure($basho, $tenki, $kingaku=1000000){
まず、関数の宣言についてです。
今までの例と同じ様に、引数を指定していますが、第3引数だけ指定の仕方が違いますね。
引数が多くなってくると、時には「基本的にはこの値を使って」となることがあります。今回であれば、身代金に要求する金額です。
そういった引数に対しては、引数用に準備した変数のあとに=を付けて初期値となる値を代入すればよいのです。
これで、関数を呼び出す際に第3引数は指定しなくても、勝手に100万円を設定してくれます。
ただ、大金持ちの家の子を誘拐したのであれば、もう少し欲しいと思うのが誘拐犯の性です。
そういった時は、関数を呼び出す際に第3引数を設定すれば、そちらの金額が優先されます。
例えば
kane_kure('すみれ小学校', '晴れ', 2000000);
こうすれば、いつもの倍の金額200万円が要求できます。ちょっとしたボーナスですね。
それでは、関数の中身を見てみましょう。
if($tenki === '晴れ'){
ここで、第2引数で入力した天気を判定しています。「晴れ」であれば、その後に記述している
$message = $basho.'の大きな木の下に'.$kingaku.'円入ったバッグ置くんやで';
という内容が$messageにセットされています。
晴れであれば、外での待ち合わせでも問題がなく、鞄も特に指定する必要が有りませんね。
しかし、雨や雪だと外に鞄を置くとお金が濡れてしまいます。くもりだったとしても、いきなり雨が降ってくる危険性があるので、晴れ以外の天気だった場合は別のメッセージをセットします。
}else{
$message = $basho.'の屋根があるとこに'.$kingaku.'円入ったスーツケース置くんやで';
}
elseで、ifの条件に該当しなかった場合の処理を記述します。
今回の条件は「晴れ」なので、もし雨や雪だった場合は、屋根がある場所にスーツケースを置いて欲しい旨のメッセージに変更しています。
この様に、引数の値を条件分岐で使用したり、テキストを差し替えたりすることが出来ます。
もし、金額によって入れる鞄を変更したい場合は「if($kingaku > 3000000)」といったような条件分岐を追加して、メッセージへ入れる内容を変更すれば、より細かな指定ができるようになります。
また、htmlに書き出すだけであれば、戻り値を指定しない使い方も可能です。
<?php
# 金をくれ
function kane_kure($basho, $tenki, $kingaku=1000000){
echo '場所は「'.$basho.'」やで。<br>';
if($tenki === '晴れ'){
echo '大きな木の下に'.$kingaku.'円入ったバッグを頼んだ';
}else{
echo '屋根があるとこに'.$kingaku.'円入ったスーツケースを頼んだ。';
}
}
kane_kure('すみれ小学校', '雨');
# 出力結果
# 場所は「すみれ小学校」やで。
# 屋根があるとこに1000000円入ったスーツケースを頼んだ。
今回は関数内にreturnがありませんね。そして、最終行のkane_kureの前にもechoがありません。
しかし、関数内でechoを使用しています。
関数内でechoを使用した時点で、htmlに書き出されます。なので、わざわざreturnで戻り値を指定しなくても、メッセージを書き出すことが出来ます。
関数で作った結果を変数に値を格納したい場合であれば、今までのように戻り値を設定しなければいけませんが、タグを書き出したりメッセージを書き出したりするだけであれば、戻り値を省略することができるのです。
戻り値がなければ、ただ関数を実行するだけで結果が得られます。なので最終行の関数前にechoを指定しなくても、関数が宣言されればでメッセージが書き出されるのです。
また、関数によっては引数を必要としない場合もあります。
<?php
# 金をくれ
function kane_kure(){
echo 'ええから100万円準備してくれ';
}
kage_kure();
# 出力結果 「ええから100万円準備してくれ」
このように、引数が必要なければ空のカッコを記述するだけです。
今回はただメッセージを書き出しているだけですが、今日の日付を取得してメッセージを作るだけであれば、引数に日付を設定しなくても、関数内部で呼び出すことが出来ます。
<?php
# 今日の日付を教えて
function kyou_no_hiduke(){
echo date('Y年m月d日').'やで';
}
kyou_no_hiduke();
# 出力結果 「2020年05月16日やで」
使い方は自由です。複数回利用するものを関数でまとめることがほとんどですが、1ページの記述量が多くなってしまう際などに関数を使用するような使い方をして、実際に関数へ触れてみるのが良いでしょう。
関数だけをまとめたファイルを読み込む際は
include('関数ファイルへの相対パス');
include_once('関数ファイルへの相対パス');
require('関数ファイルへの相対パス');
require_once('関数ファイルへの相対パス');
このような記述があります。
※どれも問題なく読み込み出来ますが、関数をまとめているだけのphpファイルであればrequire_onceを使えば良いでしょう。
実用的なサンプルコードで関数を読み解く
関数の動きや、引数と戻り値についての理解は大分深まったのではないでしょうか。
それでは次に、配列を引数に使った関数を見てみましょう。
<?php
# 画像タグ生成関数
function img_tag($arg){
$tag = '<img src="/assets/img/'.$arg['file'].'" alt="'.$arg['alt'].'" class="'.$arg['class'].'">';
return $tag;
}
$apple = [
'file' => 'apple.jpg',
'alt' => 'りんご',
'class' => 'fruit_img',
];
echo img_tag($apple);
# 出力結果 「<img src="/assets/img/apple.jpg" alt="りんご" class="fruit_img">」
引数には配列を指定することもできます。取り出し方も至って簡単です。
変数の名称が変わっているだけで、キーは変更されないので、そのままの配列状態を関数内部で使用することができます。
上記の関数のようにimgタグで使用する場合であれば、Retinaの設定など規則性がある場合は関数にしていると便利です。
以下、Retinaの設定をする関数です。
<?php
# Retina対応のimgタグ生成関数
function img_tag($arg){
$tag = '<img src="/assets/img/'.$arg['file_name'].'.'.$arg['extension'].'" srcset="/assets/img/'.$arg['file_name'].'.'.$arg['extension'].' 1x, /assets/img/'.$arg['file_name'].'@2x.'.$arg['extension'].' 2x" alt="'.$arg['alt'].'" class="'.$arg['class'].'">';
return $tag;
}
$apple = [
'file_name' => 'apple',
'extension' => 'jpg',
'alt' => 'りんご',
'class' => 'fruit_img',
];
echo img_tag($apple);
# 出力結果 「<img src="/assets/img/apple.jpg" srcset="/assets/img/apple.jpg 1x, /assets/img/apple@2x.jpg 2x" alt="りんご" class="fruit_img">」
1倍の画像がapple.jp、2倍の画像がapple@2x.jpgという名称で同階層にあることを想定しています。
毎回画像タグにsrcsetを記述するよりは、大分楽になりました。ここまでくれば、使用頻度も込みで関数の便利さが伝わります。
今回は例として引数を配列で渡していますが、第4引数まで設定して渡して運用してももちろん良いでしょう。
複数の戻り値
ではいよいよ最後です。
配列に対して複数の引数を設定できることがわかりました。配列によって、より複雑になっても問題ないこともわかりました。
では、戻り値が複数欲しい場合はどうすればよいのでしょうか。
残念ながら、複数の戻り値を受け取る方法はありません。
なので、どうしても関数で生成した複数の値を返して欲しい時は、戻り値に配列を指定しましょう。
<?php
# 戻り値に配列を指定して、複数の値を戻り値とする
function fukusuu_kure($a){
$var[] = $a + 10;
$var[] = $a + 30;
return $var;
}
$result = fukusuu_kure(10);
# 出力結果 [20, 40]
タグや書き出すだけであれば、前で説明したように関数内でechoをするだけですが、値として使用する場合は、配列に格納するのが一般的です。もっとPHPを使いこなせるようになれば、オブジェクトでも良いでしょう。
WordPressなどであれば、記事を取得するとオブジェクトで返ってきます。複数の結果が得られた際は、foreachやwhileなどを使用してループしながら使用するのが一般的です。
今回のように、ただ複数の値が欲しいだけであれば、返却する配列にキーを設定したりすると、より活用の範囲は広がってきます。
まずは簡単なものから関数化してみてください。先ほど例に挙げたRetinaタグの生成などは実用性があって良いでしょう。
使っていく内に、関数化できる部分が増えていき、より簡潔なコーディングや複雑な処理が実現できるようになってきます。
まとめ
簡単な例を中心に関数についての説明をしていきましたが、いかがだったでしょうか。
関数の動きが理解できれば、既存のコードの多くが読めるようになります。
そうすれば、今までコピペで使用していたようなものも、自分の環境に合わせてカスタムしたり、自分が使いやすいものを自作したりすることができ、より活用の場は増えていくでしょう。
最後に今回のポイントをまとめておきます。
引数はあなたが準備できるもの
戻り値はあなたが欲しいもの
引数を加工して戻り値を作るのが関数
ざっくりとしたまとめですが、この記事を順を追って見ていけば、必ず理解を深めていけるはずですので、諦めずに挑戦してみてください。
関数の部分で挫折する人はとても多いです。
しかし、しっかり読み砕いていくとそこまで難しいものでは有りません。
実際に難しいのは、その中に書かれている処理であって、それも順を追って見ていけば読み解くことができます。
そのためには、第1回で解説した変数に関する知識と、第2回で解説した配列の知識が必要不可欠です。
関数で挫折してしまった人、現在その壁にぶち当たっている人は、是非この記事を読んで基本である関数の動きから理解をしてみましょう。
そうすれば、必ず自由自在に関数を使いこなせるようになるはずですよ。