[php] 함수에서 기본 인수 사용

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");   

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



답변

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

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를 지정하지 않고 함수에서 $ 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'));


답변

실제로 가능합니다 :

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

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


최신 정보:

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

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

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

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

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

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

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

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


답변

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

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


답변

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

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

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

foo("blah", "test");

결과는 다음과 같습니다.

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


답변

나는 최근 에이 문제가 있었고이 질문과 답변을 발견했습니다. 위의 질문은 효과가 있지만 문제는 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;
    ...

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


답변

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

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

  // code
}