Heim > Artikel > Backend-Entwicklung > Tipps zum PHP7-Typ: Was Sie als PHP-Entwickler immer beachten sollten
Empfohlenes Tutorial: „PHP7“
Dieser Artikel wurde von http://web-techno.net/typing-with-php-7-what-you-shouldnt-do/ übersetzt , gehen Sie bitte zum Originaltext.
Als Strong Typing in PHP7 auftauchte, erblickte ich das Licht. Endlich bin ich zuversichtlich, dass ich aufgrund der schwachen Typisierung von PHP keine Fehler oder Inkonsistenzen mehr sehen werde.
Ich erinnere mich, dass ich Code gelesen habe und keine Ahnung hatte, welchen Typ die darin enthaltenen Variablen haben sollten. Sollte ich den Typ „int“ als Rückgabewert für diese Methode verwenden? Boolen-Typ? Wird dies zu versteckten Fehlern oder unvorhergesehenem Verhalten führen?
Strenge Typisierung ist nützlich, ebenso wie Hinweise auf Rückgabewerttypen. Sie wissen genau, mit welchen Daten Sie es zu tun haben. Sie müssen nicht mehr raten.
Allerdings ist PHP7 nicht das Ende meiner Bemühungen in diesem Artikel. Sie können immer noch verschleierten Code schreiben, auch wenn PHP7 hart daran arbeitet, dieses Problem zu beheben. Es gibt einige Regeln, die Sie befolgen müssen, um Ihren Code organisiert zu halten.
Ich werde den Befehlszeilenmodus von PHP7.1.1-dev verwenden, um jedes Beispiel in diesem Artikel auszuführen.
PHP7 führt zwei geeignete Typen ein: Skalartypen und Rückgabewerttypen. Ich werde ihre Unterschiede und ihre Verwendung hier nicht erklären. PHP-Kommentare werden besser abschneiden als ich:
*https://wiki.php.net/rfc/scalar_type_hints_v5
*https://wiki.php.net/rfc/return_types
Seien wir ehrlich: PHP7-Programmierung kann zu unvorhersehbaren Ergebnissen führen.
Bezweifeln Sie das? Hier sind einige Beispiele:
function mySuperFunction(): int{ return "hello world"; } mySuperFunction();
Dieser Code ist in Ordnung. Die Typdeklaration gibt an, dass diese Methode den Typ int zurückgeben soll. Es wird jedoch der String-Typ zurückgegeben. Unnötig zu erwähnen, dass PHP einen Fehler auslöst:
Schwerwiegender Fehler: Uncaught TypeError: Rückgabewert von mySuperFunction() muss vom Typ Ganzzahl sein, zurückgegebener String. Schwerwiegender Fehler: Nicht erfasster Typfehler: Der Rückgabetyp der Funktion mySuper muss vom Typ int sein, es wurde eine Zeichenfolge zurückgegeben.
Schauen wir uns ein anderes Beispiel an:
function mySuperFunction():int{ return "hello world1"; } mySuperFunction();
Gleiches Ergebnis wie oben: Tippfehler. Gut! Stimmt etwas mit dem Rückgabetyp nicht? Habe ich dich angelogen?
function mySuperFunction():int{ return "1hello world"; } mySuperFunction();
Sollte das nicht eine Ausnahme auslösen? Wir haben den Rückgabetyp eindeutig als int definiert, aber was zurückgegeben wird, ist ein String.
Der Übersetzungsautor fügt hinzu: PHP7.2.4 gibt einen Hinweisfehler aus:
Hinweis: Es wurde ein nicht wohlgeformter numerischer Wert festgestellt Es ist ein falsch formatierter Zahlentypwert aufgetreten
Fehler. Die Funktion gibt 1 zurück.
function mySuperFunction():int{ return 1.1456415; } mySuperFunction();
definiert den Rückgabetyp int. Offensichtlich ist der tatsächliche Rückgabetyp float. Dieser Code löst jedoch keine Ausnahme aus.
Es ergibt 1.
Immer noch nicht überzeugt?
function mySuperFunction():bool{ return "1hello world"; } mySuperFunction();
PHP behandelt „1hello world“ als booleschen Typ und gibt 1 zurück.
function mySuperFunction():bool{ return "abcde"; } mySuperFunction();
In der seltsamen Welt von PHP ist „abcde“ ein boolescher Wert. Tatsächlich wird diese Methode „true“ zurückgeben!
Wie Sie sehen, verwirren Sie diese Codierungsregeln immer noch. Kurz gesagt: Selbst wenn der Code klar ist, ist er möglicherweise nicht wahr!
PHP verwendet schwache Typisierung.
Ich will nicht.
Tatsächlich konvertiert PHP den String-Typ zur Laufzeit stillschweigend in den Boolean-Typ und in den Int-Typ. Ich bringe einfach deinen Code durcheinander! Etwas, das einfach und klar sein sollte, ist durcheinander.
Lassen Sie es uns klarstellen. Wir sind Entwickler. Daher sollten wir die Art der Daten im Code kontrollieren.
Wenn wir dies nicht tun, öffnen wir Tür und Tor für Fehler und verbreiten seltsames Verhalten und Missverständnisse unter den Entwicklern. Der Code wird sich ändern. Käfer werden auftauchen, Ihr Chef wird Sie feuern, Ihre Frau wird von Ihnen enttäuscht sein und Sie werden in den Abgrund fallen. Traurig und einsam in Selbstvorwürfen.
Es gibt noch eine Chance auf Wiedergutmachung! Alles ist möglich. PHP hat eine Lösung!
Achten Sie auf den strikten Typmodus:
declare(strict_types=1);function mySuperFunction(): bool{ return 'abcde'; }echo mySuperFunction();
Führen Sie diesen Code aus und Sie erhalten einen schwerwiegenden Fehler:
Schwerwiegender Fehler: Uncaught TypeError: Rückgabewert von mySuperFunction() muss vom Typ boolean sein, zurückgegebener String!
Uncaught TypeError: Der Rückgabewert von mySuperFunction() muss vom Typ boolean sein, es wurde ein String zurückgegeben!
Ich habe mich sehr gefreut, als dieser Fehler auf dem Bildschirm auftauchte. Normalerweise macht es keinen Spaß, auf Fehler zu stoßen, aber dieses Mal war es in Ordnung. Natürlich ist es ein String-Typ und kein boolescher Typ!
Mein Vorschlag ist: Fügen Sie diese strenge Typdeklaration in jeden Code ein. Überall! Erstellen Sie ein Code-Snippet für Ihre IDE. Jedes Mal, wenn Sie eine PHP-Datei erstellen, sollten Sie die strikte Typdeklaration ganz oben platzieren.
Leider können Sie den strikten Modus nicht global festlegen. Sie müssen dies in jeder PHP-Datei tun. Der Grund ist einfach: Jedes Paket oder jede andere Art von Ressource in Ihrer Anwendung, auch wenn der stark typisierte Modus nicht implementiert werden muss.
Ich weiß, dass einige Leute anderer Meinung sein werden. Ich weiß, dass einige Leute bereit sind, die Codekonsistenz einfach aus Gründen der möglichen „Flexibilität“ zu zerstören.
Ich kenne das Argument: „Es ist leicht zu argumentieren, dass boolesche Typen als String-Typen dargestellt werden müssen.“
我会回复他们:修复你的结构和/或你的实现。如果代码是弱类型,就会有一些问题。如果你确实需要,请修复真实存在的问题,不用再徘徊于把布尔值作为一个字符串或者int类型。
你是开发者。你不是黑客。你要解决问题,而不是与问题为伍。
五个字概括:强类型骄傲!PHP7是强类型类型语言了!
PHP7.1中Nullable类型 请小心nullable类型的笑里藏刀!它是猛兽!
nullabla类型详见PHP意见征求稿
你怎么会用错?
declare(strict_types=1);class User{ //Value object}class UserRepository{ private $database; public function construct(Database $database){ $this->database = $database; } public function getUserById(int $id):?User { //If user is not in the database, return null $user = $this->database->fetchUser($id); return $user; } }class EmailSender{ public function sendEmailToUser(int $userId) { $userRepository = new UserRepository(new Database()); $user = $userRepository->getUserById($userId); //Can send email to... null! $this->sendEmail($user); } } $emailSender = new EmailSender(); $emailSender->sendEmailToUser(12345);
这段代码将会崩溃,因为我们试图获取数据库中不存在的User模型。我们怎么能给null发邮件?
很明显你应该用如下方法修正:
...class EmailSender{ public function sendEmailToUser($userId) { $userRepository = new UserRepository(new Database()); $user = $userRepository->getUserById($userId); if ($user !== null) { $this->sendEmail($user); } } }
但是这个方法有两个问题:
对nullable的处理将导致判断是否为null的判断到处都是(if ($methodReturn !== null))。无用且聒噪。
如果用户不存在以上代码将会静静地失败。「为什么用户没收到邮件?」将会是你的噩梦。你需要明白:
用户模型不存在(可能是一个错误的用户id被传入了getUserByid())
用户模型为null,可能因为nullable类型
加上null的条件判断,导致应用什么都没做
这是另一种方式:
...class UserRepository{ private $database; public function construct($database){ $this->database = $database; } public function getUserById($id):User { $user = $this->database->fetchUser($id); //If user is not in the database, an error will be thrown! return $user; } } ...
在这个例子中没必要使用nullalble类型。代码将会抛出一个异常。如果User模型不存在,应用的执行将会终止。
那时你仅需要去处理这个错误。简单、清晰、高效,毋庸置疑。
nullable类型有一些其他的意外。
declare(strict_types=1);interface MySuperInterface{ public function superFunction():?int; }class SuperClass implements mySuperInterface{ public function superFunction():int { return 42; } } $superClass = new SuperClass();echo $superClass->superFunction();
Super类实现了接口MySubper,但不会实现接口约定。接口要求返回nullable的类型,实际将返回int类型。
然而,这段代码在PHP7.1中不会抛出错误。
等等。。。我们需要如接口中表示的那样无论如何都要返回null?
让我们尝试一下:
declare(strict_types=1);interface MySuperInterface{ public function superFunction():?int; }class SuperClass implements mySuperInterface{ public function superFunction():int { return null; } } $superClass = new SuperClass();echo $superClass->superFunction();
结果如下:
Fatal error: Uncaught TypeError: Return value of SuperClass::superFunction() must be of the type integer, null returned 致命错误:未捕获的类型错误:Super类的super方法的返回值必须得是int类型,返回了null
现在我应该理解了在某场景下很有用,比如不能在数据库中存null值时。
我强烈建议你谨慎使用。我很少在代码中使用这个类型,因为我通常有更好的解决办法。
我更喜欢在大多场景下使用null对象代替null。为什么?简而言之,因为我讨厌在任何时候检测变量是否为null!
我喜欢PHP。尤其当它引入了强类型。可能还不完美,但是将会越来越好。
不过当你在PHP中操作类型时,一定要多加小心。我还是要强调:
需要使用严格类型。
需要控制应用中数据。
如果仍使用弱类型,将会是个问题。因此:修复它!
不应该猜测变量的类型到底是什么。
尽可能避免使用nullable类型
为了每个使用我们的代码的开发人员,我们需要保持一致性。对我来说,意味着很专业。
很明显在留言中阅读你们的建议使我很开心。
参考:
http://web-techno.net/typing-with-php-7-what-you-shouldnt-do/
Das obige ist der detaillierte Inhalt vonTipps zum PHP7-Typ: Was Sie als PHP-Entwickler immer beachten sollten. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!