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

Jet*_*rst 22 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);
Run Code Online (Sandbox Code Playgroud)

Song.php

<?php

class Song
{
    public $title;
    public $lyrics;
}
Run Code Online (Sandbox Code Playgroud)

代码在函数sing()中使用或不使用小类型提示来执行其操作;

在此输入图像描述

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

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

我在这里错过了什么吗?

Gav*_*egg 25

类型提示不是必需的,但它可以让您捕获某些类型的错误.例如,您可能有一个需要整数的函数或方法.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);
Run Code Online (Sandbox Code Playgroud)

除了Test.php我添加的新文件:

test.php的

<?php

class Test
{
    public $title;
    public $lyrics;
}
Run Code Online (Sandbox Code Playgroud)

当我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
Run Code Online (Sandbox Code Playgroud)

这是PHP让我知道我在调用sing()函数时尝试使用错误类型的类.

  • @HappyDog恰恰相反,这是一个很好的例子,特别是*因为*该示例**当前**有效。`sing()` 函数旨在与 `Song` 一起使用,而不是与它共享功能的其他任何东西。在某个时候更改“Test”类是完全合理的,因为它只是一个测试,但突然代码会在完全不同的地方(“sing()”函数)中断。类型提示通过在实际错误发生的地方抛出错误来防止这种情况:错误的东西被传递给 `sing()` 并且仅在巧合下起作用。 (2认同)

Tom*_*ght 6

无论有没有类型提示,您的代码都可以正常运行。

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

例如

function displayNames($names)
{
    foreach ($names as $n) {
        echo $n;
    }
}
Run Code Online (Sandbox Code Playgroud)

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

displayNames(array('Tom', 'John', 'Frank'));
Run Code Online (Sandbox Code Playgroud)

然而,PHP 允许用户传递任何内容,例如字符串、整数、布尔值、对象等。当它们到达foreach函数内部时,它们都不会按照您期望的方式运行displayNames

添加类型提示强制执行此函数期望为数组的array事实。$names

function displayNames(array $names)
{
    // We now KNOW that $names is an array.
    foreach ($names as $n) {
        echo $n;
    }
}
Run Code Online (Sandbox Code Playgroud)

数组是一个简单的示例,但正如您所说,您也可以输入提示对象。doSqlQuery()在这种情况下,它允许开发人员仅在方法中接受数据库连接的实例。

你应该知道

PHP 7 以下版本仅允许类(包括接口)和数组的类型提示。为了输入stringintbool等的提示,您需要使用 PHP 7。


Nit*_*tin 6

提示类型是一个自然过程.起初看起来似乎是额外的工作,但随着您的项目在PHP中的增长,它非常有用.它允许更好的可读性,并使错误控制和严格的编程约定更容易应用.

最初,你必须实现'契约',其中契约是一个php接口,可以"锁定"常量和关键公共方法及其参数,如下所示:

interface SongInterface {
    //...
}

class Song implements SongInterface
{
    public $title;
    public $lyrics;
    //...
}
Run Code Online (Sandbox Code Playgroud)

然后继续实际执行部分:

$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);
Run Code Online (Sandbox Code Playgroud)

使用界面,您只需定义函数,然后在歌曲类中实现它.这样您就可以在不破坏应用程序的情况下始终注入另一个歌曲类(具有更新的功能和更改).查看oop接口:http://php.net/manual/en/language.oop5.interfaces.php

从php7开始,您还可以定义函数的返回类型.https://wiki.php.net/rfc/return_types