web-dev-qa-db-ja.com

PHPプリミティブ値へのタイプヒント?

メソッドを型ヒントしてプリミティブ型を期待できるかどうかを知りたいですか?

このようなもの:

public function someMethod(string $str)
                         //^^^^^^

または:

private function anotherMethod(int $num)
                             //^^^

同じ方法:

private function otherMethod(Person $rambo)
                           //^^^^^^

それはPHPで可能ですか?

72
Felipe Almeida

PHP 7では、以下を追加しました:

型宣言により、関数は呼び出し時にパラメーターが特定の型であることを要求できます。指定された値のタイプが正しくない場合、エラーが生成されます。inPHP 5、これは回復可能な致命的エラーになりますが、PHP 7 TypeError例外をスローします。

リファレンス: http://php.net/manual/en/functions.arguments.php#functions.arguments.type-declaration


この答えが尋ねられたとき、PHP 5が最新であり、次のように述べています。

PHP 5では、タイプヒンティングが導入されています。関数は、パラメータをオブジェクト(関数プロトタイプでクラスの名前を指定すること)、インターフェイス、配列(PHP 5.1以降)またはcallable(PHP 5.4)以降。ただし、NULLがデフォルトのパラメーター値として使用されている場合、以降の呼び出しの引数として許可されます。

クラスまたはインターフェースがタイプヒントとして指定されている場合、そのすべての子または実装も許可されます。

型ヒントは、intやstringなどのスカラー型では使用できません。リソースおよび特性も使用できません。

リファレンス: http://php.net/manual/en/language.oop5.typehinting.php

83
afuzzyllama

いや。 PHPにはプリミティブの自動変換があります。 http://bugs.php.net/bug.php?id=29508 を参照してください。これは、PHPチームが突然の心の変化(疑わしい、彼らはかなり頑固だ)がない限り、決して変更されません。

29
Rafe Kettler

はい、可能になりました。長い議論の後、スカラー関数パラメーターと戻り値の型ヒントを実装する提案が、これまでで最高の投票数で承認されました。詳細を確認してください。

スカラー型のヒントは、int、float、string、およびbool型の関数パラメーターと戻り値の型を宣言することで構成されます。これにより、PHPランタイムエンジンが値の型パラメータ関数に渡され、戻り値は、最終的なプログラミングの間違いを検出するために予期されるタイプです。オブジェクト、配列、および呼び出し可能オブジェクトのタイプヒントは、過去PHPバージョンで既に許可されていました。新しい予約語:int、float、bool、string、numericこれらは以前は予約されていませんでした。

Example :
function test(float $a) {
    var_dump($a); 
}

test(1); // float(1)
test("1"); // float(1)
test(1.0); // float(1)
test("1a"); // E_RECOVERABLE_ERROR
test("a"); // E_RECOVERABLE_ERROR
test(""); // E_RECOVERABLE_ERROR
test(1.5); // float(1.5)
test(array()); // E_RECOVERABLE_ERROR
test(new StdClass); // E_RECOVERABLE_ERROR

また、スケーラータイプのヒントを許可できるソースファイルに宣言するオプションもあります。これは、構成スクリプトの1行目である必要があり、同じファイル内の他の場所では宣言できません。

Like : declare(strict_types=1);

実行時に、PHPエンジンが値を返そうとすると、致命的なエラー:引数1がincrement()に渡されたなどの致命的なエラーをスローする宣言されたとおりに一致しないかどうかをチェックします整数型、文字列が指定されている必要があります

宣言のこの新しい機能を使用すると、誤った型の値を関数に渡すことによって引き起こされるプログラミングの初期ミスを検出することにより、より堅牢なアプリケーションを作成できます。

タイプの自動変更も発生する場合があります。たとえば、int型は自動的にfloat型パラメーターに変更できますが、

function test(float $x){
    var_dump($x);
}
test(10); // works fine

戻り型の宣言

関数宣言の最後の括弧と最初の括弧の間に期待される型が続くコロンを追加して、戻り値の型を宣言できます。

値を返さない関数については、戻り値の宣言セクションに何も追加しないでください。

function mustReturnInt(): int { ... }
function mustReturnString(): string { ... }
function mustReturnBool(): bool { ... }
function mustReturnFloat(): float { ... }
function doesNotReturnAnything() { ... }

もう少し複雑な例

declare(strict_types=1);  
class StrictTypesTestingClass {  
public function returnSameInt(int $value): int {   return $value;  }   
public function returnSameFloat(float $value): float {   return $value;  }  
public function returnSameString(string $value): string {   return $value;  }   
public function returnSameBool(bool $value): bool {   return $value;  } }  
$check = new StrictTypesTestingClass();  // calls that work  print $check->returnSameInt(10); 
print $check->returnSameFloat(10.0); 
print $check->returnSameString("test"); 
print $check->returnSameBool(true) ? 'true' : 'false';  // calls that throw exceptions 
print $check->returnSameInt("10"); 
print $check->returnSameFloat("10.0"); 
print $check->returnSameString(10);
print $check->returnSameBool("true");

弱い型チェックと型変換の動作:弱い型チェックモードは、declare(strict_types = 0);ステートメントで使用できます。または、厳密な型宣言がありません。考慮すべき点がいくつかあります。拡張機能または組み込みのPHP関数は、以前のPHPバージョン新しいスカラー型宣言の弱い型チェック規則は、拡張機能または組み込みのPHP関数の規則とほとんど同じです。NULLは、現在の型宣言と一貫性を保つための特別な場合です。クラス、呼び出し可能オブジェクト、および配列の場合NULLは、パラメーターであり、明示的にNULLの既定値が明示的に指定されていない限り、既定では受け入れられません。

