PHP7 タイプのヒント: PHP 開発者として常に覚えておくべきこと
推奨チュートリアル: "PHP7"
この記事は http://web-techno.net/typing-with-php-7-what-you から翻訳されたものです- shouldnt -do/ 、英語が得意な方は原文へどうぞ。
PHP7 に強い型付けが登場したとき、私は光を見ました。ようやく、PHP の弱い型付けによるバグや不一致はもう発生しないと確信できました。
あるコードを読んだことを覚えていますが、そこに含まれる変数の型についてはまったくわかりませんでした。このメソッドの戻り値は int 型を使用する必要がありますか?ブール型?これにより、隠れたバグや予期せぬ動作が発生するのでしょうか?
厳密な型付けは、戻り値の型のヒントと同様に便利です。どのようなデータを扱っているかを正確に把握できます。もう推測する必要はありません。
ただし、この記事での私の取り組みは PHP7 で終わりではありません。 PHP7 はこの問題を解決するために懸命に取り組んでいますが、難読化されたコードを記述することは可能です。コードを整理しておくために従う必要のあるルールがいくつかあります。
この記事の各例を実行するには、PHP7.1.1-dev のコマンド ライン モードを使用します。
PHP 型宣言
PHP7 では、スカラー型と戻り値型という 2 つの適切な型が導入されています。ここでは、それらの違いと使用方法については説明しません。 PHP コメントドラフトは私よりもうまくやるでしょう:
*https://wiki.php.net/rfc/scalar_type_hints_v5
*https://wiki.php.net/rfc /return_types
PHP7 は強い型付けを備えています...それともそれは奇妙ですか?
率直に言いましょう。PHP7 プログラミングでは、予期しない結果が生じる可能性があります。
これを疑いますか?以下にいくつかの例を示します。
function mySuperFunction(): int{ return "hello world"; } mySuperFunction();
このコードは問題ありません。型宣言は、このメソッドが int 型を返す必要があることを示しています。ただし、文字列型を返します。言うまでもなく、PHP はエラーをスローします:
致命的エラー: Uncaught TypeError: mySuperFunction() の戻り値は整数型、返される文字列である必要があります。 致命的なエラー: キャッチされない型エラー: mySuper 関数の戻り値の型は int 型である必要があります。文字列が返されました。
別の例を見てみましょう:
function mySuperFunction():int{ return "hello world1"; } mySuperFunction();
上と同じ結果: タイプ エラー。良い!戻り値の型が間違っているのでしょうか?私はあなたに嘘をつきましたか?
function mySuperFunction():int{ return "1hello world"; } mySuperFunction();
これは例外をスローすべきではないでしょうか?戻り値の型を int として明確に定義しましたが、返されるのは文字列です。
翻訳著者の補足: PHP7.2.4 は通知エラーをスローします:
通知: 整形式でない数値が見つかりました 不適切な形式の数値型値
エラーが発生しました。この関数は 1 を返します。
function mySuperFunction():int{ return 1.1456415; } mySuperFunction();
戻り値の int 型を定義します。明らかに、実際の戻り値の型は float です。しかし、このコードは例外をスローしません。
1 が返されます。
まだ納得できない場合は、
function mySuperFunction():bool{ return "1hello world"; } mySuperFunction();
PHP は '1hello world' をブール型として扱い、1 を返します。
function mySuperFunction():bool{ return "abcde"; } mySuperFunction();
PHP の奇妙な世界では、「abcde」はブール値です。実際、このメソッドは true を返します!
ご覧のとおり、これらのコーディング ルールは依然として混乱を引き起こします。つまり、コードが明確であっても、それが真実ではない可能性があります。
PHP の厳密な型付け
PHP は弱い型付けに慣れています。 ######したくないです。
実際、PHP は実行時に文字列型を Boolean 型と int 型に自動的に変換します。コードをめちゃくちゃにするだけです!シンプルで明確であるべきものがめちゃくちゃになっています。
はっきりさせておきましょう。私たちは開発者です。したがって、コード内のデータの種類を制御する必要があります。
そうしないと、バグへの扉が開かれ、開発者の間に奇妙な動作や誤解が広まることになります。コードが変わります。虫が現れ、上司は解雇され、妻はあなたに失望し、あなたは奈落の底に落ちるでしょう。自分を責めて悲しくて寂しい。
まだ救済のチャンスはあります!すべてのことが可能です。 PHP には解決策があります。
厳密な型モードに注意してください:
declare(strict_types=1);function mySuperFunction(): bool{ return 'abcde'; }echo mySuperFunction();
このコードを実行すると、致命的なエラーが発生します:
致命的なエラー: Uncaught TypeError: mySuperFunction() の戻り値ブール型である必要があります。文字列が返されます!キャッチされない型エラー: mySuperFunction() の戻り値はブール型である必要があり、文字列が返されます!
このエラーが画面にポップアップ表示されるのを見て、とてもうれしく思いました。通常、エラーが発生するのは好ましくありませんが、今回は問題ありませんでした。もちろん、ブール型ではなく文字列型です。
私の提案は、この厳密な型宣言をコードのすべての部分に入れることです。どこでも! IDE のコード スニペットを作成します。 PHP ファイルを作成するたびに、先頭に厳密な型宣言を置く必要があります。
残念ながら、厳密モードをグローバルに設定することはできません。すべての PHP ファイルでこれを行う必要があります。理由は簡単です。たとえ厳密に型指定されたモードを実装する必要がない場合でも、アプリケーション内のあらゆるパッケージや他の種類のリソースが対象となるからです。
同意しない人もいると思います。 「柔軟性」を実現するために、コードの一貫性を破壊しようとする人がいるのは承知しています。
「ブール型は文字列型として表現する必要があると主張するのは簡単です。」という議論はわかります。
我会回复他们:修复你的结构和/或你的实现。如果代码是弱类型,就会有一些问题。如果你确实需要,请修复真实存在的问题,不用再徘徊于把布尔值作为一个字符串或者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模型不存在,应用的执行将会终止。
那时你仅需要去处理这个错误。简单、清晰、高效,毋庸置疑。
PHP中nullable类型和接口
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/
以上がPHP7 タイプのヒント: PHP 開発者として常に覚えておくべきことの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









