Array löschen, recursiv, bei referenzen die referenzierte Variable löschen(unset)

FBIagent

Erfahrenes Mitglied
Hallo,

wie im Titel beschrieben möchte ich arrays(ein dimensional) vollständig recursiv löschen können. Auch Elemente die selbst ein Array sind sollen vollständig gelöscht werden. Wenn ein Element eine Referenz auf eine Variable ist soll die Variable gelöscht werden, die referenziert wird.

Ich habe bereits 2 Funktionen implementiert(Beide arbeiten gleich und liefern auch die gleichen Resultate, der einzigste Unterschied ist einmal mit Rekursion und einmal ohne Rekursion), funktioniert bei $GLOBALS auch einwandfrei nur wenn ich selbst Referenzen einem Array hinzufüge schaut das anders aus. Und bei numerischen Array-Keys scheint das garnicht zu funktionieren.

Wozu brauchst du denn sowas?
Ich möchte keinen aufwendigen Template-Parser für eine Template-System schreiben, also verwende ich PHP für die Templates. Pro Seite habe ich ein Script das die Daten zusammen sammelt und noch ein Ausgabe-Script welches die gesammelten Daten vernwenden kann. Aber nur die gesammelten Daten und Daten die das Template-System global zur verfügung stellt sollen für das Ausgabe-Script verfügbar sein. Damit ich nichts ändern muss wenn sich etwas an den Superglobalen ändert, würde ich das gerne automatisiert machen. Des weiteren wäre das dann auch auf meine eigenen variablen anwendbar(locale Arrays mit Referenzen auf globale Variablen).
PHP:
<?php

function unset_array_elements(&$array)
{
	if (!is_array($array))
		return;

	foreach ($array as $key => $value)
	{
		if (is_array($array[$key]))
		{
			if ($key != 'GLOBALS')
			{
				unset_array_elements($array[$key]);
				unset($array[$key]);
			}
		}
		else
		{
			unset($array[$key]);
		}
	}
}

function unset_array_elements2(&$arrayArg)
{
	if (!is_array($arrayArg))
		return;

	// <iteration_array>, <parent_array>, <parent_array_key>
	$arrays = array(array(&$arrayArg, null, null));
	$index = 0;
	
	while ($index < count($arrays))
	{
		$arrayInfo = $arrays[$index];
		$array = &$arrayInfo[0];

		foreach ($array as $key => &$value)
		{
			if (is_array($value))
			{
				// in case we clear the GLOBALS array, it has a reference to itself
				if ($key != 'GLOBALS')
					// safe reference to the new array($value) and the reference to it's parent array($array)
					$arrays[] = array(&$value, &$array, $key);
			}
			else
			{
				// should unset references too i guess?
				unset($array[$key]);
			}
		}
		
		++ $index;
	}

	// ignore the first array added(function argument)
	for ($index = count($arrays) - 1;$index > 0;-- $index)
	{
		unset($arrays[$index][1][$arrays[$index][2]]);
	}
}

?>

<?php
$arr = array('s1', 's2', 's3');
$arr2 = array('arr' => &$arr);
?>
$arr = <?php print_r($arr); ?><br>
$arr2 = <?php print_r($arr2); ?><br>
<?php $arr2['arr'][0] = 's5'; ?>
$arr = <?php print_r($arr); ?><br>
$arr2 = <?php print_r($arr2); ?><br>
<?php $arr[1] = 's32'; ?>
$arr = <?php print_r($arr); ?><br>
$arr2 = <?php print_r($arr2); ?><br>
<?php unset_array_elements2($arr2); ?>
$arr = <?php print_r($arr); ?><br>
$arr2 = <?php print_r($arr2); ?><br>
----------------------------------------------------------------------<br>

<?php
$arr3 = array('s2', 's3', 's4');
$arr4 = array(0 => &$arr3);
?>
$arr3 = <?php print_r($arr3); ?><br>
$arr4 = <?php print_r($arr4); ?><br>
<?php $arr4[0][0] = 's9'; ?>
$arr3 = <?php print_r($arr3); ?><br>
$arr4 = <?php print_r($arr4); ?><br>
<?php $arr3[1] = 's43'; ?>
$arr3 = <?php print_r($arr3); ?><br>
$arr4 = <?php print_r($arr4); ?><br>
<?php unset_array_elements2($arr4); ?>
$arr3 = <?php print_r($arr3); ?><br>
$arr4 = <?php print_r($arr4); ?><br>
----------------------------------------------------------------------<br>

