함수에서 기본 인수 사용


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.