PHP에서 엄격한 유형은 무엇입니까?


147

PHP 7에서 다음 줄을 보았지만 그 의미를 실제로 설명하는 사람은 없습니다. 나는 그것을 봤는데 그들이 이야기하는 것은 당신이 그것을 설문 조사 유형의 것을 좋아할 것인지 아닌지이다.

declare(strict_types = 1);

무엇을합니까? 코드에 어떤 영향을 미칩니 까? 내가해야합니까?

약간의 설명이 좋을 것입니다.



5
너무 이것 좀 봐 .take php.net/manual/en/... strict_types에 대한 지침
scaisEdge

답변:


153

로부터 트리 하우스 블로그 :

PHP 7에서는 스칼라 유형이 추가되었습니다. 구체적으로 : int, float, string 및 bool.

스칼라 타입 힌트를 추가하고 엄격한 요구 사항을 가능하게하면보다 정확하고 자체 문서화 된 PHP 프로그램을 작성할 수 있습니다. 또한 코드를보다 강력하게 제어 할 수 있으며 코드를보다 쉽게 ​​읽을 수 있습니다.

기본적으로 스칼라 형식 선언은 엄격하지 않으므로 형식 선언에 지정된 형식과 일치하도록 원래 형식을 변경하려고합니다. 즉, 숫자로 시작하는 문자열을 부동 소수점이 필요한 함수에 전달하면 처음부터 숫자를 가져 와서 다른 모든 것을 제거합니다. int가 필요한 함수에 float를 전달하면 int (1)이됩니다.

기본적으로 PHP는 가능한 경우 잘못된 유형의 값을 예상 스칼라 유형으로 캐스팅합니다. 예를 들어, 문자열을 기대하는 매개 변수에 정수가 제공되는 함수는 문자열 유형의 변수를 가져옵니다.

엄격한 유형 사용 안함 ( eval ) :

<?php

  function AddIntAndFloat(int $a, float $b) : int
  {
      return $a + $b;
  }

  echo AddIntAndFloat(1.4, '2');
  /*
  * without strict typing, PHP will change float(1.4) to int(1)
  * and string('2') to float(2.0) and returns int(3)
  */

파일 단위로 엄격 모드를 활성화 할 수 있습니다. 엄격 모드에서는 형식 선언의 정확한 유형의 변수 만 허용되거나 TypeError가 발생합니다. 이 규칙에 대한 유일한 예외는 부동을 기대하는 함수에 정수가 주어질 수 있다는 것입니다. 내부 함수 내에서의 함수 호출은 strict_types 선언의 영향을받지 않습니다.

엄격 모드를 사용하려면 선언문이 strict_types 선언과 함께 사용됩니다.

엄격한 유형 사용 ( eval ) :

<?php declare(strict_types=1);

  function AddIntAndFloat(int $a, float $b): int
  {
      return (string) $a + $b;
  }

  echo AddIntAndFloat(1.4,'2');
  // Fatal error: Uncaught TypeError: Argument 1 passed to AddIntAndFloat() must be of the type int, float given
  echo AddIntAndFloat(1,'2');
  // Fatal error: Uncaught TypeError: Argument 2 passed to AddIntAndFloat() must be of the type float, string given

  // Integers can be passed as float-points :
  echo AddIntAndFloat(1,1);
  // Fatal error: Uncaught TypeError: Return value of AddIntAndFloat() must be of the type integer, string returned

작업 예 :

<?php

declare(strict_types=1);

function AddFloats(float $a, float $b) : float
{
    return $a+$b;
}

$float = AddFloats(1.5,2.0); // Returns 3.5

function AddFloatsReturnInt(float $a, float $b) : int
{
    return (int) $a+$b;
}

$int = AddFloatsReturnInt($float,1.5); // Returns 5

function Say(string $message): void // As in PHP 7.2
{
    echo $message;
}

Say('Hello, World!'); // Prints "Hello, World!"

function ArrayToStdClass(array $array): stdClass
{
    return (object) $array;
}

$object = ArrayToStdClass(['name' => 'azjezz','age' => 100]); // returns an stdClass

function StdClassToArray(stdClass $object): array
{
    return (array) $object;
}

$array = StdClassToArray($object); // Returns array

function ArrayToObject(array $array): object // As of PHP 7.2
{
    return new ArrayObject($array);
}

function ObjectToArray(ArrayObject $object): array
{
    return $object->getArrayCopy();
}

var_dump( ObjectToArray( ArrayToObject( [1 => 'a' ] ) ) ); // array(1 => 'a');

3
엄격한 유형 사용 예제에 언급 된 첫 번째 치명적 오류가 잘못되었습니다. 문서에서 언급 한 바와 같이 : "이 규칙의 유일한 예외는 float를 기대하는 함수에 정수가 주어질 수 있다는 것입니다." int에서 함수 호출이 실패하지 않습니다. 그래도 문자열에 있습니다.
Paul

63

strict_types 유형 강제에 영향을 미칩니다.

형식 힌트를 사용하지 않으면 strict_types미묘한 버그가 발생할 수 있습니다.

엄격한 타입 이전에 int $x" int에 대해 강제적 인$x 값을 가져야한다 " 는 의미 에 강제 될 수있는 모든 값은 다음을 포함하여 유형 힌트를 전달합니다.int

  • int 적절한 ( 242),
  • 플로트 ( 10.17)
  • 부울 ( true),
  • null또는
  • 선행 숫자가있는 문자열 ( "13 Ghosts")

을 설정 strict_types=1하면 엔진에 int $x"$ x는 적절한 유형이어야하며 유형 강제 변환은 허용되지 않아야합니다."를 의미합니다. 전환과 잠재적 손실없이 정확히 제공된 것만 얻을 수 있다는 확신이 있습니다.

예:

<?php
function get_quantity(): int {
    return '100 apples';
}
echo get_quantity() . PHP_EOL;

잠재적으로 혼란스러운 결과를 얻습니다.

Notice: A non well formed numeric value encountered in /Users/bishop/tmp/pmkr-994/junk.php on line 4
100

대부분의 개발자들은 int"int"만을 의미 하는 힌트를 기대할 것 입니다. 그러나 그것은 "int와 같은 것"을 의미하지는 않습니다. strict_types를 활성화하면 예상되고 바람직한 동작이 나타납니다.

<?php declare(strict_types=1);

function get_quantity(): int {
    return '100 apples';
}
echo get_quantity() . PHP_EOL;

수율 :

Fatal error: Uncaught TypeError: Return value of get_quantity() must be of the type int, string returned in example.php:4

유형 힌트를 사용하는 경우 여기에 두 가지 교훈이 있다고 생각합니다.

  • strict_types=1항상 사용하십시오 .
  • strict_typespragma 추가를 잊어 버린 경우 통지를 예외로 변환하십시오 .

1
이것은 거의 1 년 전에 이미 이미 잘 답변되었습니다;)
emix

6
실제로 다른 답변 @emix를 투표했습니다. 그러나 나는 "해야한다"라는 질문에 대해서는 언급하지 않았다. 나는 또한 더 작고 충격적인 예가 사람들의 사용을 장려 할 것이라고 생각했다 strict_types.
감독

1
이 질문은 간결하게 "해야합니까?" OP의 질문의 일부. 약간의 어려움을 겪은 후 PHP로 돌아 가면 매우 도움이되었습니다.
Darragh Enright
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.