$GLOBALS = <?php print_r($GLOBALS); ?><br>
<?php unset_array_elements2($GLOBALS); ?>
$GLOBALS = <?php print_r($GLOBALS); ?><br>
$_POST = <?php print_r($_POST); ?><br>
$_GET = <?php print_r($_GET); ?><br>
$_COOKIE = <?php print_r($_COOKIE); ?><br>
$_FILES = <?php print_r($_FILES); ?><br>

Ausgabe:
Code:
$arr = Array ( [0] => s1 [1] => s2 [2] => s3 )
$arr2 = Array ( [arr] => Array ( [0] => s1 [1] => s2 [2] => s3 ) )
$arr = Array ( [0] => s5 [1] => s2 [2] => s3 )
$arr2 = Array ( [arr] => Array ( [0] => s5 [1] => s2 [2] => s3 ) )
$arr = Array ( [0] => s5 [1] => s32 [2] => s3 )
$arr2 = Array ( [arr] => Array ( [0] => s5 [1] => s32 [2] => s3 ) )
$arr = Array ( )
$arr2 = Array ( )
----------------------------------------------------------------------
$arr3 = Array ( [0] => s2 [1] => s3 [2] => s4 )
$arr4 = Array ( [0] => Array ( [0] => s2 [1] => s3 [2] => s4 ) )
$arr3 = Array ( [0] => s9 [1] => s3 [2] => s4 )
$arr4 = Array ( [0] => Array ( [0] => s9 [1] => s3 [2] => s4 ) )
$arr3 = Array ( [0] => s9 [1] => s43 [2] => s4 )
$arr4 = Array ( [0] => Array ( [0] => s9 [1] => s43 [2] => s4 ) )
$arr3 = Array ( [0] => s9 [1] => s43 [2] => s4 )
$arr4 = Array ( [0] => Array ( [0] => s9 [1] => s43 [2] => s4 ) )
----------------------------------------------------------------------
$GLOBALS = Array ( [GLOBALS] => Array *RECURSION* [_POST] => Array ( ) [_GET] => Array ( [ping] => pong ) [_COOKIE] => Array ( ) [_FILES] => Array ( ) [arr] => Array ( ) [arr2] => Array ( ) [arr3] => Array ( [0] => s9 [1] => s43 [2] => s4 ) [arr4] => Array ( [0] => Array ( [0] => s9 [1] => s43 [2] => s4 ) ) )
$GLOBALS = Array ( [GLOBALS] => Array *RECURSION* )
$_POST = Notice: Undefined variable: _POST in C:\servers\apache\htdocs\unset_array_elements.php on line 106
$_GET = Notice: Undefined variable: _GET in C:\servers\apache\htdocs\unset_array_elements.php on line 107
$_COOKIE = Notice: Undefined variable: _COOKIE in C:\servers\apache\htdocs\unset_array_elements.php on line 108
$_FILES = Notice: Undefined variable: _FILES in C:\servers\apache\htdocs\unset_array_elements.php on line 109

Nach dem aufruf von unset_array_elements2 sollte das referenzierte Array global nicht mehr existieren:
PHP:
unset_array_elements2($arr2); -> $arr sollte nicht mehr existieren
unset_array_elements2($arr4); -> $arr3 sollte nicht mehr existieren

Allerdings existieren $arr und $arr3 nach den tests noch. Bei $GLOBALS sind alle anderen wie _POST, _GET etc. auch verschwunden da funktioniert das also irgendwie.

Mache ich da was mit den Referenzen falsch? In $GLOBALS ist am Ende $arr und $arr3 nicht mehr vorhanden.

Daten nur auf null setzen möchte ich nicht, die Ausgabe-Schicht soll rein garnichts von den hervorgegangenen Vorgängen wissen.
 
Zuletzt bearbeitet:
Hi,
auf Null setzen ist aber eine gute Idee, weil dann der Carbage von Php greift und du brauchst dich um nichts mehr kümmern.

Sehe es mal so z.B. in C++ mußte man expliziet zum Kontruktor auch einen Destruktor programmieren. Heute haben aber alle Interpreter Sprachen, wozu auch Php zählt, einen Carbage Kollektor. Also alles was Null ist fliegt aus den Stack raus, verstehe nicht warum du das nicht nutzen willst...:)
 
Zurück