オプションのパラメーターを持つPHP関数


107

10個のパラメーターを受け入れることができるPHP関数を作成しましたが、必要なのは2つだけです。ときどき、8番目のパラメーターを定義したいのですが、8番目に達するまで、各パラメーターに空の文字列を入力したくありません。

私が持っていた1つのアイデアは、実際の関数に渡すパラメーターの配列を含む抽象化された関数を渡すことでした。

必要なパラメーターのみを渡すことができるように関数を設定するより良い方法はありますか?



それは奇妙です。PHPの組み込み関数には、オプションのパラメーターがあります。では、なぜそのような関数を作成できないのでしょうか。
ロドリゴ

2
これらの回答の多くは時代遅れであることに注意してください... PHPは可変長の引数リストを持つ関数をサポートするようになりました
ashleedawg

回答:


62

関数に1つのパラメーター(配列)を指定させます。配列の値として実際のパラメーターを渡します。


編集: Pekkaのコメント内のリンクは、それを要約したものです。


1
それは奇妙です。PHPの組み込み関数には、オプションのパラメーターがあります。では、なぜそのような関数を作成できないのでしょうか。
ロドリゴ

1
@Rodrigoのような関数を定義することは絶対に可能です。ただし、それらは位置オプションです。これは、単一のオプションパラメータ以外のものについてはかなりお粗末です。
マットボール

1
[OK]で試してみましたが、ここでその方法を確認しました:stackoverflow.com/a/34869/1086511
Rodrigo

Walfの答えを見て取る-ちょうど提案「アレイを使用する」ことを行うことができますより多くあります同様の問題と同じスレッド内とより詳細な例を
DJDave

63

この場合、キーをパラメーター名、値を値とする配列を渡します。

$optional = array(
  "param" => $param1,
  "param2" => $param2
);

function func($required, $requiredTwo, $optional) {
  if(isset($optional["param2"])) {
    doWork();
  }
}

あなたの例では、$ optionalを関数内でグローバルに設定する必要はありませんか?
user481826 2010

1
グローバル?番号..?関数を呼び出す前にその配列を作成し、それを渡します。私のコードは、何をすべきかについてのマットボールズの記述の例です。
ラボット

「配列を使用する」という提案以外にもできることはたくさんあります。同じスレッドでの
Walfの

45

あなたが望むものを達成するために、Rabbotが言ったように配列を使用してください(これは過度に使用される場合、これは文書化/維持するのに苦痛になる可能性があります)。または、従来のオプションの引数を使用します。

//My function with tons of optional params
function my_func($req_a, $req_b, $opt_a = NULL, $opt_b = NULL, $opt_c = NULL)
{
  //Do stuff
}
my_func('Hi', 'World', null, null, 'Red');

しかし、私は通常、その多くの引数を使用して関数/メソッドを書き始めると、コードのにおいであり、よりクリーンなものにリファクタリング/抽出できることがわかります。

//Specialization of my_func - assuming my_func itself cannot be refactored
function my_color_func($reg_a, $reg_b, $opt = 'Red')
{
  return my_func($reg_a, $reg_b, null, null, $opt);
}
my_color_func('Hi', 'World');
my_color_func('Hello', 'Universe', 'Green');

2010年、「コードのにおい」、「リファクタリング」、「コードのメンテナンス」などの概念は、私たちのコミュニティでは一般的ではありませんでした。あなたは私たちのほとんどの前に一歩を踏み出した:)
Billal Begueradj

15

PHP 5.6以降では、引数リストに...トークンを含めることができ、関数が可変数の引数を受け入れることを示します。引数は配列として指定された変数に渡されます。例えば:

...を使用して可変引数にアクセスする例

<?php
function sum(...$numbers) {
    $acc = 0;
    foreach ($numbers as $n) {
        $acc += $n;
    }
    return $acc;
}

echo sum(1, 2, 3, 4);
?>

上記の例は出力します:

10

可変長引数はPHPドキュメントをリストします


この応答はより多くのポイントに値します。私の特定のケースシナリオには適していませんが、情報が豊富で理解しやすい PHP 7.3がまもなく登場します!5.6と7はEOLです。
AdheneManx 2018

12

