0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

PHP5上級試験/準上級試験の上級合格に挑戦(4) 3章関数後編

Last updated at Posted at 2021-02-16

前回

上級Ⅱ3章関数前編

  • 副作用をもつ関数
  • 関数表記方法・変数との表記方法の違い

上級Ⅱ3章関数中編

  • スコープ
  • スタティック
  • 上記2つの複合応用問題

※今まで受けてきた中で関数だと、複合応用問題、関数と変数表記方法が主に出題されてると思う

関数後編

入れ子

  • 関数の中に別の関数を定義すること
  • 入れ子にした関数を呼び出すには先にそれを含む関数を呼び出す

下記の出力はどうなるか。

index.php
//(1)
function x(){
 function y(){
   echo 'ご機嫌';
 }
}
x();
y();

//(2)
function x(){
 function y(){
   echo 'ご機嫌';
 }
}
y();

//(3)
function x(){
 function y(){
   echo 'ご機嫌';
 }
}
x();

(1)ご機嫌が出力
(2)エラー終了
(3)エラーはないが、ご機嫌も出力されない
→つまり、x()だけでもy()だけでもだめで、まず先にx()を呼び出し、つぎにy()を呼び出さないといけない

値渡しと参照渡し

  • 値渡しはコピー、参照渡しはそっくりそのまま渡すイメージ
  • デフォルトはもちろん値渡し
  • マクロで言う、byVal,byRef
  • 値渡しはデフォルトそのまま、参照渡しはパラメータの前に&(アンパサンド)をつける

いつものどおり下記の出力を答えてください

index.php
//(1)値渡し
function test($arr) {
  $arr++;
 }
$x = 20;
test($x);
echo $x;

//(2)参照渡し
function test2(&$arr) {
  $arr++;
 }
$x = 20;
test2($x);
echo $x;

 

 
 

上記では、仮引数のほうで(1)のほうは$arrで、値渡し、(2)は&$arrと、参照渡し。
値渡しはコピーを渡しただけなので、外側にある$xは20のまま。
参照渡しはまるごと渡すので、関数内で1こふえてるので21に。
結果、「2021」となる。(改行してないので)

パラメータのデフォルト値

  • パラメータのデフォルト値を決めておいて省略されたときにそれを渡せる
  • マクロで言うOptional

いつものどおり下記の出力を答えてください

index.php
//(1)
function test($x=1,$y=200,$z=300) {
  echo '$x='.$x.'<br>';
  echo '$y='.$y.'<br>';
  echo '$z='.$z.'<br>';
 }
test(1,2,3);
test(1,2);
test(1);

//(2)
function test($x=1,$y=200,$z=300) {
  echo '$x='.$x.'<br>';
  echo '$y='.$y.'<br>';
  echo '$z='.$z.'<br>';
 }
test(,2);
test(,,2);

(1) ここはまあ簡単でしょう
$x=1

$y=2

$z=3

$x=1

$y=2

$z=300

$x=1

$y=200

$z=300

(2)
エラー終了。
このように、頭部分を省略するという書き方はできない。
デフォルト値を持つパラメータに対する引数の指定を省略した場合は、それ以降の引数の指定もすべて省略しないといけない。
つまり、(2)のように、1番目を省略したら続く引数も省略しないといけないってこと。

パラメータと引数の関係

  • 関数のパラメータの数 > 引数 → 指定されなかったパラメータは未設定のまま処理続行(警告あり)
  • 関数のパラメータの数 < 引数 → あまった引数は無視(警告はなし)

いつものどおり下記の出力を答えてください

index.php
//(1)
function test($x,$y) {
  echo '$x='.$x.'<br>';
  echo '$y='.$y.'<br>';
  echo '$z='.$z.'<br>';
 }
test(1,2,3);
test(1);
test();

エラー終了しなかったが、ログを見ると警告が2つ発生
そして、出力はtest(1,2,3)のみだった。それが下記。

$x=1
$y=2
$z=

可変パラメータ

  • 関数が不特定の数のパラメータを必要とするときに利用
  • 「func_num_args()」「func_get_arg()」「func_get_args()」の3つを使う
  • func_num_args()は関数にはいってる引数の数を取得
  • func_get_arg($arg_num)は指定した番号の引数の値を取得。引数は○番目かを指定。Forと一緒に
  • func_get_args()は引数リストを配列化。foreachと一緒に使うことが多いハズ

