ジョブを均等に分割するには、PHP でイテレータをもっと活用する必要があります。
//Pages
$perPage = 10; // Avoid magic numbers
$files = new GlobIterator('docs/*.xml');
$filtered = new FileXmlDoctypeFilterIterator($files, $requestedType);
$count = iterator_count($filtered);
$pagination = new LimitPagination($_GET['page'], $count, $perPage);
foreach ($pagination->getLimitIterator($filtered) as $file)
{
$xml = simplexml_load_file($file);
...
}
では、これはどのように機能するのでしょうか。まず最初に、定義済みのGlobIterator
which を使用することで、その名前から、それが何をするかがすでにわかるかもしれません。ただし、配列を返すのではなくglob()
、イテレータです。
これは特にここで行われ、他のイテレータとのスタックを可能にします。たとえば、次のものは具象であるFilterIterator
ため、フィルター決定のために現在持っているコードをこのイテレーターに移動する必要があります。それがどのように機能するかは、PHPマニュアルに記載されています。
次に、ページネーションを独自のオブジェクトに完全にカプセル化するオブジェクトでiterator_count()
使用される関数を使用して、フィルター処理されたすべてのファイルの数が取得されます。詳細については、 PHP を使用した XML ページネーションLimitPagination
に対する私の回答を参照してください。
$pagination->getLimitIterator($filtered)
指定されたページ内にあるフィルター処理されたファイルを提供するように、別の反復子を提供します ($_GET['page']
上記の例)。また、他のページへのリンクを出力できるように、ページのリストも提供します。
それで、ここで何が行われたか:
- ファイルのフィルタリングに関する問題は、filter-iterator にカプセル化されています。
- ページネーションに関する問題は、イテレータも提供するページネーション オブジェクトにカプセル化されています。
- グロブ化されたファイルをフィルタリングする問題は、配列を反復子に変えることで解決されました。
技術的には、これらすべてを配列でも解決できますが、イテレータの大きな利点は、配列よりもはるかに柔軟であることです。
たとえば、特別な子を作成するイテレータを作成することで、これをさらに改善できます。このイテレータにはSimpleXMLElement
、doctype を取得するためのアルゴリズムと、ファイル パスについて既知のアルゴリズムも含まれます。これに別個のインターフェースを与えると、フィルター反復子に役立ちます。
また、ページネーションが関係しているため、カウント操作の重みが大きくなりすぎないように、フィルタ イテレータをキャッシュすることも理にかなっています。
ここでの反復子の利点は明らかにコードの再利用です。たとえば、LimitPagination
オブジェクトは、反復子の形式で改ページするデータを提供するあらゆる種類の改ページで機能します。
配列に固執したい場合は、それをArrayPagination
オブジェクトに変換する必要があり、フィルター反復子の代わりに、array_filter()
ファイルをフィルター処理するコールバック関数で使用できます。また、プロトタイピングに配列を使用する場合は、ArrayIterator
配列から反復子に切り替えることCallbackFilterIterator
もできます (また、配列フィルター関数を再利用できるはずです)。