Umgang globale Variabel Funktion ...

Hallo zusammen,

kann mir jemand einen Tipp geben wie man mit globalen Variable in einer Funktion umgeht.

Irgendwie verstehe ich gerade nicht, wenn ich z.B. eine Variable global in einer Funktion deklariere
und die Funktion zweimal hintereinander aufrufe, das beim zweiten Funktionsaufruf die Werte vom
ersten Aufruf erhalten bleiben.

Wie geht man mit solchen Variabel um und vor allem wie verhalten sich solche Variabel?

Gruß
MacToolz

Der Tipp wäre die PHP Doku.
PHP: Variable scope - Manual
Mehr geht auch nicht, weil ohne einen Beispiele Code kann man nur raten.
Wobei ich versuchen würde auf globale Variablen zu verzichten.
Stattdessen lieber statische Variablen nutzen oder, wenn man die Variable auch außerhalb der Funktion benötigt, mit Rückgabewerten oder Referenzen arbeiten.
Michael

Hi,

ich bin mir schon über die Deklarationen z.B. global bewusst. Ich habe leider auch keine andere Idee
nicht mit Globale Deklarationen zu arbeiten, weil ja rein theoretisch jeder darauf schreiben kann.

Hier wird die Variable „$arVarList“ global deklariert. Jetzt verhält es sich ja so, das wenn der Funktionsaufruf verlassen wird, sind im Array Daten geschrieben worden und an die Funktion zurück gegeben.
Jetzt wird die Funktion nochmal aufgerufen, und es wird ja dann in die selbe global variabel geschrieben.

Was passiert aber mit dem erneuten Aufruf von der Funktion, wenn immer wieder „global $arVarList“ als Deklaration durchgeführt wird? Wird dafür immer wieder neuer Speicher allokiert?

Oder kennt das PHP Speichermanagement die Variable schon? Muss ja eigentlich oder, weil durch den zweiten Aufruf
wird ja in den selben Bereich geschrieben.

Ok, wenn es ja so ist, was wäre denn der richtige Weg von Global weg zukommen?

Müsste ich mir jetzt selber ein eigenes Objekt erstellen, was ich dann zur Laufzeit erzeuge und wieder freigebe?

function FN_GetAllObjectType($ID, $Type, $arVarName, $xResetVarList) 
{ 
	global $arVarList;		
					
	if ($xResetVarList)
	{
		$arVarList = array();
	}
	else
	{  																																																													 																												 														 							 				     		 
	    foreach (IPS_GetChildrenIDs($ID) as $VarChildID) 
	    {		
				$ChildObj = IPS_GetObject($VarChildID);
				// Alles in Liste sichern
				if ($Type == 32767)
				{
					$arVarList[] = $VarChildID;
				}			
				// über VAR Namen sichern
				elseif (sizeof($arVarName) <> 0)
				{
					foreach ($arVarName as $VarName) 
	    			{				
						if ($ChildObj['ObjectName'] == $VarName) 
						{
							$arVarList[] = $VarChildID;					
						}
					}
				}
				// suchen über Datentyp
				elseif ($Type <> '')
					if ($ChildObj['ObjectType'] == $Type)
					{
						$arVarList[] = $VarChildID;
					}
				else
				{
					//$arVarList[] = $VarChildID;		
				}																																				
			// rekursiver Funktionsaufruf ...																													 																				 															 					 
			FN_GetAllObjectType($VarChildID, $Type, $arVarName, $xResetVarList);							  
	    } 						
	}
	return $arVarList;
} 

Gruß
MacToolz

Eigentlich steht das ganz gut in der von Nall-Chann verlinkten Doku beschrieben. Mit global wird eine Variable von Außerhalb im inneren Block zugänglich gemacht, nicht definiert. Für rekursive Funktionen bietet sich das Static Schlüsselwort an.

Tommi

Definitiv static.
Sofern die Variable nur in dieser Funktion benutzt wird.
Wenn es dir um den Vergleich vom Speicherverbrauch geht und der Verwaltung, dann kannst du ja einfach den Verbrauch selber messen, oder dir die weiterführenden Links zu PHP antun.
PHP: Reference Counting Basics - Manual

Das sind aber Themen wo du in speziellen PHP Foren eventuell mehr Kompetenz findest als hier.
Michael

Hi,

ich muss nochmal nachfragen. Ich verstehe nicht genau was da passiert.