デフォルト値をnullに設定するだけです。

<?php
function functionName($value, $value2 = null) {
// do stuff
}

2
最良の答えですがnull、日付タイプの非ビットに置き換えてください。たとえばarray()アレイの場合
Mohamed hesham

ありがとう...これは私が探していたものです
Davide De Maestri

12

注:これは、PHP 5.5以前の古い回答です。PHP 5.6+はデフォルトの引数をサポートします

PHP 5.5以前では、次の2つの方法のいずれかを使用してこれを実現できます。

  • 使用func_num_args()およびfunc_get_arg()関数を、
  • NULL引数を使用します。

使い方

function method_1()
{
  $arg1 = (func_num_args() >= 1)? func_get_arg(0): "default_value_for_arg1";
  $arg2 = (func_num_args() >= 2)? func_get_arg(1): "default_value_for_arg2";
}

function method_2($arg1 = null, $arg2 = null)
{
  $arg1 = $arg1? $arg1: "default_value_for_arg1";
  $arg2 = $arg2? $arg2: "default_value_for_arg2";
}

クリーンで理解しやすいので2番目の方法を選びますが、最初の方法が必要になる場合もあります。


1
ここで二重の「=」が必要です。そうしないと、すべての式がtrueを返します。また、2番目の例の式は、変数が常にそれ自体と等しいため、常にtrueを返します。
ChuckieDub

良い点ですが、これは実際に機能します。PHPでは$x = null; if ($x) echo "true"; else echo "false";、$ x変数に値(このコードでは「null」)がある場合でも、このコードは「false」を出力します。また、どちらの方法でも三項演算子を使用しているため、「=」を1つだけ使用するのが適切です。でテストする場合method(); method(1); method(1, 2);、最初の呼び出しはarg1とarg2をデフォルト値に関連付け、2番目の呼び出しは2番目の引数をデフォルト値に関連付け、最初の引数は「1」にします。最後の呼び出しはデフォルト値を関連付けません。
Daniel Loureiro 2013年

