tl; dr要するに、この記事では、PHP 5.6(バージョン5.4より前)のバージョンでも、静的プログラミング言語と同様のコンパイラー動作を実現できる特性を作成します。 さらに、特性は入力だけでなく、出力パラメーターも検証します。 つまり、タイピングのヒントに完全に没頭しています。
Webアプリケーションで問題なくこの特性を接続して使用できます。
7.0より古いPHPバージョンのタイプヒンティング
PHPバージョン<7では、メソッド定義で、関数に提供されるデータ型と関数の出力データ型を記述できます。
ここではすべてが素晴らしいです。 尋ねたところ、判明した。
public function filterArray(array $arr, string $filterParameter, callable $filterCallback) : array
配列のフィルタールールを定義する必要があります。ラムダ関数を取得して作成し、その中にフィルタールールを定義しました。 そして
、彼らは事前にそれが配列であり、整数ではないことを知って、
$ arrを
filterArray()に
渡しました 。
突然文字列ではなくオブジェクトを
$ filterParameterとして
渡すと 、PHPはすぐに解析エラーを
返します。 例えば、私たちはこれを注文しませんでした。
PHPバージョン5.6でのタイプヒンティング
ただし、PHPバージョン<5.6は、出力データ型の明示的な指定をサポートしていません。
public function sortArray($arr, $filterParam) : array // <- {
また、PHP <5.6は、
integer 、
string 、
floatなどの入力データ型としてプリミティブをサポートしません。
ただし、一部のタイプは、古いバージョンの言語でも指定できます。 たとえば、
array 、
object 、またはクラスのインスタンスのタイプのパラメーターを関数に渡すように指定できます。
class ArrayForSorting { public $arrayForSorting; public function __construct($arrayForSorting) { $this->arrayForSorting = $arrayForSorting; } } class UserSortArray { public $availableSortingMethods; public function insertSort(ArrayForSorting &$sortArray) { if (false === isset($availableSortMethods->insertMethod)) { throw new UserSortArrayException('Insert method for user array sort is not available.'); } return uasort($sortArray->arrayForSorting, $availableSortMethods->bubbleMethod); } }
元の問題
しかし、お願いします。 配列ではなく、たとえば関数にdoubleを渡す必要がある場合はどうすればよいですか?
また、プログラマーは、文字列、少なくとも配列、少なくとも任意のクラスのインスタンスを関数に簡単に渡すことができます。
この場合の解決策は簡単です。入力パラメーターと出力パラメーターの妥当性を毎回確認するだけです。
class ArraySorter { public function sortArray(array &$sortArray, $userCallback) {
ただし、同じコードを何回書かなければならないか考えることすら怖いです。
if (null !== $param && '' !== $param) { return false;
この問題の明らかな解決策は、トレーにバリデーターを書き込むことです。これに続いて、すべてのタイプの入力パラメーターのチェックを委任します。 パラメーターが必要なタイプではない場合、パーサーはすぐに例外をスローします。
出力では、次のものが得られます。
- 言語の動的な型付けが少なくなります。 しかし、OOPの原則はプログラマーによって地獄に送られることもありません。
- データ型をチェックするための重複コードは、特性を呼び出すことができる場合は、個別の...エンティティとして取り出されます。
- 他のクラスの構造に影響を与えることなく、新しいバリデーターを追加できます。
トレイトは、インポートされた任意のクラスから呼び出すことができるという点で、保護されたメソッドに本質的に似ています。 ただし、継承とは異なり、できるだけ多くの特性をクラスに接続し、そのすべてのプロパティとメソッドを使用できます。
特性は、バージョン5.4.0以降のPHPで使用できます。
特性のソース全体Z.Y. 具体的には、各プリミティブの検証を個別に記述したため、将来的には追加の検証ルールを使用して配列を特性に渡すことができます。 たとえば、整数の場合は
maxValue 、
minValue 、
isNaturalを検証でき、文字列の場合は
空ではなく
長さを検証できます。
<?php namespace traits; trait Validator { public function validate($validationParams) {
使用される特性は非常に単純です。 例として、この特性を使用して関数の入出力データをチェックする方法を示すために、一意の識別子を生成および取得するメソッドを格納するNotebookクラスを実装します。
namespace models; use traits; class Notebook { use \traits\Validator; private $_uid; public function __construct() { $this->_uid = $this->generateUniqueIdentifier(); } public function getNotebookUID() {
別の例:画面にメッセージを表示するPenクラス(一定量のインクで初期化される単純なインクペン)。
ペンクラス <?php namespace models; use traits; class Pen { use \traits\Validator; private $remainingAmountOfInk; public function __construct() { $this->remainingAmountOfInk = 100; } public function drawMessage($message) { $this->validate([ 'string' => $message, ]); if (0 > $this->remainingAmountOfInk) { echo 'Ink ended';
さて、テーブルにペンを書いてみましょう:「Hello World」!
結論:
Pen writes message: hi habrahabr exception was throwed during validation of message
おわりに
ここでは、このような単純な特性の助けを借りて、異なるクラスのメソッドをコピーすることなく
、象のsi-sharpeに関数の入力/出力パラメーターを検証さ
せることができます。
上記の例の
validate()メソッドを特定の検証パラメーター(具体的には、doubleまたはstring変数の最小/最大値、パラメーター検証のカスタムコールバック、例外がスローされたときにメッセージを表示するなど
)に具体的にねじ込みませんでした。
なぜなら、この記事の主な目的は、言語の静的化を可能にするテクノロジーが、古いバージョンのPHPでも簡単に実装されるという事実について話すことだったからです。