함수에서 기본 인수 사용


177

PHP 함수의 기본값에 대해 혼란 스럽습니다. 다음과 같은 기능이 있다고 가정 해보십시오.

function foo($blah, $x = "some value", $y = "some other value") {
    // code here!
}

$ x에 기본 인수를 사용하고 $ y에 다른 인수를 설정하려면 어떻게합니까?

나는 다른 방법으로 실험 해 왔으며 점점 혼란스러워지고 있습니다. 예를 들어, 나는이 두 가지를 시도했다 :

foo("blah", null, "test");
foo("blah", "", "test");

그러나 두 가지 모두 $ x에 대한 적절한 기본 인수는 아닙니다. 또한 변수 이름으로 설정하려고했습니다.

foo("blah", $x, $y = "test");   

나는 이런 식으로 작동 할 것으로 기대했다. 그러나 예상대로 작동하지 않습니다. 어쨌든 함수를 호출 할 때마다 기본 인수를 입력해야합니다. 그리고 나는 분명한 것을 놓치고 있어야합니다.


68
당신은 아마 아무것도 빠지지 않을 것입니다. PHP 개발자는 아마도 이것을 놓쳤을 것입니다.
Matti Virkkunen

흥미로운 질문입니다. 원본에 의존하는 것이 확실하지 않은 경우 기본 프로그래머 만 사용하여 다른 프로그래머가 상속 한 함수를 확장하기 때문에 실제로이 작업을 수행 할 필요가 없었습니다. 답이 궁금합니다.
Kai Qing

3
내가 본 최고의 질문 중 하나! 아무것도 지나치지 않았습니까? foo("blah", , "test");?
Madara의 유령

2
기본 인수는 인수 만 따를 수 있습니다. 즉, foo ( "blah") 및 x, y가 기본값이거나 foo ( "Blah", "xyz")이고 y가 기본값 일 수 있습니다.
마우스 음식

1
예상되는 행동. php.net/manual/en/functions.arguments.php의 "기본 인수 값"섹션을 참조하십시오. null 값과 빈 문자열은 함수에 대한 실제 인수로 허용됩니다.
jmdavalos

답변:


164

함수 선언을 다음과 같이 변경하여 원하는 것을 수행 할 것을 제안합니다.

function foo($blah, $x = null, $y = null) {
    if (null === $x) {
        $x = "some value";
    }

    if (null === $y) {
        $y = "some other value";
    }

    code here!

}

이렇게 foo('blah', null, 'non-default y value');하면 두 번째 매개 변수가 $x여전히 기본값을 가져 오는 것처럼 원하는 방식으로 전화를 걸고 원하는대로 작동 할 수 있습니다 .

이 방법을 사용하면 null 값을 전달하면 그 뒤에 오는 매개 변수의 기본값을 재정의하려는 경우 한 매개 변수의 기본값을 원한다는 의미입니다.

다른 답변에서 언급했듯이

기본 매개 변수는 함수의 마지막 인수로만 작동합니다. 함수 정의에서 기본값을 선언하려는 경우 하나의 매개 변수를 생략하고 그 뒤에있는 매개 변수를 대체 할 방법이 없습니다.

다양한 수의 매개 변수와 다양한 유형의 매개 변수를 사용할 수있는 방법이 있다면 Ryan P가 표시 한 답변과 비슷한 함수를 선언하는 경우가 많습니다.

