Vous pouvez utiliser un Iterator itérer sur le tableau, puis produire votre sortie désirée:
class TranformArrayIterator extends RecursiveIteratorIterator
{
protected function indent()
{
echo str_repeat("\t", $this->getDepth());
return $this;
}
public function beginIteration()
{
echo '<nodes>', PHP_EOL;
}
public function endIteration()
{
echo '</nodes>', PHP_EOL;
}
public function beginChildren()
{
$this->indent()->beginIteration();
}
public function endChildren()
{
$this->indent()->endIteration();
}
public function current()
{
return sprintf('%s<node>%s</node>%s',
str_repeat("\t", $this->getDepth() +1),
parent::current(),
PHP_EOL);
}
}
puis assembler comme ceci:
$iterator = new TranformArrayIterator(new RecursiveArrayIterator($nodes));
foreach($iterator as $val) {
echo $val;
}
sorties
<nodes>
<node>parent node</node>
<node>parent node</node>
<nodes>
<node>child node</node>
<node>child node</node>
<nodes>
<node>grand child node</node>
<node>grand child node</node>
</nodes>
</nodes>
</nodes>
Pour masquer $key
lors de l'utilisation $key => $val
, ajoutez à TraverseArrayIterator
public function key()
{
return '';
}
Étant donné que votre objectif semble être de produire XML, vous pouvez aussi passer un XMLWriter en tant que collaborateur du Iterator. Cela permet plus de contrôle sur le XML généré et permet également que la sortie est XML valide:
class TranformArrayIterator extends RecursiveIteratorIterator
{
private $xmlWriter;
public function __construct(
XmlWriter $xmlWriter,
Traversable $iterator,
$mode = RecursiveIteratorIterator::LEAVES_ONLY ,
$flags = 0)
{
$this->xmlWriter = $xmlWriter;
parent::__construct($iterator, $mode, $flags);
}
public function beginIteration()
{
$this->xmlWriter->startDocument('1.0', 'utf-8');
$this->beginChildren();
}
public function endIteration()
{
$this->xmlWriter->endDocument();
}
public function beginChildren()
{
$this->xmlWriter->startElement('nodes');
}
public function endChildren()
{
$this->xmlWriter->endElement();
}
public function current()
{
$this->xmlWriter->writeElement('node', parent::current());
}
}
Vous aurait alors l'utiliser comme ceci:
$xmlWriter = new XmlWriter;
$xmlWriter->openUri('php://output');
$xmlWriter->setIndent(true);
$xmlWriter->setIndentString("\t");
$iterator = new TranformArrayIterator(
$xmlWriter,
new RecursiveArrayIterator($nodes)
);
et foreach
« ing dessus produira la même sortie alors (mais en ajoutant le prologue XML)
pourquoi cherchez-vous une approche basée sur l'itération? Est-ce un devoir? – SilentGhost
pourquoi? pourquoi ferais-tu ça? –
Votre exemple utilise déjà l'itération en combinaison avec la récursivité. – meagar