유형 힌트를 사용할 때 null 인수를 전달할 수 없습니다


193

다음 코드 :

<?php

    class Type {

    }

    function foo(Type $t) {

    }

    foo(null);

?>

런타임에 실패했습니다.

PHP Fatal error:  Argument 1 passed to foo() must not be null

다른 언어처럼 null을 전달할 수없는 이유는 무엇입니까?

답변:


357

PHP 7.1 이상 (2016 년 12 월 2 일 릴리스)

null이 구문 을 사용하도록 변수를 명시 적으로 선언 할 수 있습니다

function foo(?Type $t) {
}

이 결과

$this->foo(new Type()); // ok
$this->foo(null); // ok
$this->foo(); // error

따라서 선택적 인수를 원할 경우 규칙을 따를 수 있습니다 Type $t = null 있지만 인수 null와 유형을 모두 허용하도록 하려면 위의 예를 따르십시오.

자세한 내용은 여기를 참조 하십시오 .


PHP 7.0 이상

당신은 같은 기본값을 추가해야합니다

function foo(Type $t = null) {

}

그렇게하면 null 값을 전달할 수 있습니다.

이것은 유형 선언 에 대한 매뉴얼 섹션에 설명되어 있습니다 .

NULL매개 변수의 기본값이로 설정된 경우 값 을 승인하도록 선언 할 수 있습니다 NULL.


10
그렇다면 왜 null 객체null 객체가 아닌가?
Pacerier

4
대부분의 언어는 null이 모든 유형을 갖도록 허용합니다. 이 시나리오에서.
Henry

24
제 생각에는 이것은 언어 구성이 좋지 않습니다. 1. 다른 언어에서는 null이 모든 유형일 수 있으므로이 경우 null이 유효한 인수가됩니다. 2 : Php는 널에 허용되는 것으로 지정하기 위해 인수에 기본값을 사용하고 있습니다. 이는 모호하며 개발자가 널을 명시 적으로 전달하도록 강제하더라도 필수 매개 변수는 불가능합니다.
Henry

2
나는 @Henry에 동의하며, 선택적 매개 변수처럼 보이는 매개 변수를 필요로하는 것이 이상하게 보입니다.
Force Hero

6
나는 2에 ​​대해서만 @Henry에 동의합니다. 1에 관해서 function foo(Type $t)는 null을 전달할 수 없다는 사실 은 매우 좋습니다. 참조 널 참조를 : 억 달러 실수를
콘스탄틴 Galbenu을

36

PHP 7.1부터는 함수 반환 형식과 매개 변수로 nullable 형식 을 사용할 수 있습니다. 형식 ?T은 지정된 Type T또는의 값을 가질 수 있습니다 null.

따라서 함수는 다음과 같습니다.

function foo(?Type $t)
{

}

PHP 7.1로 작업 할 수있게 되 자마자이 표기법이 function foo(Type $t = null) 호출자가 매개 변수에 대한 인수를 명시 적으로 지정하도록 강제하기 때문에이$t .


12

시험:

function foo(Type $t = null) {

}

PHP 함수 인수를 확인하십시오 .


11
내가 가진 문제는 함수의 정의가 변경된다는 것입니다. 이제 매개 변수는 선택 사항입니다. 실제로 저자가 의도 한 것이 아닙니다 (널을 전달하는 경우 암시 적으로 선택 사항 임).
호감

7

다른 답변에서 이미 언급했듯이 null기본값으로 지정 하는 경우에만 가능 합니다.

그러나 가장 안전한 유형 안전 객체 지향 솔루션은 NullObject입니다 .

interface FooInterface
{
    function bar();
}
class Foo implements FooInterface
{
    public function bar()
    {
        return 'i am an object';
    }
}
class NullFoo implements FooInterface
{
    public function bar()
    {
        return 'i am null (but you still can use my interface)';
    }
}

용법:

function bar_my_foo(FooInterface $foo)
{
    if ($foo instanceof NullFoo) {
        // special handling of null values may go here
    }
    echo $foo->bar();
}

bar_my_foo(new NullFoo);

1
이 접근 방식은 종종 1 클래스 대신 3이 필요하기 때문에 비실용적입니다. 또한이 NullFoo방법을 사용하면 (의 정의에 따라 null) 의미가없는 추상 메소드를 대체 할 수 있습니다 .
TheOperator

1
내 경험상 NullObject 패턴은 일반적으로 매우 엄격한 클래식 OO 방식으로 작업하는 경우 실용적 일 수 있습니다. 답에 따르면 NullObject 패턴은 if (something is null)존재하지 않는 값의 모든 동작을 다루기 때문에 외부의 공동 작업자가 오브젝트가 존재하지 않거나 (널) 존재하지 않습니다.
잃었다
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.