strict型は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)
  */

ファイルごとに厳格モードを有効にすることができます。strictモードでは、型宣言の正確な型の変数のみが受け入れられるか、TypeErrorがスローされます。この規則の唯一の例外は、浮動小数点数を期待する関数に整数を与えることができることです。内部関数内からの関数呼び出しは、strict_types宣言の影響を受けません。

strictモードを有効にするには、strict_types宣言とともにdeclareステートメントを使用します。

有効な厳格なタイプ(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
厳密な型を有効にした例で言及されている最初の致命的なエラーは間違っています。ドキュメントで述べられているように:「このルールの唯一の例外は、整数が浮動小数点数を期待する関数に与えられるかもしれないということです。」関数呼び出しはintで失敗しません。それはひもであるでしょう。
ポール・

63

strict_types 型強制に影響します。

なしで型ヒントを使用strict_typesすると、微妙なバグが発生する可能性があります。

厳密な型の前は、「intに強制可能な値が必要int $x」を意味し$xていました。に強制される可能性のある任意の値は、タイプヒントを渡します。int

  • intプロパティ(242)、
  • フロート(10.17)、
  • ブール(true)、
  • null、または
  • 先頭の数字("13 Ghosts")を含む文字列。

を設定strict_types=1することで、エンジンにint $x「$ xはintプロパティのみであり、型強制は許可されない」ことを意味します。変換や潜在的な損失なしに、与えられたものだけを正確に得ることができます。

例:

<?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

タイプヒントを使用する場合、ここには2つのレッスンがあると思います。

  • strict_types=1常に使用します。
  • strict_typesプラグマの追加を忘れた場合に備えて、通知を例外に変換します。

1
これは、ほぼ1年前のように既に十分に回答されています;)
emix

6
確かに、私は他の回答@emixに賛成票を投じました。しかし、「やらなければならない」という疑問には触れなかった。また、よりコンパクトで衝撃的な例が人々に使用を奨励すると感じましたstrict_types
ビショップ

1
この質問は、「やるべきこと」を簡潔に扱っていると思います。OPの質問の一部。少し休止してからPHPに戻ると、非常に役に立ちました。
Darragh Enright
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.