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
ある場合は関数内で使用しないでください。
いいえ、この方法で引数をスキップすることはできません。引き渡し引数を省略することができるのは、引数がパラメーター リストの最後にある場合のみです。
これに対する公式の提案がありました: https://wiki.php.net/rfc/skipparams、これは却下されました。提案ページは、このトピックに関する他の SO の質問にリンクしています。
false
またはのようなデフォルトを指定する以外に、引数を「スキップ」する方法はありませんnull
。
これに関しては、PHP には構文糖衣が不足しているため、次のようなものがよく見られます。
checkbox_field(array(
'name' => 'some name',
....
));
コメントで雄弁に述べられているように、配列を使用して名前付き引数をエミュレートしています。
これにより究極の柔軟性が得られますが、場合によっては必要ない場合もあります。少なくとも、ほとんどの場合、期待されていないと思われるものはすべて、引数リストの最後に移動できます。
オプションの引数をスキップできることに関しては何も変わっていませんが、正しい構文のために、スキップしたい引数に 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 に設定されます。
スキップされた(必要な)パラメーターについては、安全のためにデフォルトのパラメーターを使用してください。
(デフォルトのパラメーターが '' などである場合に null を設定するか、その逆を行うと、問題が発生します...)
引数をスキップすることはできませんが、配列パラメーターを使用でき、パラメーターの配列であるパラメーターを 1 つだけ定義する必要があります。
function myfunction($array_param)
{
echo $array_param['name'];
echo $array_param['age'];
.............
}
パラメータは必要な数だけ追加でき、定義する必要はありません。関数を呼び出すときは、次のようにパラメーターを配置します。
myfunction(array("name" => "Bob","age" => "18", .........));
前述のとおり、パラメータをスキップすることはできません。この回答は、コメントに入れるには大きすぎる補遺を提供するために書きました。
@Frank Nockeは、デフォルトのパラメーターを使用して関数を呼び出すことを提案しているため、たとえば
function a($b=0, $c=NULL, $d=''){ //...
あなたが使用する必要があります
$var = a(0, NULL, 'ddd');
$b
これは、最初の 2 つの (および$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.
このデフォルト定数は、コード全体で一度だけ定義されることに注意してください (メソッド宣言にも値はありません)。そのため、予期しない変更があった場合は、関数/メソッドに常に正しいデフォルト値を指定します。
もちろん、このソリューションの明快さは、読者に何も言わない生のデフォルト値 ( など) をNULL
提供するよりも優れています。0
$var = a(,,'ddd');
(私は、好きなように呼び出すことが最良の選択肢になることに同意します)
このスニペット:
function getData($name, $options) { $default = 配列( '制限' => 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 で必要なことは実現できません。
ただし、このコードを関数の先頭に配置して、機能を取得できます。
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であり、引数が「オプション」であるかどうかを確認するだけです(デフォルト値があることを意味します)。はいの場合、引数にデフォルト値を割り当てるだけです。
これは私がすることです:
<?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 */
?>
これが誰かを助けることを願っています
前にアドバイスしたように、何も変わっていません。ただし、パラメーター (特にオプションのパラメーター) が多すぎると、コードの匂いが強いことを示すことに注意してください。
おそらく、あなたの関数はやりすぎです:
// 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, $limit = NULL, $page = '1') {
if (!$limit){
$limit = 50;
}
}
getData('some name', '', '23');
@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;
...
}
?>
お役に立てれば。
getData('some name');
それらを渡さないでください。デフォルト値が受け入れられます