変数でforeach
ループを使用したいのですが、この変数にはさまざまなタイプ、たとえばNULL
を使用できます。
foreach
の前にテストします:
if(is_array($var)){
foreach($var as ...
しかし、Iterator
インターフェイスを実装するクラスにもなり得ることに気付きました。たぶん私は盲目ですが、クラスがインターフェイスを実装しているかどうかを確認する方法は? is_a
関数やinherits
演算子のようなものはありますか? class_implements
が見つかりましたが、使用できますが、もっと簡単なものがありますか?
そして、2番目に重要なのは、変数is_array
または "implements Iterator
interface"をチェックするのにこの関数が存在することで十分か、それとも何かをテストする必要があるかということです。
関数内でforeach
を使用していて、配列または Traversable オブジェクトが必要な場合は、その関数のヒントを次のように入力できます。
function myFunction(array $a)
function myFunction(Traversable)
関数内でforeach
を使用していない場合、または両方を期待している場合 単純にこの構成を使用できます 変数を反復処理できるかどうかを確認します。
if (is_array($a) or ($a instanceof Traversable))
foreach
は配列とオブジェクトを処理できます。これは次の方法で確認できます。
$can_foreach = is_array($var) || is_object($var);
if ($can_foreach) {
foreach ($var as ...
}
Traversable
を特に確認する必要はありません。配列-PHPでトラバース可能です。
より技術的に:
foreach
は、すべての種類のトラバーサル、つまり配列、プレーンオブジェクト(アクセス可能なプロパティがトラバースされる)およびTraversable
オブジェクト(または内部get_iterator
ハンドラーを定義するオブジェクト)で動作します。
( ソース )
一般的なPHPプログラミングでは、変数が
andis not
foreach
を使用できます。
単純な関数でTraversable
のインスタンスを確認できます。これはIterator
のすべてに対して機能します。なぜならIterator extends Traversable
function canLoop($mixed) {
return is_array($mixed) || $mixed instanceof Traversable ? true : false;
}
<?php
$var = new ArrayIterator();
var_dump(is_array($var), ($var instanceof ArrayIterator));
bool(false)
またはbool(true)
を返します
<?php
/**
* Is Array?
* @param mixed $x
* @return bool
*/
function isArray($x) : bool {
return !isAssociative($x);
}
/**
* Is Associative Array?
* @param mixed $x
* @return bool
*/
function isAssociative($x) : bool {
if (!is_array($array)) {
return false;
}
$i = count($array);
while ($i > 0) {
if (!isset($array[--$i])) {
return true;
}
}
return false;
}
<?php
$arr = [ 'foo', 'bar' ];
$obj = [ 'foo' => 'bar' ];
var_dump(isAssociative($arr));
# bool(false)
var_dump(isAssociative($obj));
# bool(true)
var_dump(isArray($obj));
# bool(false)
var_dump(isArray($arr));
# bool(true)
PHP 7.1以降、まさにこの目的のために擬似タイプ iterable
があります。タイプヒントiterable
は、Traversable
インターフェイスの実装だけでなく、任意の配列を受け入れます。 PHP 7.1では、関数 is_iterable()
も導入されました。古いバージョンについては、新しい組み込み機能を使用せずに同等のタイプの施行を達成するためのその他の回答を参照してください。
公正なプレー:BlackHoleが指摘したように、この質問は 反復可能なオブジェクトと配列型のヒント? と-の複製のようです 彼または彼女の答え は私のものよりも詳細になります。