16

私が思いつくことができる最高のものは

function is_array_alike($array) {
  return is_array($array) || (is_object($array) && $array instanceof ArrayAccess && $array instanceof Traversable && $array instanceof Serializable && $array instanceof Countable);
}

うーん。もっときれいなものはありますか?

編集:のテストis_objectは不要のようです。それについてのセクションをPHPマニュアルのインスタンスに追加しました。

4

4 に答える 4

11

さて、あなたはあなたの投稿で「きれい」という言葉を使用したので、読みやすさのための化粧品の変更についての簡単な提案:

function is_array_or_alike($var) {
  return is_array($var) ||
           ($var instanceof ArrayAccess  &&
            $var instanceof Traversable  &&
            $var instanceof Serializable &&
            $var instanceof Countable);
}

変更の説明:

  1. 関数名の変更: " is_array_alike"-> " is_array_or_alike"配列性と類似性の両方がテストされていることを明確にするために、

  2. パラメータ/引数の名前の変更:$array-> $var" $array"は、引数が配列型であることを前提としているためです。

  3. 読みやすさとDrupalコーディング標準への準拠のためのスタック&&'ed条件:最大80文字の行。あなたはDrupalのコアメンテナーの1人なので、この関数がDrupalに組み込まれる可能性があると思います。したがって、とにかくコミットする前にこれを行ったと思います。

  4. あなたはそれが不必要であることは正しいですis_object()instanceofJavaでは、最初のオペランドがオブジェクトでない場合にコンパイル時エラーがスローされるため、これが必要になりますが、PHPでチェックしたところ、エラーはなく、bool(false)の結果だけでした。

私はあなたがユースケースを提供するというpaulmatthews86の提案を2番目にしています。基準がわからない場合、推奨事項を提供することは困難です。たとえば、ダックタイピングのパラダイムの観点から少し借用するには、instanceofテストは便利ですが、必ずしも必須ではなく、完全である必要もありません。できることと、特定のコンテキストでの動作に関心がある場合は$var、リフレクションを使用して、後で呼び出す必要のあるメソッドの存在を確認するか、渡されたときに期待どおりに動作することをテストできます。配列関数に。たとえば、、などで「機能」しますかarray_udiff_assocarray_chunkこれらの動作がユースケースにとってより重要である場合、これらのテストはinstanceofタイプテストに取って代わる可能性がありますが、もちろん多くの重複があります。

お役に立てれば。投稿することにした場合、最終的に何を決定するかを確認することに興味があります。

于 2012-09-11T16:58:25.893 に答える
1

phphttp ://php.net/manual/en/class.iterator.phpにイテレータインターフェイスがあります

使用する

function isIter($abc) {
    return (is_array($abc) || $abc instanceof Traversable);
}
于 2012-09-10T07:23:16.633 に答える
1

ArrayObjectを実装していてもSerializable、オブジェクトが配列のように実装する必要があるという仮定は間違っています。

逆の場合です。Serializableオブジェクトのシリアル化を効果的に防ぐために利用できます。したがって、インターフェイスチェックから削除することを検討します。

またinstanceof、オブジェクトなしで使用すると、(致命的な)エラーが表示されます。「配列のような」オブジェクトのチェックをリーフ関数に委任し、入力タイプの厳密性が低い関数でそれを利用することをお勧めします。

function is_array_or_object_arraylike($var) {

    return is_array($var) 
        || (is_object($var) && is_object_arraylike($var))
        ;
}

function is_object_arraylike($obj) {

    return $obj instanceof ArrayAccess
        && $obj instanceof Traversable
        && $obj instanceof Countable
        ;
}

また、オブジェクトが配列に似ていても、ほとんどの配列関数では機能しないことにも注意してください。また、ではうまく機能しforeachないため、ここで探しているアレイ機能の概要を説明する必要があります。

于 2012-10-04T17:25:29.237 に答える
0

is_countableここに関数を実装するPHP7.3の新しい仕様がありますhttps://wiki.php.net/rfc/is-countable

仕様に基づいて、以前のPHPバージョンでは、これを使用できます

if (is_array($foo) || $foo instanceof Countable) {
    return count($foo);
}

または、このようなポリフィルの一種を実装することもできます

if (!function_exists('is_countable')) {

    function is_countable($c) {
        return is_array($c) || $c instanceof Countable;
    }

}
于 2018-04-18T13:48:21.703 に答える