「PHP/入門/関数とは」の版間の差分

削除された内容 追加された内容
Ef3 (トーク | 投稿記録)
→‎ジェネレター: ジェネレター関数は、値を返す代わりに、yieldで必要なだけの値を生成することを除けば、通常の関数と同じように見えます。 yieldを含む関数はすべてジェネレター関数です。 ジェネレター関数が呼び出されると、繰返し実行可能なオブジェクト(iterable型のオブジェクト)が返されます。 そのオブジェクトに対して反復処理を行うと (たとえば foreach ループで)、 PHP は値が必要になるたびにオブジェクトの反復処理用メソッドをコールし、 ジェネレターが値を返した時点でその状態を保存して、次の値が必要になったときに再開できるようにします。 生成する値がなくなったら、ジェネレターは単に終了し、呼出し元のコードは配列の値がなくなったときと同じように続行できます。
タグ: 2017年版ソースエディター
Ef3 (トーク | 投稿記録)
タグ: 2017年版ソースエディター
1 行
<includeonly>
== 基本 ==
=== ユーザー定義関数 ===
</includeonly>
== 関数の定義と呼出し ==
PHPでは、ひとまとまりの処理に名前をつけ、あとから何度も呼出せるようにする仕組みがあります。
これを'''関数'''(かんすう;【英】Function)といいます。
57 ⟶ 59行目:
 
=== 値を返す関数 ===
関数は、呼出し元に値を返すことができます。
関数は、呼び出し元に確定したデータを出力することもできる。なお、確定したデータのことをプログラミング用語で一般に「値」(ち、あたい)という。データが確定さえしていれば、数値でなくても文字列であっても、プログラミングでいう「値」である。
値を返すには <code>return</code>文を使い、<code>return</code>は単一の式を取ります。
もし、<code>return</code>に値を与えないと、その関数の戻値型は void 型となります。
 
例えば、下記のコードは、単純に関数fが1を返す関数である
関数が呼び出し元に確定データを与える事を、関数が「値を返す」という。
 
 
値を返すには <code>return </code>という宣言を使う。returnはその後に書かれた確定値 (整数、浮動小数、文字列) を返す。
 
 
例えば、下記のコードは、単純に関数fが1を返す関数である。
 
:<syntaxhighlight lang=php>
<?php
function f() {
return 1;
}
 
$a =echo f();
 
echo $a;
 
?>
</syntaxhighlight>
;実行結果
 
実行結果
1
:と表示されます
 
;解説
: 上記コードを実行すると、まずf()が呼び出され、f()から1が返され、その値が $a に代入されます。
: PHPの代入演算子は右結合かつ右辺の値を返すので、<code>$a = $b = 0;</code> は、<code>$a = ( $b = 0 );</code>と解され、<code>$a = 0; $b = 0;</code>と同じ結果となります。
 
;参考
:<syntaxhighlight lang=php>
<?php
$num =echo pi();
 
print $num;
?>
</syntaxhighlight>
;実行結果
 
を実行すると、
3.1415926535898
:<code>pi()</code> は、円周率の数値を返す関数である
のように表示される。
 
<code>pi()</code> は、円周率の数値を返す関数である。
 
=== 関数の引数と戻値 ===
171 ⟶ 157行目:
 
==== 型宣言 ====
型宣言は、関数の引数や返り値、そして PHP 7.4.0 以降ではクラスのプロパティに追加することができます。
これらは、呼出し時に指定した型の値であることを保証し、 そうで一致しない場合は TypeError がスローされます。
strict_types を 1 にセットすると、型宣言漏れをエラーにできます。
 
209 ⟶ 196行目:
|-
| classまたはinterfacd の名前
| 値は与えられたクラスまたはインターフェースのインスタンスでなければならないりません
|
|-
|self
| 値は型宣言が使用されているクラスと同じクラスのインスタンスでなければならないりません。クラス内でのみ使用可能。
|
|-
|parent
|型宣言が使われているクラスの親のインスタンスでなければならないりません。クラス内でのみ使用可能。
|
|-
|array
|値は配列でなければならないりません
|
|-
229 ⟶ 216行目:
|-
|bool
|値はブール値でなければならないりません
|
|-
|float
|値は浮動小数点数でなければならないりません
|
|-
|int
|値は整数値でなければならないりません
|
|-
|string
|値は文字列でなければならないりません
|
|-
320 ⟶ 307行目:
関数の内側で作られた変数は関数を抜けると揮発します。
 
関数から抜けても、次回の呼出しで値を保持してほしいときは、ローカル変数を static 宣言します。
;[https://paiza.io/projects/4e_Gl-me4bQZ_jNrTuKOLg?language=php 例]:<syntaxhighlight lang=php line highlight=5>
<?php
375 ⟶ 362行目:
</syntaxhighlight>
: 関数の中で別の関数を定義することは可能ですが意味はありません。
: 定義した関数の中で inner() を呼出すことは複数回できます。
: 定義した関数を抜けたあとも、定義した関数を呼出すことはできます。
: ですが、関数内で定義された関数から「外側の」ローカル変数は参照できません。
: global 宣言した変数は、「外側の」ローカル変数ではなくトップレベルの変数です。
: あまつさえ、関数を定義する関数を二回呼出すと、<code>PHP Fatal error: Cannot redeclare</code> と致命的エラーです。
; これは、関数内で別の関数を定義しても関数スコープにはならず'''クロージャではない'''ことを表しています。
}}
456 ⟶ 443行目:
</syntaxhighlight>
:整数の累乗を求める関数 <code>ipow()</code> と、整数を3桁ごとに ',' で区切ってた文字列を返す関数 <code>comma3()</code> を定義しました。
:2つの関数とも定義が再帰的なので、再帰的呼出しで実装しています。
:再帰的呼出しは、終了条件を間違えると「無限再帰」に陥ってしまい、資源(この場合はスタック)を喰いつくすまで帰ってきません。
:アルゴリズムが再帰的な場合、再帰的呼出しを行う関数として実装するとコードは短くなりますが、PHPの処理系はtailrecのような最適化は行わないので、関数呼出しのオーバーヘッドが再帰のたびに課金され、資源にも優しくないので、再帰で実装したあと回帰テストを書き、ループで実装しテストを通ることを確認するのがベターでしょう。
464 ⟶ 451行目:
<code>yield</code>を含む関数はすべてジェネレター関数です。
 
ジェネレター関数が呼出されると、繰返し実行可能なオブジェクト(<code>iterable</code>型のオブジェクト)が返されます。
そのオブジェクトに対して反復処理を行うと (たとえば foreach ループで)、 PHP は値が必要になるたびにオブジェクトの反復処理用メソッドをコールし、 ジェネレターが値を返した時点でその状態を保存して、次の値が必要になったときに再開できるようにします。