上記の関数を使って下記コードを書いた

index.php
function test()
{
    $args_num = func_num_args();
    echo "引数の数: $args_num<br>";

    $args_2num  = func_get_arg(1); //2番めの引数を指定
    echo "2番めの引数:$args_2num<br>";

    $args = func_get_args();
    foreach ($args as $s){
      echo $s.",<br>";
    }
}

test(1, 2);
echo "<br>";
test(1,2,3,4,5);
echo "<br>";


こちらの出力は

引数の数: 2
1番めの引数:2
1,
2,

引数の数: 5
1番めの引数:2
1,
2,
3,
4,
5,

となる

その他

return

  • 英語のとおり、返り値を渡せる
  • 返り値が不要でも、このreturn;だけで、その関数を終了させることができる
  • 関数末尾の場合returnがなくてもOK
  • 複数の値を帰す場合はarray()で。カンマ区切りのはない
  • デフォルトで関数からの値はコピー。
  • 参照渡しにしたいなら、先程の通り、関数名の前に&(アンパサンド)をつける。
  • 関数呼び出し側でも関数名の前に&(アンパサンド)をつける。
index.php

function &test(&$x){
  return $x;
}

$x = 1;
$result = &test($x);
$x = 2;
echo $result;

$resultに&test()という関数が格納されているので、
最後の行ではtest()が参照渡しの状態で実行される
したがってこの出力は2になる

可変関数

  • 関数の名前を変数に代入したもの
  • 指定した関数名に対応する関数がないとエラーになる
  • 関数があるかどうかを調べるのはfunction_exists(function_name)でいける
  • また言語構造であるecho()やisset()はこれで呼び出せない

※言語構造とは言語を構成する要素のこと。トークンと言い換えてもいいかも。
例としてifとかforとかある。
紛らわしい例として、echo/isset以外に、print/unset/dieなど。動詞っぽいから紛らわしい。
覚えるしかないが、よく使うのは上のようなものぐらいだと思う。一応下で確認しておこう。
これらは関数ではないので、カッコでくくってもくくらなくてもよい、とされている。
参考→キーワードリスト
ここにあるのは全部言語構造だそう。

index.php
//(1)
function test()
{
  $test_name = 'print';
  $test_name('ご機嫌');
}

//(2)
$test_name = 'print';
if (function_exists($test_name){
  $test_name('ご機嫌');
} else {
  $test_name,'は未定義です';
}

//(3)
$test_name = 'echo';
$test_name('ご機嫌');

(1)が基本。もちろんご機嫌が出力。
(2)も同じくご機嫌が出力。関数があるか確かめてから実行してる点に注目。
(3)エラー。echoやissetはだめ。

### 匿名関数

  • 他の関数と重複しないランダムな名前が割り振られる
  • create_fucntion()で作成
  • パラメータリストで指定されたパラメータと、コードで作成
  • create_fucntion(string $args,string $code);
  • array_filter()などの関数の引数として使用
index.php

$Myfunc = create_function('$x'.'echo $x;);
$Myfunc('hello');

$Myfunc2 = create_function('x', 'return $x >= 80);
$a = array(78,79,80.81,82);
$b = array_filter($a,$Myfunc2);
printf($b);

出力は
Hello,2=>80, 3=>81, 4=82となる

# 今後
上級Ⅱ3章関数前編

  • 副作用をもつ関数
  • 関数表記方法・変数との表記方法の違い

上級Ⅱ3章関数中編

  • スコープ
  • スタティック
  • 上記2つの複合応用問題

上級ⅡⅣ関数後編は下記の通り

  • 入れ子
  • ご機嫌
  • 値渡しと参照渡し
  • パラメータのデフォルト値
  • パラメータと引数の関係
  • 可変パラメータ
  • return
  • 可変関数
  • 匿名関数

長かったけど、これで3章終わり。
引っかかりやすいなーというところは、
可変パラメータ、可変関数だと思います。

頑張って覚えましょう!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?