다음은 또 다른 예입니다 (이것은 귀하의 질문에 대답하지 않지만 유익한 정보입니다 :

public function __construct($params = null)
{
    if ($params instanceof SOMETHING) {
        // single parameter, of object type SOMETHING
    } else if (is_string($params)) {
        // single argument given as string
    } else if (is_array($params)) {
        // params could be an array of properties like array('x' => 'x1', 'y' => 'y1')
    } else if (func_num_args() == 3) {
        $args = func_get_args();

        // 3 parameters passed
    } else if (func_num_args() == 5) {
        $args = func_get_args();
        // 5 parameters passed
    } else {
        throw new InvalidArgumentException("Could not figure out parameters!");
    }
}

$ x = isset ($ x) 아닙니까? $ x : '기본 값'; ?
zloctb

@zloctb 이것은 깨끗하고 읽을 수있는 null 검사입니다. 개발자가 선호하는 것 같습니다. $ x = isset ($ x)입니까? $ x : '기본 값'; 또는 $ x = is_null ($ x)? 'default value': $ x; 이 솔루션뿐만 아니라 작동합니다. 가독성 및 유지 관리에 대한 기본 선택입니다.
DeveloperWeeks

9
미래의 독자들을 위해 명확히하기 위해. 첫 번째 솔루션은 null매번 기본값을 할당 할 때마다 매개 변수에 실제 값 을 할당하는 것을 불가능하게합니다 . 실제로 null을 원할 때 (예 : $ x == "use_null"이 $ x = null 인 경우) 다른 특수 값이있는 경우에도 특수 값을 리터럴 값으로 할당 할 수 없습니다 매개 변수 (이 경우 "use_null"문자열). 따라서 기본값을 사용하고 싶을 때 (그리고 null유효한 옵션 이 되길 원할 때) 절대로 원치 않는 고유 한 "키"를 사용해야합니다.
DiegoDD

37

선택적 인수는 함수 호출이 끝날 때만 작동합니다. $ x를 지정하지 않고 함수에서 $ y에 값을 지정하는 방법은 없습니다. 일부 언어는 명명 된 매개 변수 (예 : VB / C #)를 통해이를 지원하지만 PHP는 지원하지 않습니다.

인수 대신 매개 변수에 연관 배열을 사용하는 경우이를 에뮬레이션 할 수 있습니다. 즉

function foo(array $args = array()) {
    $x = !isset($args['x']) ? 'default x value' : $args['x'];
    $y = !isset($args['y']) ? 'default y value' : $args['y'];

    ...
}

그런 다음 함수를 다음과 같이 호출하십시오.

foo(array('y' => 'my value'));

1
isset($args['x'])현재 빈 문자열, 빈 배열 또는 false기본값으로 대체되므로 조건은 실제로 입니다.
Tim Cooper

@TimCooper lol 나는 첫 번째 의견을 기반으로 '=== null'이어야하며 isset을 대신 사용하여 답변을 변경 한 다음 의견을 변경 한 것을 다시 보았습니다. : D
Ryan P

아아! 나는 전혀 마음에 들지 않습니다 ... 아, 당신은 모든 것을 가질 수는 없습니다. 나는 기본 논증의 순서에 대해 조금 더 생각해야 할 것이라고 생각합니다. 감사!
renosis

불행히도이 답변으로 null을 할당 할 수 없습니다. 이것은 더 나은 옵션입니다 : $x = !array_key_exists('x',$args) ? 'default x value' : $args['x'];
Frank Forte

20

실제로 가능합니다 :

foo( 'blah', (new ReflectionFunction('foo'))->getParameters()[1]->getDefaultValue(), 'test');

당신이 그렇게하고 싶은지는 또 다른 이야기입니다 :)


최신 정보:

이 솔루션을 피하는 이유는 다음과 같습니다.

  • 그것은 (논쟁 적으로) 추악하다
  • 명백한 오버 헤드가 있습니다.
  • 다른 답변이 증명했듯이 대안이 있습니다.

그러나 실제로 다음과 같은 상황에서 유용 할 수 있습니다.

  • 원래 기능을 원하지 않거나 변경할 수 없습니다.

  • 기능을 변경할 수는 있지만

    • 사용하는 null(또는 동등한) 옵션이 아닙니다 (DiegoDD의 의견 참조 )
    • 당신은 협회와 함께 가고 싶지 않아 func_num_args()
    • 당신의 인생은 몇 LOC 저장에 달려 있습니다

성능에 대해 매우 간단한 테스트에 따르면 Reflection API를 사용하여 기본 매개 변수를 가져 오면 함수 호출이 25 배 느리지 만 여전히 1 마이크로 초 미만인 것으로 나타났습니다 . 그걸로 살 수 있는지 알아야합니다.

물론 루프에서 사용하려는 경우 미리 기본값을 가져와야합니다.


1
이것을 원하지 않는 이유는 무엇입니까? 꽤 편리해 보입니다.
Bryan

10
function image(array $img)
{
    $defaults = array(
        'src'    => 'cow.png',
        'alt'    => 'milk factory',
        'height' => 100,
        'width'  => 50
    );

    $img = array_merge($defaults, $img);
    /* ... */
}

2
뭔가 빠졌습니까? 이것은 질문에 전혀 대답하지 않는 것 같지만 7 개의 공감대가 있습니다. 약간의 설명을 추가하면 도움이 될까요?
Sean the Bean

3
@SeantheBean : true, 설명은 더 나을 것이지만, 요점은 PHP가 명명 된 인수를 가지지 않기 때문에 연관 배열을 단일 매개 변수로 사용하는 것입니다.
MestreLion

1
질문에 주어진 예를 사용하는 것이 더 도움이됩니다. 예 :$defaults = [ 'x' => 'some value', 'y' => 'some other value'];
Frank Forte

4

내가 아는 유일한 방법은 매개 변수를 생략하는 것입니다. 매개 변수를 생략하는 유일한 방법은 매개 변수 목록을 재 배열하여 생략하려는 매개 변수가 설정 해야하는 매개 변수 뒤에 오도록 하는 것입니다. 예를 들면 다음과 같습니다.

function foo($blah, $y = "some other value", $x = "some value")

그런 다음 foo를 다음과 같이 호출 할 수 있습니다.

foo("blah", "test");

결과는 다음과 같습니다.

$blah = "blah";
$y = "test";
$x = "some value";

3

나는 최근 에이 문제가 있었고이 질문과 답변을 발견했습니다. 위의 질문은 효과가 있지만 문제는 PHPStorm과 같은 기본값을 지원하는 IDE에 기본값을 표시하지 않는다는 것입니다.

여기에 이미지 설명을 입력하십시오

사용 null하면 값을 비워두면 값이 무엇인지 알 수 없습니다.

내가 선호하는 해결책은 함수 정의에 기본값을 넣는 것입니다.

protected function baseItemQuery(BoolQuery $boolQuery, $limit=1000, $sort = [], $offset = 0, $remove_dead=true)
{
    if ($limit===null) $limit =1000;
    if ($sort===null) $sort = [];
    if ($offset===null) $offset = 0;
    ...

유일한 차이점은 그들이 동일한 지 확인해야한다는 것입니다.하지만 추가 선명도를 지불하는 데는 작은 가격이라고 생각합니다.


ReflectionFunction 자체의 내부 사용으로 가격이 절약됩니다!
SubjectDelta

2

이 작업을 직접 수행 할 수는 없지만 약간의 코드를 통해 에뮬레이션 할 수 있습니다.

function foo($blah, $x = false, $y = false) {
  if (!$x) $x = "some value";
  if (!$y) $y = "some other value";

  // code
}

6
그것은 효과가 있지만, null이 경우에는 개념적으로보다 깔끔한 것을 사용 하는 것을 알았 습니다 false.
TRiG

php는 엄격하지 않은 언어이기 때문에 TriG의 의견에 추가하는 것이 false보다 위험 null합니다. !$x여러 가지 다른 입력에 대한 사실 것, 그 프로그래머를 놀라게 할 수 있습니다 0, ''. 와 함께 null사용 !isset하면보다 엄격한 테스트로 사용할 수 있습니다 .
ToolmakerSteve

1
<?php
function info($name="George",$age=18) {
echo "$name is $age years old.<br>";
}
info();     // prints default values(number of values = 2)
info("Nick");   // changes first default argument from George to Nick
info("Mark",17);    // changes both default arguments' values

?>

1

null 통합 연산자를 사용하는 2 센트 ??(PHP 7부터)

function foo($blah, $x = null, $y = null) {
    $varX = $x ?? 'Default value X';
    $varY = $y ?? 'Default value Y';
    // ...
}

repl.it 에서 더 많은 예제를 확인할 수 있습니다


0

이것은 객체가 더 나은 경우입니다 .x와 y를 유지하도록 객체를 설정하고 기본값을 설정하는 등의 작업이 가능합니다.

배열을 사용하는 접근 방식은 객체를 만드는 데 가깝습니다 (사실 객체는 객체를 통해 작동하는 매개 변수 및 함수의 무리이며 배열을 취하는 함수는 일부 ov 매개 변수를 통해 작동합니다)

분명히 null이나 이와 같은 것을 기본값으로 설정하는 트릭을 항상 할 수 있습니다


0

빈 문자열이 인수인지 확인하여 다음과 같이 호출 할 수 있습니다.

foo('blah', "", 'non-default y value', null);

기능 아래 :

function foo($blah, $x = null, $y = null, $z = null) {
    if (null === $x || "" === $x) {
        $x = "some value";
    }

    if (null === $y || "" === $y) {
        $y = "some other value";
    }

    if (null === $z || "" === $z) {
        $z = "some other value";
    }

    code here!

}

null또는 을 채우더라도 상관없이 ""동일한 결과를 얻을 수 있습니다.


0

개별 매개 변수 대신 배열을 함수에 전달하고 널 병합 연산자 (PHP 7+)를 사용하십시오.

아래에서는 2 개의 항목으로 배열을 전달합니다. 이 기능 내에서 기본 볼트가 할당되지 않은 경우 item1의 값이 설정되어 있는지 확인하고 있습니다.

$args = ['item2' => 'item2',
        'item3' => 'value3'];

    function function_name ($args) {
        isset($args['item1']) ? $args['item1'] : 'default value';
    }

$args['item1'] = $args['item1']??'default value'; PHP 7 이상에서 사용할 수 있습니다 . $ args [ 'item1']이 null이면 default value문자열은 $ args [ 'item1']에 할당됩니다
Sadee
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.