このアプローチには多くの利点があります。タイプセーフティを取得します。これは、最終的に静的にコードを分析できることを意味します!ある関数から誤って文字列を取得し、整数として別の関数に渡すというバグを検出できます。私にとって、毎日PHPを使用してJava OOP言語のリファレンスとして、これはPHPにとって大きな進歩です。

16
Purushottam

PHPはサポートしていません。この理由は、自動変換だけでなく、コミュニティの反応にも関連しています。

これまでのところ、2010年5月にPHPトランクにスカラータイプヒンティングのサポートが追加されました。ただし、コミュニティの反応により、この機能は5.4リリースに含まれませんでした。

これについては少し論争がありました。この変更に反対した人々は、このサポートはPHPの基本的な設計に反すると主張しました。 PHPは弱い型付け言語と見なされます。本質的に、これはPHPではデータ型を宣言する必要はありません。変数にはデータ型が関連付けられていますそれらを使用すると、エラーにならずに整数に文字列を追加するなどの過激なことを行うことができます。

IMHO:にスカラー型のヒントを追加する必要がありますPHP ASAP、それは私たちが必要とする機能です、私は本当にPHP弱い型付き言語ですが、ハイエンドの開発とプロダクションのために、特にOOコンテキストでは、スカラー型のヒントが必要です。PHPには、手続き型とオブジェクト指向のように両方の選択肢があります。

5
TCB13

はい、可能です。

http://ru2.php.net/manual/ru/language.oop5.typehinting.php#83442

警告:元のマニュアルにはタイプミスがあります:代わりにresrouce of resource

人々はしばしばスカラー/基本型ヒントについて尋ねます。これは、MVCフレームワークで使用するクラスのドロップで、カスタムエラーハンドラーを使用してtypehintsを有効にします。

注:このコードは、インクルードヘッダーの他のすべてのコードの上に含める必要があります。set_error_handler()関数を使用している場合は、これも使用することに注意してください。 set_error_handlers()をチェーンする必要があるかもしれません

どうして?

  1. 人々はis_ *関数を使用してパラメーターを検証することにうんざりしているためです。
  2. 防御コーダーの冗長コーディングの削減。
  3. 関数/メソッドは、必要な入力に関して自己定義/文書化しています。

また、PHP 6.0のtypehintsの説明に従って、PHP内部ボードを参照してください。

<?php

define('TYPEHINT_PCRE', '/^Argument (\d)+ passed to (?:(\w+)::)?(\w+)\(\) must be an instance of (\w+), (\w+) given/');

class Typehint
{

    private static $Typehints = array(
        'boolean'   => 'is_bool',
        'integer'   => 'is_int',
        'float'     => 'is_float',
        'string'    => 'is_string',
        'resource'  => 'is_resource'
    );

    private function __Constrct() {}

    public static function initializeHandler()
    {

        set_error_handler('Typehint::handleTypehint');

        return TRUE;
    }

    private static function getTypehintedArgument($ThBackTrace, $ThFunction, $ThArgIndex, &$ThArgValue)
    {

        foreach ($ThBackTrace as $ThTrace)
        {

            // Match the function; Note we could do more defensive error checking.
            if (isset($ThTrace['function']) && $ThTrace['function'] == $ThFunction)
            {

                $ThArgValue = $ThTrace['args'][$ThArgIndex - 1];

                return TRUE;
            }
        }

        return FALSE;
    }

    public static function handleTypehint($ErrLevel, $ErrMessage)
    {

        if ($ErrLevel == E_RECOVERABLE_ERROR)
        {

            if (preg_match(TYPEHINT_PCRE, $ErrMessage, $ErrMatches))
            {

                list($ErrMatch, $ThArgIndex, $ThClass, $ThFunction, $ThHint, $ThType) = $ErrMatches;

                if (isset(self::$Typehints[$ThHint]))
                {

                    $ThBacktrace = debug_backtrace();
                    $ThArgValue  = NULL;

                    if (self::getTypehintedArgument($ThBacktrace, $ThFunction, $ThArgIndex, $ThArgValue))
                    {

                        if (call_user_func(self::$Typehints[$ThHint], $ThArgValue))
                        {

                            return TRUE;
                        }
                    }
                }
            }
        }

        return FALSE;
    }
}

Typehint::initializeHandler();

?>

An are some examples of the class in use:

<?php

function teststring(string $string) { echo $string; }
function testinteger(integer $integer) { echo $integer; }
function testfloat(float $float) { echo $float; }

// This will work for class methods as well.

?>

あなたは写真を取得します。

3
Sergii Smirnov

Accordind to PHP documentation タイプヒンティングはプリミティブタイプではサポートされていません。

ただし、クラスとインターフェイスではサポートされています。

編集:配列でもサポートされていることを忘れていました。

1
Luc M

渡されたパラメーターからブール値を強制するための短い構文を次に示します。 $stateが真の場合、$this->is_activeはtrueに設定されます。他のすべてのタイプの値では、falseに設定されます。

function set_active ( $state ) {
    $this->is_active = true === $state;
}
0
Lee Blue