OK PHPで引数をスキップする方法を完全に忘れてしまいました。
私が持っているとしましょう:
function getData($name, $limit = '50', $page = '1') {
...
}
中央のパラメーターがデフォルト値(つまり、「50」)になるように、この関数をどのように呼び出しますか?
getData('some name', '', '23');
上記は正しいでしょうか?これが機能しないようです。
OK PHPで引数をスキップする方法を完全に忘れてしまいました。
私が持っているとしましょう:
function getData($name, $limit = '50', $page = '1') {
...
}
中央のパラメーターがデフォルト値(つまり、「50」)になるように、この関数をどのように呼び出しますか?
getData('some name', '', '23');
上記は正しいでしょうか?これが機能しないようです。
回答:
あなたの投稿は正しいです。
残念ながら、パラメーターリストの最後でオプションのパラメーターを使用する必要がある場合は、最後のパラメーターまですべてを指定する必要があります。一般的に、組み合わせて一致させる場合は、''
またはのデフォルト値を指定し、それらがデフォルト値であるnull
場合は関数内で使用しないでください。
$limit = is_numeric($limit) ? $limit : '50';
の最初に行います
false
またはのようなデフォルトを指定する以外に、引数を「スキップ」する方法はありませんnull
。
これに関してPHPには構文上の砂糖がないので、次のようなものがよく見られます。
checkbox_field(array(
'name' => 'some name',
....
));
これは、雄弁にコメントで述べたように、配列を使用して名前付き引数をエミュレートしています。
これにより、究極の柔軟性が得られますが、場合によっては必要ないこともあります。少なくとも、ほとんどの場合は予期しないと思われるものを引数リストの最後に移動できます。
いいえ、この方法で引数をスキップすることはできません。引数の受け渡しのみ省略できますは、パラメーターリストの最後にある場合にます。
これに関する公式の提案がありました: https //wiki.php.net/rfc/skipparams、拒否されました。提案ページは、このトピックに関する他のSOの質問にリンクしています。
オプションの引数をスキップできることに関しては何も変更されていませんが、正しい構文とスキップしたい引数にNULLを指定できるようにするには、次のようにします。
define('DEFAULT_DATA_LIMIT', '50');
define('DEFAULT_DATA_PAGE', '1');
/**
* getData
* get a page of data
*
* Parameters:
* name - (required) the name of data to obtain
* limit - (optional) send NULL to get the default limit: 50
* page - (optional) send NULL to get the default page: 1
* Returns:
* a page of data as an array
*/
function getData($name, $limit = NULL, $page = NULL) {
$limit = ($limit===NULL) ? DEFAULT_DATA_LIMIT : $limit;
$page = ($page===NULL) ? DEFAULT_DATA_PAGE : $page;
...
}
これはこのようにしてgetData('some name',NULL,'23');
呼び出すことができます。将来この関数を呼び出す人は、毎回デフォルトを宣言したり、定数を宣言したりする必要はありません。
簡単な答えは「いいえ」です。しかし、なぜ議論を再整理するときにスキップしてこれを達成するのですか?
あなたのものは「デフォルトの関数引数の誤った使用法」であり、期待どおりに機能しません。
PHPドキュメントの補足:
デフォルトの引数を使用する場合、デフォルトはデフォルト以外の引数の右側にある必要があります。そうでなければ、物事は期待どおりに動作しません。
以下を検討してください。
function getData($name, $limit = '50', $page = '1') {
return "Select * FROM books WHERE name = $name AND page = $page limit $limit";
}
echo getData('some name', '', '23'); // won't work as expected
出力は次のようになります。
"Select * FROM books WHERE name = some name AND page = 23 limit"
デフォルトの関数引数の正しい使用法は次のようになります。
function getData($name, $page = '1', $limit = '50') {
return "Select * FROM books WHERE name = $name AND page = $page limit $limit";
}
echo getData('some name', '23'); // works as expected
出力は次のようになります。
"Select * FROM books WHERE name = some name AND page = 23 limit 50"
非デフォルトの後に右側にデフォルトを置くと、定義されていない/指定されていない場合、その変数のデフォルト値が常に返されます。ここにリンクがありますれます。参照用とこれらの例の。
編集:null
他の人が提案しているように設定することは機能する可能性があり、別の代替手段ですが、必要なものに適合しない場合があります。定義されていない場合、デフォルトは常にnullに設定されます。
上記のように、パラメーターをスキップすることはできません。この回答は、コメントに入れるには大きすぎる補遺を提供するために書きました。
@Frank Nocke は、デフォルトのパラメーターで関数を呼び出すことを提案しているため、たとえば
function a($b=0, $c=NULL, $d=''){ //...
あなたは使うべきです
$var = a(0, NULL, 'ddd');
これは、最初の2つの($b
および$c
)パラメーターを省略した場合と機能的に同じになります。
どれがデフォルトかは明らかではありません( 0
であるかはデフォルト値を提供するために入力されていますか、それとも重要ですか?)
関数(またはメソッド)の作成者がデフォルト値を変更できる場合、デフォルト値の問題が外部(または組み込み)関数に関連する危険もあります。したがって、プログラムで呼び出しを変更しないと、意図せずにその動作が変更される可能性があります。
一部の回避策はDEFAULT_A_B
、「関数AのBパラメータのデフォルト値」や「省略」パラメータなどのグローバル定数を定義することです。
$var = a(DEFAULT_A_B, DEFAULT_A_C, 'ddd');
クラスの場合、クラス定数を定義すると、それらがグローバルスコープの一部になるため、より簡単でエレガントになります。
class MyObjectClass {
const DEFAULT_A_B = 0;
function a($b = self::DEFAULT_A_B){
// method body
}
}
$obj = new MyObjectClass();
$var = $obj->a(MyObjectClass::DEFAULT_A_B); //etc.
このデフォルト定数はコード全体で1回だけ定義されるため(メソッド宣言にも値はありません)、予期しない変更が発生した場合は、常に関数/メソッドに正しいデフォルト値を指定します。
この溶液の透明性は、より良い生のデフォルト値(のような供給よりももちろんありNULL
、0
読者に何も言わないなど)。
(私はのような呼び出し$var = a(,,'ddd');
が最良の選択肢であることに同意します)
引数をスキップすることはできませんが、配列パラメーターを使用でき、パラメーターの配列である1つのパラメーターのみを定義する必要があります。
function myfunction($array_param)
{
echo $array_param['name'];
echo $array_param['age'];
.............
}
また、必要な数のパラメーターを追加できます。パラメーターを定義する必要はありません。関数を呼び出すときは、次のようにパラメーターを配置します。
myfunction(array("name" => "Bob","age" => "18", .........));
他の誰もがすでに言ったように、あなたが望むものは、関数にコード行を追加することなしにPHPでは不可能です。
ただし、次のコードを関数の先頭に配置して、機能を取得できます。
foreach((new ReflectionFunction(debug_backtrace()[0]["function"]))->getParameters() as $param) {
if(empty(${$param->getName()}) && $param->isOptional())
${$param->getName()} = $param->getDefaultValue();
}
したがって、基本的にはdebug_backtrace()
このコードが配置されている関数名を取得し、新しいReflectionFunction
オブジェクトを作成してすべての関数引数をループします。
ループでは、関数の引数がempty()
ANDであり、引数が「オプション」である(デフォルト値があることを意味する)かどうかを確認します。はいの場合、デフォルト値を引数に割り当てます。
以前にアドバイスしたように、何も変更されませんでした。ただし、パラメーターが多すぎる(特にオプションのパラメーターが多い)ことは、コードの臭いを示す強力な指標です。
おそらくあなたの関数はやりすぎです:
// first build context
$dataFetcher->setPage(1);
// $dataFetcher->setPageSize(50); // not used here
// then do the job
$dataFetcher->getData('some name');
一部のパラメーターは論理的にグループ化できます。
$pagination = new Pagination(1 /*, 50*/);
getData('some name', $pagination);
// Java coders will probably be familiar with this form:
getData('some name', new Pagination(1));
最後の手段として、いつでもアドホックパラメータオブジェクトを導入できます。
$param = new GetDataParameter();
$param->setPage(1);
// $param->setPageSize(50); // not used here
getData($param);
(これは、あまり正式でないパラメーター配列手法の美化されたバージョンです)
場合によっては、パラメーターをオプションにする理由そのものが間違っていることがあります。この例では、$page
本当にオプションであることを意図していますか?いくつかの文字を保存すると本当に違いがありますか?
// dubious
// it is not obvious at first sight that a parameterless call to "getData()"
// returns only one page of data
function getData($page = 1);
// this makes more sense
function log($message, $timestamp = null /* current time by default */);
このスニペット:
function getData($ name、$ options){ $ default = array( 「限界」=> 50、 'ページ' => 2 ); $ args = array_merge($ default、$ options); print_r($ args); } getData( 'foo'、array()); getData( 'foo'、array( 'limit' => 2)); getData( 'foo'、array( 'limit' => 10、 'page' => 10));
答えは:
アレイ ( [制限] => 50 [ページ] => 2 ) アレイ ( [制限] => 2 [ページ] => 2 ) アレイ ( [制限] => 10 [ページ] => 10 )
これは私がすることです:
<?php
function getData($name, $limit = '', $page = '1') {
$limit = (EMPTY($limit)) ? 50 : $limit;
$output = "name=$name&limit=$limit&page=$page";
return $output;
}
echo getData('table');
/* output name=table&limit=50&page=1 */
echo getData('table',20);
/* name=table&limit=20&page=1 */
echo getData('table','',5);
/* output name=table&limit=50&page=5 */
function getData2($name, $limit = NULL, $page = '1') {
$limit = (ISSET($limit)) ? $limit : 50;
$output = "name=$name&limit=$limit&page=$page";
return $output;
}
echo getData2('table');
// /* output name=table&limit=50&page=1 */
echo getData2('table',20);
/* output name=table&limit=20&page=1 */
echo getData2('table',NULL,3);
/* output name=table&limit=50&page=3 */
?>
これが誰かを助けることを願っています
これは、いくつかの技術的に有能な答えを持つ古い質問のようなものですが、PHPの最新の設計パターンの1つであるオブジェクト指向プログラミングを求めています。プリミティブスカラーデータ型のコレクションを注入する代わりに、関数が必要とするすべてのデータを含む「注入されたオブジェクト」の使用を検討してください。 http://php.net/manual/en/language.types.intro.php
注入されたオブジェクトには、プロパティ検証ルーチンなどがある場合があります。注入されたオブジェクトへのデータのインスタンス化と注入がすべての検証に合格できない場合、コードはすぐに例外をスローし、アプリケーションは扱いにくい処理を回避できます。不完全なデータが含まれている可能性があります。
展開する前に、注入されたオブジェクトにタイプヒントを付けて、間違いを見つけることができます。アイデアのいくつかは、数年前のこの記事にまとめられています。
https://www.experts-exchange.com/articles/18409/Using-Named-Parameters-in-PHP-Function-Calls.html
オプションのパラメーターでファクトリーを作成する必要がありましたが、私の回避策は、nullの合体演算子を使用することでした:
public static function make(
string $first_name = null,
string $last_name = null,
string $email = null,
string $subject = null,
string $message = null
) {
$first_name = $first_name ?? 'First';
$last_name = $last_name ?? 'Last';
$email = $email ?? 'foo@bar.com';
$subject = $subject ?? 'Some subject';
$message = $message ?? 'Some message';
}
使用法:
$factory1 = Factory::make('First Name Override');
$factory2 = Factory::make(null, 'Last Name Override');
$factory3 = Factory::make(null, null, null, null 'Message Override');
かわいらしいことではありませんが、ファクトリーでテストに使用するのに適したパターンかもしれません。
これを試して。
function getData($name, $limit = NULL, $page = '1') {
if (!$limit){
$limit = 50;
}
}
getData('some name', '', '23');
関数呼び出しで中間パラメーターをスキップすることはできません。しかし、これで回避できます:
function_call('1', '2', '3'); // Pass with parameter.
function_call('1', null, '3'); // Pass without parameter.
関数:
function function_call($a, $b='50', $c){
if(isset($b)){
echo $b;
}
else{
echo '50';
}
}
@IbrahimLawalが指摘したように。それらをnull
値に設定することをお勧めします。渡さnull
れた値が、定義したデフォルトを使用しているかどうかを確認してください。
<?php
define('DEFAULT_LIMIT', 50);
define('DEFAULT_PAGE', 1);
function getData($name, $limit = null, $page = null) {
$limit = is_null($limit) ? DEFAULT_LIMIT : $limit;
$page = is_null($page) ? DEFAULT_PAGE : $page;
...
}
?>
お役に立てれば。