right O que os tipos estritos fazem no PHP?



php psr portugues (2)

Do blog de Treehouse :

Com o PHP 7, agora adicionamos tipos escalares. Especificamente: int, float, string e bool.

Adicionando sugestões de tipo escalar e permitindo requisitos estritos, espera-se que programas PHP mais corretos e auto-documentados possam ser escritos. Também lhe dá mais controle sobre seu código e pode tornar o código mais fácil de ler.

Por padrão, as declarações de tipo escalar não são estritas, o que significa que tentarão alterar o tipo original para corresponder ao tipo especificado pela declaração de tipo. Em outras palavras, se você passar uma string que comece com um número em uma função que exija um float, ele irá capturar o número desde o início e remover todo o resto. Passar um float em uma função que requer um int se tornará int (1).

Por padrão, o PHP irá lançar valores do tipo errado para o tipo escalar esperado, se possível. Por exemplo, uma função que recebe um inteiro para um parâmetro que espera uma string obterá uma variável do tipo string.

Tipos restritos desativados ( 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)
  */

É possível ativar o modo estrito em uma base por arquivo. No modo estrito, somente uma variável do tipo exato da declaração de tipo será aceita, ou um TypeError será lançado. A única exceção a essa regra é que um inteiro pode ser dado a uma função esperando um float. Chamadas de função de dentro de funções internas não serão afetadas pela declaração strict_types.

Para ativar o modo estrito, a declaração declare é usada com a declaração strict_types:

Tipos restritos habilitados ( 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

exemplo de trabalho:

<?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 on 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');

https://src-bin.com

Eu vi essa nova linha no PHP7, mas ninguém realmente explica o que isso significa. Eu pesquisei e tudo o que eles falam é que você estará habilitando ou não como um tipo de pesquisa.

declare(strict_types = 1);

O que isso faz? Como isso afeta meu código? Eu devo fazer isso? Alguma explicação seria legal.


Answer #1

strict_types afeta a coerção de tipo .

Antes de tipos estritos, int $x significava que " $x deve ter um valor semelhante a um int, mas não necessariamente um int apropriado". Qualquer coisa que pudesse ser coagida a um int seria o tipo de dica, incluindo:

  • um int apropriado ( 242 ),
  • um flutuador ( 10.17 ),
  • um bool ( 1 )
  • null ou
  • uma string com dígitos iniciais ( 13 Ghosts ).

Agora, definindo strict_types=1 , você diz ao mecanismo que int deve significar "exatamente e somente um int apropriado". Nada mais. Você tem uma grande e grande garantia de que você está recebendo exatamente e apenas o que foi dado, sem qualquer conversão e perda potencial.

Exemplo:

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

Produz um resultado potencialmente confuso:

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

A maioria dos desenvolvedores espera, na minha opinião, uma dica int para significar "apenas um int". Mas isso não significa "algo parecido com um int". Ativar tipos estritos fornece o provável comportamento esperado e desejado:

<?php declare(strict_types=1);

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

Rendimentos:

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

Eu acho que há duas lições aqui, se você usar dicas de tipo:

  • Use strict_types=1 , sempre.
  • Converta avisos em exceções, caso você esqueça de adicionar o pragma strict_types .




php-7.2