좋아, PHP에서 인수를 건너 뛰는 방법을 완전히 잊었습니다.
내가 가지고 있다고 가정 해 봅시다.
function getData($name, $limit = '50', $page = '1') {
...
}
중간 매개 변수가 기본값 (예 : '50')을 사용하도록이 함수를 어떻게 호출합니까?
getData('some name', '', '23');
위의 내용이 맞습니까? 나는 이것을 작동시킬 수없는 것 같다.
좋아, PHP에서 인수를 건너 뛰는 방법을 완전히 잊었습니다.
내가 가지고 있다고 가정 해 봅시다.
function getData($name, $limit = '50', $page = '1') {
...
}
중간 매개 변수가 기본값 (예 : '50')을 사용하도록이 함수를 어떻게 호출합니까?
getData('some name', '', '23');
위의 내용이 맞습니까? 나는 이것을 작동시킬 수없는 것 같다.
답변:
귀하의 게시물이 정확합니다.
불행히도 매개 변수 목록의 맨 끝에 선택적 매개 변수를 사용해야하는 경우 마지막 매개 변수까지 모든 것을 지정해야합니다. 일반적으로 당신이 앤 매치를 혼합하려는 경우, 당신은 그들에게의 디폴트 값을 제공 ''
또는 null
, 그들은 그 기본값 경우 함수 내에서 사용하지 않습니다.
$limit = is_numeric($limit) ? $limit : '50';
의 시작 부분에 GetData의의 기능
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로 설정합니다.
건너 뛴 매개 변수에 대해서는 기본 매개 변수를 사용하여 안전을 유지하십시오.
(기본 매개 변수가 ''또는 이와 유사하거나 그 반대 인 경우 null로 설정하면 문제가 발생합니다 ...)
위에서 언급했듯이 매개 변수를 건너 뛸 수 없습니다. 나는 주석을 달기에 너무 큰 부록을 제공하기 위해이 답변을 작성했습니다.
@Frank Nocke 는 기본 매개 변수를 사용하여 함수를 호출하도록 제안 합니다.
function a($b=0, $c=NULL, $d=''){ //...
당신은 사용해야합니다
$var = a(0, NULL, 'ddd');
기능적으로 처음 두 개를 생략하는 것과 동일합니다 ( $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.
이 기본 상수는 코드 전체에서 정확히 한 번 정의되므로 (메서드 선언에도 값이 없음) 예기치 않은 변경이 발생하는 경우 항상 올바른 기본값으로 함수 / 메서드를 제공합니다.
물론이 솔루션의 명확성은 원시 기본값 (예 : 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()
인수가 "선택 사항" 인지 확인하기 만하면됩니다 (기본값이 있음을 의미). 그렇다면 단순히 기본값을 인수에 할당합니다.
앞서 언급 했듯이 아무것도 변경되지 않았습니다. 그러나 너무 많은 매개 변수 (특히 선택적 매개 변수)는 코드 냄새의 강력한 지표입니다.
아마도 당신의 기능이 너무 많은 일을하고있을 것입니다 :
// 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 = 배열 ( '한도'=> 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의 현대적인 디자인 패턴 중 하나 인 객체 지향 프로그래밍에 대해 외칩니다. 원시 스칼라 데이터 유형의 모음을 삽입하는 대신 함수에 필요한 모든 데이터를 포함하는 "주입 된 객체"를 사용하는 것이 좋습니다. http://php.net/manual/en/language.types.intro.php
주입 된 개체에는 속성 유효성 검사 루틴 등이있을 수 있습니다. 주입 된 개체에 대한 데이터의 인스턴스화 및 주입이 모든 유효성 검사를 통과 할 수없는 경우 코드는 즉시 예외를 throw 할 수 있으며 애플리케이션은 처리의 어색한 프로세스를 피할 수 있습니다. 잠재적으로 불완전한 데이터로.
주입 된 개체를 입력하여 배포하기 전에 실수를 포착 할 수 있습니다. 이 기사에는 몇 년 전의 아이디어 중 일부가 요약되어 있습니다.
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;
...
}
?>
도움이 되었기를 바랍니다.