web-dev-qa-db-ja.com

PHPで型ヒントが必要なのはなぜですか?

PHPでのタイプヒントの重要性に頭を悩ませています。

PHPの 'type hinting'は次のように定義できます:

「タイプヒント」は、特定のタイプのオブジェクトのみを渡すことを強制します。これにより、互換性のない値を渡さないようにし、チームなどで作業している場合は標準を作成します。

したがって、最も基本的なレベルでヒントを入力し、実際にコードを機能させる必要はありませんか?

何が起こっているのかを試して理解するための次のコードがあります...

Index.php

<?php
include 'Song.php';

$song_object = new Song;

$song_object->title = "Beat it!";
$song_object->lyrics = "It doesn't matter who's wrong or right... just beat it!";


function sing(Song $song)
{
    echo "Singing the song called " . $song->title;
    echo "<p>" . $song->lyrics . "</p>";
}

sing($song_object);

Song.php

<?php

class Song
{
    public $title;
    public $lyrics;
}

コードは、関数sing()の小さな型ヒントの有無にかかわらず、その処理を行います。

enter image description here

したがって、これは、型ヒントが特定のクラスのみが使用され、機能コードを生成するために必要でないことを確認するための単なるコーディング規約であると私に信じさせます、これは正しいですか?

上記の引用が示唆するように、タイプヒントは、チームで作業している場合に標準を作成するためのものです

ここで何か不足していますか?

22

タイプヒントは必須ではありませんが、特定のタイプの間違いを見つけることができます。たとえば、整数を必要とする関数またはメソッドがあるとします。 PHPは 喜んで変換 "数字の文字列"を整数に変換します。これにより、デバッグ動作が困難になる可能性があります。コードで整数が特に必要であると指定した場合、多くのプログラマは、この方法でコードを保護することをベストプラクティスと見なしています。

この動作の具体例として、_index.php_ファイルの更新バージョンを見てみましょう。

index.php

_<?php
include 'Song.php';
include 'Test.php';

$song_object = new Song;
$test_object = new Test;

$song_object->title = "Beat it!";
$song_object->lyrics = "It doesn't matter who's wrong or right... just beat it!";

$test_object->title = "Test it!";
$test_object->lyrics = "It doesn't matter who's wrong or right... just test it!";


function sing(Song $song)
{
    echo "Singing the song called " . $song->title;
    echo "<p>" . $song->lyrics . "</p>";
}

sing($song_object);
sing($test_object);
_

さらに、私が追加した新しい_Test.php_ファイル:

Test.php

_<?php

class Test
{
    public $title;
    public $lyrics;
}
_

ここで_index.php_を実行すると、次のエラーが発生します。

出力:

_Singing the song called Beat it!<p>It doesn't matter who's wrong or right...
just beat it!</p>PHP Catchable fatal error:  Argument 1 passed to sing() must
be an instance of Song, instance of Test given, called in test/index.php on
line 22 and defined in test/index.php on line 15

Catchable fatal error: Argument 1 passed to sing() must be an instance of
Song, instance of Test given, called in test/index.php on line 22 and defined
in test/index.php on line 15
_

これはPHPで、sing()関数を呼び出したときに間違ったタイプのクラスを使用しようとしたことを知らせています。

27
Gavin Anderegg

タイプヒントは自然なプロセスです。最初は余分な作業のように思えるかもしれませんが、プロジェクトがPHPで成長するときに非常に役立ちます。読みやすさが向上し、エラー制御と厳密なプログラミング規則の適用が容易になります。

最初に、「コントラクト」を実装する必要があります。コントラクトは、定数と主要なパブリックメソッドとそれらの引数を「ロック」できるphpインターフェースです。

interface SongInterface {
    //...
}

class Song implements SongInterface
{
    public $title;
    public $lyrics;
    //...
}

次に、実際の実行部分を続行します。

$song = (object) new Song;

$song->title = (string) "Beat it!";
$song->lyrics = (string) "It doesn't matter who's wrong or right... just beat it!";


function sing(SongInterface $song): string
{
    $html = (string)  "Singing the song called " . $song->title
    . "<p>" . $song->lyrics . "</p>";

    return htmlentities($html, ENT_QUOTES, 'utf-8');
}

echo sing($song);

インターフェースを使用して、関数を定義し、それを曲のクラスに実装するだけです。このようにして、アプリケーションを壊すことなく、常に新しい機能と変更を加えた別の曲クラスを挿入できます。 oopインターフェースを確認してください: http://php.net/manual/en/language.oop5.interfaces.php

Php7以降、関数の戻り値の型を定義することもできます。 https://wiki.php.net/rfc/return_types

6
Nitin

コードwould型ヒントの有無にかかわらず正常に実行されます。

型ヒントは、特定の型の何かをその関数/メソッドに渡すことを強制するだけです。

例えば。

_function displayNames($names)
{
    foreach ($names as $n) {
        echo $n;
    }
}
_

この関数は、ユーザーが次のように配列を渡したと仮定すると正常に機能します。

_displayNames(array('Tom', 'John', 'Frank'));
_

ただし、PHPを使用すると、ユーザーは文字列、int、bool、オブジェクトなどの任意のものを渡すことができます。これらはどれも、foreachdisplayNames関数の内部。

arrayタイプのヒントを追加すると、この関数は_$names_が配列であることを期待するという事実が強制されます。

_function displayNames(array $names)
{
    // We now KNOW that $names is an array.
    foreach ($names as $n) {
        echo $n;
    }
}
_

配列は簡単な例ですが、先ほど述べたように、ヒントオブジェクトを入力することもできます。その場合、開発者は、たとえばdoSqlQuery()メソッドでデータベース接続のインスタンスのみを受け入れることができます。

知っておくべき

7未満のPHPバージョンでは、クラス(インターフェースを含む)と配列の型ヒントのみが許可されます。 stringintboolなどのヒントを入力するには、PHP 7.を使用する必要があります。

3
Tom Wright

必要ですか? いいえ

それはベストプラクティスですか? はい

PHPバージョンはそれをサポートしていますか?PHP 5.6クラスのみ、PHP 7+はプリミティブの型ヒントを許可します(int 、文字列、ブール値など)も同様です。

それはどのように役立ちますか?

  1. IDEによるヒントの取得(IDEによって異なります)。
  2. チームプロジェクトでのコーディングスタイルの標準化。
  3. 論理エラー の削減。
  4. PHP非可逆型言語から、ある種の強く型付けされたPHPに移行するが、開発者の手で非可逆または強力に使用するオプションを維持する。
1
evilReiko

タイプのヒントは、名前がヒントの多くを言っているようなものです。これにより、開発者は引数として渡される可能性のあるクラスを確認し、間違った引数を渡さないようにすることができます。これは、同じプロジェクトで複数の人と作業している場合や、コードがオープンソース向けである場合に特に役立ちます。

Php7では、文字列、int、(混合)、および配列のヒントが追加されているため、クラスだけでなく標準のphpタイプも使用できます。

1
Marvin Fischer
  • 特にプロジェクトが大きい場合、コードをより安定させます

  • コードはより読みやすく、よりクリーンでプロフェッショナルです

  • iDEでオートコンプリートを提供します

  • phpstanのようなコードスニファーは、間違ったパラメーターでメソッドを呼び出している場所を見つけることができます

  • 新しいプロジェクトに来たときに、コードとメソッドがどのように機能するかを簡単に理解できる

  • タイプヒントがないと、間違ったオブジェクトでメソッドを呼び出すと何も起こりません$ song-> titleおよび$ song-> lyricsはnullを返すため、タイプヒントの例外は投げられた

0
fico7489