Mir geht es nicht zwingend um die Speicherverwaltung, sondern mir fehlt das Verständnis dafür
wie ich meine Daten nach dem ersten Funktionsaufruf löschen kann.

Ich habe mir ja da was schon gebastelt, indem ich mir mit einer Reset Variabel in dem Funktionsaufruf
dann das Array gelöscht wird.

Also irgendwie stehe ich auf dem Schlauch …

Gruß
MacToolz

Ich glaube mit deiner letzten Frage kann keiner etwas anfangen.
Was meinst du mit löschen?
Entweder ist sie static und somit bleiben die Werte innerhalb der Funktion vorhanden, oder nicht.
Beim ersten Aufrufen der Funktion wird der Wert automatisch gesetzt (die Zuweisung hinter static).
Michael

Hi,

mhhh … wieso, ich rede doch von Daten die in meinem Array geschrieben worden sind, das hatte ich doch erwähnt.

Also, ich habe beides ausprobiert Staic wie global. In meinem vorhandenem Code sieht man das die Array Variable „arVarList“ global deklariert wurde.

Rufe ich meine Funktion ein zweites mal auf, werden dem global Array neue weitere Elemente hinzugefügt.

Es geht ja nicht darum das die Inhalte in meinem Array Elemente weg sind, sondern das sich das Array mit neuen Elementen erweitert, also das Array wird größer.

Das möchte ich aber nicht.

Mein Gedanke ist, das wenn der zweite Aufruf kommt, mein globales Array leer sein soll.
Die Variabel muss aber global sein weil die Funktion rekursiv arbeitet.

Was meinst du damit "innerhalb der Funktion ??

Gruß
MacToolz

Dann brauchst du weder global noch static.

Irrglaube.
Das geht auch ganz simpel mit Übergabe der Daten als Parameter an die Funktion und dem Rückgabewert.
Oder übergeben der Variable als Referenz.

Na innerhalb der Funktion, nicht außerhalb.
Siehe wieder:
PHP: Geltungsbereich von Variablen - Manual

Ich versuchen Mal aus deinen eher wirren Beschreibungen zusammenzufassen was du willst:
Im Script wird eine Funktion aufgerufen.
Diese soll rekursiv sich selber aufrufen und alle Daten zusammenführen und dem aufrufenden zurückgeben.
Wird im Script die Funktion ein weiteres Mal aufgerufen, so fängt sie wieder mit neuen/leeren Daten an.
Korrekt?


function FN_GetAllObjectType($ID, $Type, $arVarName) 
{ 
       $arVarList = array();
        foreach (IPS_GetChildrenIDs($ID) as $VarChildID) 
        {        
                $ChildObj = IPS_GetObject($VarChildID);
                // Alles in Liste sichern
                if ($Type == 32767)
                {
                    $arVarList[] = $VarChildID;
                }            
                // über VAR Namen sichern
                elseif (sizeof($arVarName) != 0)
                {
                    foreach ($arVarName as $VarName) 
                    {                
                        if ($ChildObj['ObjectName'] == $VarName) 
                        {
                            $arVarList[] = $VarChildID;                    
                        }
                    }
                }
                // suchen über Datentyp
                elseif ($Type  '')
                    if ($ChildObj['ObjectType'] == $Type)
                    {
                        $arVarList[] = $VarChildID;
                    }
                else
                {
                    //$arVarList[] = $VarChildID;        
                }                                                                                                                                                
            // rekursiver Funktionsaufruf ...                                                                                                                                                                                                                                                                                        
            $add= FN_GetAllObjectType($VarChildID, $Type, $arVarName);                              
            $arVarList = array_merge($arVarList,$add);
        }                         
    return $arVarList;
}  

Michael

Hi,

tut mir ja leid das ich mich nicht ganz auf deinem Niveau begeben kann …

Ich werde das gleich mal testen … Kenne nicht alle Funktionen die es im PHP gibt wie z.B. das array_merge.
Aber so leuchtet es mir ein und sollte auch so funktionieren …

Bis später mal ich gebe Rückmeldung … aber die paar Zeilen sind ja überschaubar … von daher sollte das ja passen an den stellen die du abgeändert hast … :slight_smile:

Gruß
MacToolz

Das hat nix mit irgendeinem Niveau zu tun.
Du stellst einfach die falschen Fragen :wink:
Oder zu kompliziert :smiley:
Michael