2011-10-20 11 views
43

私は、オブジェクトの種類を本当に気にせずに、オブジェクトで使用することを意図したコードに取り組んできました。書かれているメソッドがどのような型のオブジェクトを期待していても何らかの難しさに遭遇したというヒントを打ちたいオブジェクトのタイプヒント

私は内のオブジェクトを渡すことを試みたとき、私はfunction myFunc (object $obj)function myFunc (stdClass $obj)が、これら発生したエラーの両方を試してみました:

Catchable fatal error: Argument 1 passed to MyClass::MyFunc() must be an instance of object, instance of ObjectActualClass given

を同じは私が何をしないのですstdClass同様

で起こったのか?私は、明示的に他のクラスから継承していないすべてのクラスがstdClassから継承したと考えました。つまり、PHPのすべてのクラスの基本クラスはstdClassです。これは当てはまりませんか?

+2

が重複する可能性でこれを確認することができます[PHPタイプヒンティング:?アレイのサポート、オブジェクトではありません](http://stackoverflow.com/questions/1547696/php-type-hinting -array-supported-object-not) – Jon

+0

完全な解決策の私の答えを参照してください –

答えて

42

stdClassは基本クラスではありません! PHPクラスはどのクラスからも自動的に継承されません。明示的に別のクラスを拡張しない限り、すべてのクラスはスタンドアロンです。 PHPはこの点で多くのオブジェクト指向言語とは異なります。

+0

これは正しいですが、この問題の完全な解決策は下の私の答えを参照してください。オブジェクトのヒントを入力する方法を示します。https://stackoverflow.com/questions/7839059/type-hinting-for-any-object/23337681#23337681 –

6

すべてのオブジェクトが拡張される基本クラスはありません。タイプヒントを削除して、@param注釈で予想されるタイプを文書化するだけです。

-3

あなたはこのような何かを行うことができます:

function myFunc ($obj) 
{ 
    if ($obj instanceof stdClass) { .... } 
} 
+2

すべてのオブジェクトがstdClassから派生しているわけではありません。これは、$ objの型ヒントとしてstdClassを含めることと同じです – ljelewis

+1

stdClassは基本クラスではなく、間違った答えです... –

3

は、指定されたクラスを拡張するために、あなたのインターフェイスのすべてのユーザーを必要とせずにこれを行うには組み込みのメカニズムがありません。とにかく、なぜこれをやりたいのですか?すべてのオブジェクトタイプに共通しているのは、APIの適切な入力になるには十分ですか?

このようにヒントを入力しても、何も得られない可能性があります。一方、インターフェイスを実装するためのヒンティング・タイプのヒンティング・タイプ(Traversableなど)ははるかに意味があります。

ヒントを入力するのに似たものが必要な場合は、実行時のチェックをパラメータのis_objectに置き換えることができます。

1

タイプヒントstdClassはPHP 5.3以降で動作します(私が間違っていない場合)。続き stdClass構築物についてtypehintを使用して、有効なコードです:

test.php

class Test{ 
    function hello(stdClass $o){ 
     echo $o->name; 
    } 
} 

class Arg2 extends stdClass{ 
    public $name = 'John'; 
    function sayHello(){ 
     echo 'Hello world!'; 
    } 
} 

$Arg1 = new stdClass(); 
$Arg1->name = 'Peter'; 

$Arg2 = new Arg2(); 
$Arg2->sayHello(); 

$test = new Test(); 

// OK 
$test->hello($Arg1); 
$test->hello($Arg2); 

// fails 
$test->hello(1); 

が出て印刷します:

Hello world!
Peter
John

Catchable fatal error: Argument 1 passed to Test::hello() must be an instance of stdClass, integer given, called in test.php on line 32 and defined in test.php on line 5

9

オブジェクトのための型のヒンティングはありませんが、あなたが使用することができます。

if (!is_object($arg)) { 
    return; 
} 
36

ベストこれを実行する方法は、Objectという退化したインタフェースを作成することです。縮退インタフェースとは、メソッドが定義されていないことを意味します。

interface Object { 

    // leave blank 

} 

次に、基本クラスでObjectを実装できます。

class SomeBase implements Object { 

    // your implementation 

} 

あなたは

function myFunc (Object $obj); 

myFunc($someBase); 

に望んでいたとして、あなたは今、あなたのObjectインタフェースから継承する任意のオブジェクトを渡すと、このタイプのヒントが通過しますあなたの関数を呼び出すことができます。配列、int、stringなどを渡すと、型ヒントは失敗します。

+6

+1これは最高のoopの答えです。 – DerDu

+1

あなたのクラス構造がより階層的であれば、基本クラスで 'stdClass'を拡張することはできませんでしたか? –

+0

OPはすでにstdClassを使用していますが、stdClassはすべてのオブジェクトのベースではないため動作しません。 Javaほどそうではありません。 – Gokigooooks

3

8年しかかかりませんでしたが、これは間もなく可能になります。PHP 7.2では、objectタイプのヒントが導入されました! 私はこれを書いているので、それは現在RFCの段階にあり、is due to be released in Novemberです。

アップデート、11月30日:PHP 7.2 has been released

RFC: Object typehint

Discussion

これは、あなたが期待するかもしれないとまったく同じように動作します。

<?php 

class Foo {} 
class Bar {} 

function takeObject(object $obj) { 
    var_dump(get_class($obj)); 
} 

takeObject(new Foo); 
takeObject(new Bar); 
takeObject('not an object'); 

はになりますこの

string(3) "Foo"

string(3) "Bar"

Fatal error: Uncaught TypeError: Argument 1 passed to takeObject() must be an object, string given, called in...

一副作用はobjectは現在、残念ながら壊れ上記@Gaz_Edgeの既存のソリューションをレンダリングする予約語であることです。

1

php7.2では、この機能が実装されました。任意のオブジェクトにヒントを入力できます。

function myFunc(Object $myObject) : Object { 
    return $myObject; 
} 

あなたはのofficial documentation

関連する問題