유형 힌트를 사용할 때 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.