1
function method_2($ arg1 = "default_value_fot_arg1"、$ arg2 = "default_value_fot_arg2"){phpはパラメータに関するものを処理し、nullをパラメータとして渡すこともできます(人々がnullを使用する理由はわかりません)
nerkn

1
@nerkn、その通り、PHPは現在デフォルトの引数をサポートしています。笑、簡単なことを達成するために多くの回避策をとる必要があったときのことを覚えています。良い時代:Pただし、古いコード(5.5以前)でもこれらのアプローチを確認できます。
Daniel Loureiro 2017年

4

オブジェクトをparams-transportesとして使用することもできると思います。

$myParam = new stdClass();
$myParam->optParam2 = 'something';
$myParam->optParam8 = 3;
theFunction($myParam);

function theFunction($fparam){      
  return "I got ".$fparam->optParam8." of ".$fparam->optParam2." received!";
}

もちろん、この関数で「optParam8」と「optParam2」のデフォルト値を設定する必要があります。それ以外の場合は、「通知:未定義のプロパティ:stdClass :: $ optParam2」が表示されます。

関数パラメーターとして配列を使用する場合、私はこの方法でデフォルト値を設定するのが好きです:

function theFunction($fparam){
   $default = array(
      'opt1' => 'nothing',
      'opt2' => 1
   );
   if(is_array($fparam)){
      $fparam = array_merge($default, $fparam);
   }else{
      $fparam = $default;
   }
   //now, the default values are overwritten by these passed by $fparam
   return "I received ".$fparam['opt1']." and ".$fparam['opt2']."!";
}

2

有効な状態のオブジェクトを作成するために2つの値のみが必要な場合は、他のすべてのオプションの引数を削除し、それらにセッターを提供できます(実行時にそれらを変更したくない場合を除く)。次に、必要な2つの引数を使用してオブジェクトをインスタンス化し、必要に応じてセッターを通じて他の引数を設定します。

参考文献


2

私はこれが古い記事であることを知っていますが、OPのような問題があり、これが私が思いついたものです。

渡すことができる配列の例。特定の注文が必要な場合は、これを再度注文することができますが、この質問の場合は、要求された内容が実行されます。

$argument_set = array (8 => 'lots', 5 => 'of', 1 => 'data', 2 => 'here');

これは扱いやすく、読みやすく、データ抽出ポイントは、コーディングの任意の場所ですぐに追加および削除でき、しかも大規模な書き換えを回避できます。整数キーを使用してOPの元の質問を集計しましたが、文字列キーも同じように簡単に使用できました。実際、読みやすさのために、私はそれをお勧めします。

これを外部ファイルに貼り付けて簡単に

function unknown_number_arguments($argument_set) {

    foreach ($argument_set as $key => $value) {

        # create a switch with all the cases you need. as you loop the array 
        # keys only your submitted $keys values will be found with the switch. 
        switch ($key) {
            case 1:
                # do stuff with $value
                break;
            case 2:
                # do stuff with $value;
                break;
            case 3:
                # key 3 omitted, this wont execute 
                break;
            case 5:
                # do stuff with $value;
                break;
            case 8:
                # do stuff with $value;
                break;
            default:
                # no match from the array, do error logging?
                break;
        }
    }
return;
}

ファイルの場合、これを最初に置きます。

$argument_set = array(); 

これらを使用して、データの送信元に応じて、次のデータ使用番号/命名を割り当てます。

$argument_set[1][] = $some_variable; 

そして最後に配列を渡します

unknown_number_arguments($argument_set);

1
function yourFunction($var1, $var2, $optional = Null){
   ... code
}

通常の関数を作成し、オプションの変数にデフォルトのNull値を指定して追加できます。

Nullはまだ値です。その変数の値で関数を呼び出さない場合、空ではないためエラーは発生しません。


2
そのすべてをさらに説明できますか?変数名を数字で始めることはできないため、指定されたコードは構文的に無効です
Nico Haase

0

通常、8番目の値を渡すだけの場合は、パラメーターを最初に並べ替えることができます。パラメータを指定する必要があるのは、設定する最後のパラメータまでです。

異なる値を使用している場合は、2つのオプションがあります。

1つは、異なるパラメーターを取り、他のパラメーターにデフォルトを設定する一連のラッパー関数を作成することです。これは、いくつかの組み合わせのみを使用する場合に便利ですが、非常に複雑になる可能性があります。

他のオプションは、キーがパラメータの名前である配列を渡すことです。その後、キーを持つ配列に値があるかどうかを確認し、ない場合はデフォルトを使用できます。しかし、繰り返しになりますが、パラメータが多い場合、これは煩雑になり、多くの追加コードを追加する可能性があります。


0

PHPはデフォルトの引数を許可します(リンク)を。あなたの場合、関数コードに応じて、3から8までのすべてのパラメーターをNULLまたは空の文字列 ""として定義できます。このようにして、最初の2つのパラメーターを使用してのみ関数を呼び出すことができます。

例えば:

<?php
  function yourFunction($arg1, $arg2, $arg3=NULL, $arg4=NULL, $arg5=NULL, $arg6=NULL, $arg7=NULL, $arg8=NULL){
echo $arg1;
echo $arg2;
if(isset($arg3)){echo $arg3;}
# other similar statements for $arg4, ...., $arg5
if(isset($arg8)){echo $arg8;}
}

興味深いアイデア...しかし、あなたの提案は問題を解決しません。実際、どの引数がエコーされているかについての情報を追加すると(たとえばを使用echo " this is arg3: " . $arg3;してなど)、egを呼び出すとが出力されることがわかりyourFunction(3, 2, $arg8=5);ます32 this is arg3: 5。問題は、PHPでオプションのパラメーターを渡すときにパラメーターの位置が重要であることです...パラメーター名パラメータ値をパラメータ名にマップするのに十分ではありません
mastropi

0

使用しないパラメータを無視するようにNullを設定し、位置に応じて必要なパラメータを設定するだけです。

 function myFunc($p1,$p2,$p3=Null,$p4=Null,$p5=Null,$p6=Null,$p7=Null,$p8=Null){
    for ($i=1; $i<9; $i++){
        $varName = "p$i";
        if (isset($$varName)){
            echo $varName." = ".$$varName."<br>\n";
        }
    }
}   

myFunc( "1", "2", Null, Null, Null, Null, Null, "eight" );

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.