为什么在PHP中需要类型提示?

时间:2016-07-11 14:04:27

标签: php oop type-hinting

我无法解决PHP中类型提示的重要性。

显然,PHP中的“类型提示”可以定义如下:

  

“类型提示”强制您仅传递特定类型的对象。   这可以防止您传递不兼容的值,并创建一个   如果您正在与团队合作等标准。

因此,在最基本的级别上进行类型提示,不需要实际使代码有效吗?

我有以下代码试图了解发生了什么......

的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

因此,这让我相信类型提示只是一种编码约定,以确保只使用某些类而不需要生成功能代码,这是正确的吗?

如上所述,类型提示可以创建标准,如果您正在与团队合作

我在这里错过了什么吗?

5 个答案:

答案 0 :(得分:22)

类型提示不是必需的,但它可以让您捕获某些类型的错误。例如,您可能有一个需要整数的函数或方法。 PHP将happily convert&#34;数字看字符串&#34;整数,这可能导致难以调试的行为。如果在代码中指定特别需要一个整数,则可以首先防止出现这类错误。许多程序员都认为以这种方式保护他们的代码是最佳实践。

作为此操作的具体示例,让我们查看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()函数时尝试使用错误类型的类。

答案 1 :(得分:5)

类型提示是一个自然过程。起初看起来似乎是额外的工作,但随着您的项目在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

答案 2 :(得分:3)

您的代码 可以使用或不使用类型提示运行。

类型提示只会强制您将特定类型的内容传递给该函数/方法。

E.g。

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

假设用户按如下方式传入数组,此函数可以正常工作。

displayNames(array('Tom', 'John', 'Frank'));

然而,PHP将允许用户传递任何内容,例如字符串,int,bool,对象等。当它到达foreach displayNames内部时,这些都不会表现出您的预期。 1}}功能。

添加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 :(得分:1)

类型提示就像名称更多的提示。它允许开发人员查看哪些类可以作为参数传递,并防止它们传递错误的参数。如果你不仅仅是一个人在同一个项目上工作和/或代码是用于开源的话,那就特别有帮助。

在php7类型提示中添加了字符串,int,(mixed)和数组,所以你不需要只有类,但也可以使用标准的php类型

答案 4 :(得分:0)

  • 使您的代码更稳定,尤其是在项目较大的情况下

  • 该代码更具可读性,更简洁,更专业

  • 让您在IDE中自动完成

  • 像phpstan这样的
  • 代码嗅探器可以在调用方法的地方找到 参数错误

  • 您可以更轻松地理解代码以及进入新项目时方法的工作方式

  • 没有类型提示,如果您将使用错误的对象调用方法,则不会发生任何事情,因为 $ song-> title $ song-> lyrics 将返回null ,并抛出类型提示异常