In PHP ist Array_walk_recursive eine sehr nützliche Funktion, mit der Sie jedes Element in einem mehrdimensionalen Array betreiben können. Diese Funktion kann jedoch auch Speicherlecks verursachen, insbesondere wenn es sich um große Datenmengen handelt. Speicherlecks können dazu führen, dass die Speicherverwendung der Anwendung wächst und letztendlich zum Absturz des Systems. Daher ist es sehr wichtig zu wissen, wie Sie bei der Verwendung von array_walk_recursive Speicherlecks vermeiden können.
Speicherleck bezieht sich auf das Programm, das den Speicher beantragt, es wird jedoch nicht freigegeben, wenn es nicht mehr verwendet wird, was zu einer kontinuierlichen Zunahme der Speicherverwendung führt, was letztendlich die Leistung und Stabilität des Programms beeinflusst. In PHP treten Speicherlecks normalerweise auf, wenn kreisförmige Referenzen, unbegrenzte Ressourcenzuweisungen oder unreinigte Variablen das Gedächtnis belegen.
Die Funktion array_walk_recursive wird verwendet, um das Array rekursiv zu durchqueren und auf jedes Element eine Rückruffunktion anzuwenden. Die grundlegende Syntax ist wie folgt:
<span><span><span class="hljs-title function_ invoke__">array_walk_recursive</span></span><span>(</span><span><span class="hljs-keyword">array</span></span><span> &</span><span><span class="hljs-variable">$array</span></span><span>, </span><span><span class="hljs-keyword">callable</span></span><span> </span><span><span class="hljs-variable">$callback</span></span><span>);
</span></span>
$ array ist das zu verarbeitende Array.
$ callback ist eine Rückruffunktion, die auf jedes Element des Arrays angewendet wird.
Zum Beispiel:
<span><span><span class="hljs-variable">$array</span></span><span> = [</span><span><span class="hljs-number">1</span></span><span>, [</span><span><span class="hljs-number">2</span></span><span>, </span><span><span class="hljs-number">3</span></span><span>], </span><span><span class="hljs-number">4</span></span><span>];
</span><span><span class="hljs-title function_ invoke__">array_walk_recursive</span></span><span>(</span><span><span class="hljs-variable">$array</span></span><span>, function(&</span><span><span class="hljs-variable">$item</span></span><span>, </span><span><span class="hljs-variable">$key</span></span><span>) {
</span><span><span class="hljs-variable">$item</span></span><span> = </span><span><span class="hljs-variable">$item</span></span><span> * </span><span><span class="hljs-number">2</span></span><span>;
});
</span><span><span class="hljs-title function_ invoke__">print_r</span></span><span>(</span><span><span class="hljs-variable">$array</span></span><span>);
</span></span>
Ausführungsergebnisse:
<span><span>Array
(
[</span><span><span class="hljs-meta">0</span></span><span>] => </span><span><span class="hljs-number">2</span></span><span>
[</span><span><span class="hljs-meta">1</span></span><span>] => Array
(
[</span><span><span class="hljs-meta">0</span></span><span>] => </span><span><span class="hljs-number">4</span></span><span>
[</span><span><span class="hljs-meta">1</span></span><span>] => </span><span><span class="hljs-number">6</span></span><span>
)
[</span><span><span class="hljs-meta">2</span></span><span>] => </span><span><span class="hljs-number">8</span></span><span>
)
</span></span>
Obwohl diese Funktion sehr leistungsfähig ist, können Sie beim Umgang mit größeren Datensätzen Speicher -Leck -Probleme haben, insbesondere wenn Arrays eine große Anzahl verschachtelter Arrays oder Objekte enthalten.
Array_WALK_RECURSIVE betreibt jedes Element mit Referenz. Wenn das Array über das Array rekursiv iteriert, liest und modifiziert es Elemente wiederholt ohne ordnungsgemäße Speicherverwaltung, insbesondere wenn es auf sehr komplexe Strukturen stößt. Insbesondere wenn in der Rückruffunktion neue Referenzen oder Objekte erstellt werden, werden diese Objekte möglicherweise nicht rechtzeitig zerstört, was zu einer zunehmenden Speicherverwendung führt.
Angenommen, Sie erstellen ein neues Objekt in der Rückruffunktion und speichern es, ohne diese Objekte explizit zu zerstören:
<span><span><span class="hljs-variable">$array</span></span><span> = [</span><span><span class="hljs-number">1</span></span><span>, [</span><span><span class="hljs-number">2</span></span><span>, </span><span><span class="hljs-number">3</span></span><span>], </span><span><span class="hljs-number">4</span></span><span>];
</span><span><span class="hljs-title function_ invoke__">array_walk_recursive</span></span><span>(</span><span><span class="hljs-variable">$array</span></span><span>, function(&</span><span><span class="hljs-variable">$item</span></span><span>, </span><span><span class="hljs-variable">$key</span></span><span>) {
</span><span><span class="hljs-variable">$item</span></span><span> = </span><span><span class="hljs-keyword">new</span></span><span> </span><span><span class="hljs-title class_">StdClass</span></span><span>(); </span><span><span class="hljs-comment">// Erstellen Sie ein neues Objekt</span></span><span>
});
</span></span>
In diesem Beispiel wird jedes Mal ein neues Objekt erstellt, wenn Sie wieder aufnehmen, und diese Objekte werden nicht zerstört. Wenn das Array sehr groß ist oder die rekursive Tiefe tief ist, wird das Speicherleck sehr schwerwiegend.
Hier sind einige Best Practices, um Speicherlecks von array_walk_recursive zu vermeiden:
Wenn Sie in der Rückruffunktion temporäre Variablen oder Objekte erstellen, verwenden Sie sie, um sie explizit zu zerstören. Dies wird dazu beitragen, den Speicher rechtzeitig freizugeben.
<span><span><span class="hljs-variable">$array</span></span><span> = [</span><span><span class="hljs-number">1</span></span><span>, [</span><span><span class="hljs-number">2</span></span><span>, </span><span><span class="hljs-number">3</span></span><span>], </span><span><span class="hljs-number">4</span></span><span>];
</span><span><span class="hljs-title function_ invoke__">array_walk_recursive</span></span><span>(</span><span><span class="hljs-variable">$array</span></span><span>, function(&</span><span><span class="hljs-variable">$item</span></span><span>, </span><span><span class="hljs-variable">$key</span></span><span>) {
</span><span><span class="hljs-variable">$item</span></span><span> = </span><span><span class="hljs-keyword">new</span></span><span> </span><span><span class="hljs-title class_">StdClass</span></span><span>();
</span><span><span class="hljs-keyword">unset</span></span><span>(</span><span><span class="hljs-variable">$item</span></span><span>); </span><span><span class="hljs-comment">// Zerstören Sie Objekte rechtzeitig</span></span><span>
});
</span></span>
Generatoren sind eine effiziente Alternative, die Arrays auf faule Weise durchqueren kann, anstatt das gesamte Array sofort in den Speicher zu laden. Durch die Verwendung des Generators können Speicherlecks effektiv vermieden werden.
<span><span><span class="hljs-function"><span class="hljs-keyword">function</span></span></span><span> </span><span><span class="hljs-title">recursive_walk</span></span><span>(</span><span><span class="hljs-params"><span class="hljs-variable">$array</span></span></span><span>) {
</span><span><span class="hljs-keyword">foreach</span></span><span> (</span><span><span class="hljs-variable">$array</span></span><span> </span><span><span class="hljs-keyword">as</span></span><span> </span><span><span class="hljs-variable">$key</span></span><span> => </span><span><span class="hljs-variable">$value</span></span><span>) {
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-title function_ invoke__">is_array</span></span><span>(</span><span><span class="hljs-variable">$value</span></span><span>)) {
</span><span><span class="hljs-keyword">yield</span></span><span> </span><span><span class="hljs-keyword">from</span></span><span> </span><span><span class="hljs-title function_ invoke__">recursive_walk</span></span><span>(</span><span><span class="hljs-variable">$value</span></span><span>); </span><span><span class="hljs-comment">// Rekursiv durch Subarrays durchqueren</span></span><span>
} </span><span><span class="hljs-keyword">else</span></span><span> {
</span><span><span class="hljs-keyword">yield</span></span><span> </span><span><span class="hljs-variable">$key</span></span><span> => </span><span><span class="hljs-variable">$value</span></span><span>;
}
}
}
</span><span><span class="hljs-variable">$array</span></span><span> = [</span><span><span class="hljs-number">1</span></span><span>, [</span><span><span class="hljs-number">2</span></span><span>, </span><span><span class="hljs-number">3</span></span><span>], </span><span><span class="hljs-number">4</span></span><span>];
</span><span><span class="hljs-keyword">foreach</span></span><span> (</span><span><span class="hljs-title function_ invoke__">recursive_walk</span></span><span>(</span><span><span class="hljs-variable">$array</span></span><span>) </span><span><span class="hljs-keyword">as</span></span><span> </span><span><span class="hljs-variable">$key</span></span><span> => </span><span><span class="hljs-variable">$value</span></span><span>) {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"<span class="hljs-subst">$key</span></span></span><span> => </span><span><span class="hljs-subst">$value</span></span><span>\n";
}
</span></span>
Der Generator kann den Speicherverbrauch effektiv reduzieren, indem Elemente bei Bedarf geladen werden.
Vermeiden Sie es, neue Variablen oder Objekte in der Rückruffunktion zu erstellen, und das direkte Ändern des Wertes des ursprünglichen Array -Elements kann unnötigen Speicheraufwand vermeiden.
<span><span><span class="hljs-variable">$array</span></span><span> = [</span><span><span class="hljs-number">1</span></span><span>, [</span><span><span class="hljs-number">2</span></span><span>, </span><span><span class="hljs-number">3</span></span><span>], </span><span><span class="hljs-number">4</span></span><span>];
</span><span><span class="hljs-title function_ invoke__">array_walk_recursive</span></span><span>(</span><span><span class="hljs-variable">$array</span></span><span>, function(&</span><span><span class="hljs-variable">$item</span></span><span>, </span><span><span class="hljs-variable">$key</span></span><span>) {
</span><span><span class="hljs-variable">$item</span></span><span> *= </span><span><span class="hljs-number">2</span></span><span>; </span><span><span class="hljs-comment">// Ändern Sie das ursprüngliche Element direkt</span></span><span>
});
</span></span>
Stellen Sie sicher, dass die von der Rückruffunktion ausgeführte Operation so einfach wie möglich ist und nicht zu viel Ressourcenzuweisung oder komplexe Berechnungen durchführt, insbesondere wenn Sie rekursiv aufrufen. Wenn in der Rückruffunktion Ressourcen vorhanden sind, die wiederholt erstellt werden müssen, versuchen Sie, in jeder Rekursion wiederholtes Erstellen zu vermeiden.
<span><span><span class="hljs-variable">$array</span></span><span> = [</span><span><span class="hljs-number">1</span></span><span>, [</span><span><span class="hljs-number">2</span></span><span>, </span><span><span class="hljs-number">3</span></span><span>], </span><span><span class="hljs-number">4</span></span><span>];
</span><span><span class="hljs-title function_ invoke__">array_walk_recursive</span></span><span>(</span><span><span class="hljs-variable">$array</span></span><span>, function(&</span><span><span class="hljs-variable">$item</span></span><span>, </span><span><span class="hljs-variable">$key</span></span><span>) {
</span><span><span class="hljs-built_in">static</span></span><span> </span><span><span class="hljs-variable">$multiplier</span></span><span> = </span><span><span class="hljs-number">2</span></span><span>; </span><span><span class="hljs-comment">// Verwenden Sie statische Variablen, um konstante Werte zu speichern</span></span><span>
</span><span><span class="hljs-variable">$item</span></span><span> *= </span><span><span class="hljs-variable">$multiplier</span></span><span>;
});
</span></span>
Manchmal kann das Design des Arrays selbst die Leistung und den Speicherverbrauch beeinflussen. Versuchen Sie, zu tief verschachtelte Strukturen zu vermeiden. Wenn möglich, sollten Sie die Datenstruktur in einer flacheren Form vereinfachen und die Komplexität der Rekursion verringern.
Obwohl Array_walk_recursive ein sehr bequemes Werkzeug ist, erfordert die Verwendung auch Sorgfalt, insbesondere wenn es sich um komplexe oder große Datenmengen handelt. Durch die Kontrolle des Speicherverbrauchs, die Reinigung unnötiger Variablen und Objekte und die Übernahme von Generatoren und anderen Optimierungsstrategien können Speicher -Leck -Probleme effektiv vermieden werden. Denken Sie daran, die Speicherverwaltung ist einer der Schlüssel zur PHP -Leistungsoptimierung. Angemessener Speicherverbrauch kann die Stabilität und Reaktionsgeschwindigkeit der Anwendung erheblich verbessern.