php7.0 に mongo 拡張機能をインストールする方法: 1. mongodb ユーザー グループとユーザーを作成します; 2. mongodb ソース コード パッケージをダウンロードし、ソース コード パッケージを "/usr/local/src/" ディレクトリに配置します; 3. 「src/」ディレクトリに入ります; 4. ソースコードパッケージを解凍します; 5. mongodb ファイルディレクトリを作成します; 6. ファイルを「mongodb/」ディレクトリにコピーします; 7. mongodb 設定ファイルを作成して設定を変更します。

php5 では、fsockopen() 関数を使用して TCP ポートを検出できます。この機能を使用して、ネットワーク接続を開き、ネットワーク通信を実行できます。ただし、php7 では、fsockopen() 関数でポートを開けない、サーバーに接続できないなどの問題が発生する可能性があります。この問題を解決するには、socket_create() 関数とsocket_connect() 関数を使用して TCP ポートを検出します。

PHP 7.0 でインストールされているプラグインが表示されない問題を解決するには: プラグインの設定を確認し、プラグインを有効にします。 PHP を再起動して、構成の変更を適用します。プラグイン ファイルの権限をチェックして、それらが正しいことを確認します。不足している依存関係をインストールして、プラグインが適切に機能することを確認します。他のすべての手順が失敗した場合は、PHP を再構築します。他に考えられる原因としては、プラグインのバージョンに互換性がない、間違ったバージョンをロードしている、PHP 構成の問題などが挙げられます。

php7.0 をインストールおよび展開する方法: 1. PHP 公式 Web サイトにアクセスして、ローカル システムに対応するインストール バージョンをダウンロードします; 2. ダウンロードした zip ファイルを指定したディレクトリに解凍します; 3. コマンド ライン ウィンドウを開いて、次のリンクに移動します。 「E:\php7」ディレクトリ 「php -v」コマンドを実行するだけです。

PHP サーバー環境の一般的な解決策には、正しい PHP バージョンがインストールされていること、および関連ファイルがモジュール ディレクトリにコピーされていることを確認することが含まれます。 SELinux を一時的または永続的に無効にします。 PHP.ini をチェックして構成し、必要な拡張機能が追加され、正しく設定されていることを確認します。 PHP-FPM サービスを開始または再起動します。 DNS 設定に解決の問題がないか確認してください。

システムが再起動した後、UnixSocketの権限を自動的に設定する方法。システムが再起動するたびに、UnixSocketの許可を変更するために次のコマンドを実行する必要があります:sudo ...

エラーの原因とソリューションPECLを使用してDocker環境に拡張機能をインストールする場合、Docker環境を使用するときに、いくつかの頭痛に遭遇します...

PHP7 と比較すると、PHP8 にはパフォーマンス、新機能と構文の改善、型システム、エラー処理と拡張機能の点でいくつかの利点と改善点があります。ただし、どのバージョンを使用するかは、特定のニーズとプロジェクトの状況によって異なります。詳細な紹介: 1. パフォーマンスの向上、PHP8 はコードの実行速度を向上できるジャストインタイム (JIT) コンパイラーを導入します; 2. 新機能と構文の改善、PHP8 は名前付きパラメーターとオプションのパラメーターの宣言をサポートします。関数の作成 呼び出しがより柔軟になり、匿名クラス、プロパティの型宣言などが導入されています。
