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?
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
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;
}
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.
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
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.
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
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.
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.
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;
}
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 …