[OOP PHP] Methoden blockieren sich gegenseitig?!

fragger1991

New Member
Hallo,

ich habe mir eine Klasse geschrieben wo ich alle Infos für mein GS WI auslesen kann, nun habe ich aber das Problem das ich 2 Methoden aufrufen muss innerhalb einer Aktion, das endet jedoch im Abbruch der Seite, es ist kein Vollständiger Seitenaufbau damit mehr möglich.

Interessanterweise werden auch keine Fehler ausgegeben, display_errors steht auf 1 mit E_ALL und E_NOTICE.

Konkret geht es um diese beiden Methoden:
PHP:
	public function getLoginByFtpId($id, $sID) {

		$sID = call_user_func_array("getServerIDById", array($sID));

		if($this->checkServerExist($sID) == true) {

			$arr = call_user_func_array("changeObjectInArray", array($this->ftplist($sID)));
			foreach($arr as $key => $val) {
				if($val[id] == $id) return $val[userid];
			}

		} else {
			return 0;
		}

	}

	public function getStatusByFtpId($id, $sID) {

		$sID = call_user_func_array("getServerIDById", array($sID));

		if($this->checkServerExist($sID) == true) {

			$arr = call_user_func_array("changeObjectInArray", array($this->ftplist($sID)));
			foreach($arr as $key => $val) {
				if($val[id] == $id) return $val[enabled];
			}

		} else {
			return 0;
		}

	}

Innerhalb dieser Methoden werden jeweils 2 definierte, externe Funktionen angefragt, welche ich mittels call_user_func_array eingebunden habe. Die Methoden sollen jeweils den Status ob Aktiv oder nicht und den FTP Loginnamen ausgeben, die Daten werden über ftplist geholt, wo sich alle FTP Accounts drin befinden, das ganze wird dann mit dem IF gesucht und entsprechend ausgegeben.

Ein bekannter von mir weiß zwar wie man das Problem löst, doch hat nicht wirklich Interesse mir den Weg zu verraten, "es wäre zu Kompliziert". Ich hoffe mal hier kennt einer das selbe Problem und hat eine Lösung dazu =)

Vielen Dank!
 
Ich habs nur mal kurz überflogen:
Hast du die jeweiligen Methoden beide ausprobiert, ob sie funktionieren?
Und warum schreibst du überhaupt so viel redundanten Code?

Code:
public function getStatusByFtpId($id, $sID, $extMethod) { 

        $sID = call_user_func_array("getServerIDById", array($sID)); 

        if($this->checkServerExist($sID) == true) { 

            $arr = call_user_func_array($extMethod, array($this->ftplist($sID))); 
            foreach($arr as $key => $val) { 
                if($val[id] == $id) return $val[enabled]; 
            } 

        } else { 
            return 0; 
        } 

    }

Könnte beide Funktionen mit einmal ersetzen - kostet dich "nur" ein Argument mehr.

Versuch es mal mit debuggen und prüfe erstmal ab, an welcher Stelle das Script abbricht. Entweder über einen integrierten Debugger in deiner IDE - oder mit ein paar die("Marker<br/>"); - Befehlen im Sinne von:

Code:
public function getStatusByFtpId($id, $sID, $extMethod) { 
die("Marker<br/>");
        $sID = call_user_func_array("getServerIDById", array($sID)); 
die("Marker<br/>");
        if($this->checkServerExist($sID) == true) { 
die("Marker<br/>");
            $arr = call_user_func_array($extMethod, array($this->ftplist($sID))); 
die("Marker<br/>");
            foreach($arr as $key => $val) { 
                if($val[id] == $id) return $val[enabled]; 
            } 
die("Marker<br/>");
        } else { 
            return 0; 
        } 

    }

Dann weißt du zumindest, an welcher Stelle das Script abbricht und kannst besser nachvollziehen, wo der Fehler liegen könnte. Vermutlich beim Aufruf der externen Methode?
 
Hast du die jeweiligen Methoden beide ausprobiert, ob sie funktionieren?
Kommentiere ich den einen Aufruf aus, klappt es, beide Methoden funktionierten 100%ig.

Und warum schreibst du überhaupt so viel redundanten Code?
Weiß ich, ich Lager alles erstmal aus bevor ich es zusammenführe.

Das finde ich ist einfacher ;)
Code:
	public function getUserDataByFtpId($id, $sID, $value) {

		$sID = call_user_func_array("getServerIDById", array($sID));

		if($this->checkServerExist($sID) == true) {

			$arr = call_user_func_array("changeObjectInArray", array($this->ftplist($sID)));
			foreach($arr as $key => $val) {
				if($val[id] == $id) return $val[$value];
			}

		} else {
			return 0;
		}

	}

Entweder über einen integrierten Debugger in deiner IDE
Ich nutze keine IDE, ich nutze den Windows Editor, ich brauch den ganzen kram nicht, zumal ich ja weiß das beide Methoden funktionieren ;)

- oder mit ein paar die("Marker<br/>"); - Befehlen im Sinne von:
Wenn ich da nun ein die setze wird er vermutlich das Script an dieser stelle abbrechen und nicht wenn das Script abbricht mir etwas ausgeben ;)

Vermutlich beim Aufruf der externen Methode?
Das ist korrekt, trage ich das Array Manuell ein, funktionieren beide Methoden zusammen, es liegt an:
PHP:
$arr = call_user_func_array("changeObjectInArray", array($this->ftplist($sID)));

Aber wie bekomme ich das nun gelöst?! Auch wenn ich die Methoden zusammenführe und $value angebe komme ich auf das gleiche Ergebnis - Weiße Seite die nicht vollständig geladen ist.
 
Ich nutze keine IDE, ich nutze den Windows Editor, ich brauch den ganzen kram nicht, zumal ich ja weiß das beide Methoden funktionieren
Etwas hochwertiger als Notepad duerfte es schon sein, ich kann Notepad++ (Syntax-Highlighting, Zusammenklappen von Funktionsbloecken, ...) empfehlen.


Ich verstehe den Sinn dieser Funktion nicht:
Code:
$sID = call_user_func_array("getServerIDById", array($sID));
Waere folgendes nicht aequivalent und bedeutend weniger komplex?
Code:
$sID = getServerIDById($sid);
Zu Beachten ist dass -da alles aus einer Klasse ist- diese Funktionen wahrscheinlich auch aus einer Klasse sind und somit entweder ueber $this->getServerIDById($sid); oder call_user_func_array(array($this,'getServerIDById'),array($sID)); aufgerufen werden muss. Bei fehlender Funktion beendet der Compiler, und da der Funktionsaufruf dynamisch ist kann er es erst beim Ausfuehren und nicht schon beim Bytecode-Compilen feststellen.

Wenn ich da nun ein die setze wird er vermutlich das Script an dieser stelle abbrechen und nicht wenn das Script abbricht mir etwas ausgeben
Das ist die einfachste Form des debuggen. Du setzt eine Marke und kontrollierst ob sie ausgegeben wird. Wenn ja, die Marke unter den naechsten kritischen Bereich setzen oder nach binary search algorithm (immer die Mitte der Zeilen nehmend) verfahren. Sobald die Marke nicht ausgegeben wird weisst du dass die vorige Zeile das Problem darstellt.
 
Ich verstehe den Sinn dieser Funktion nicht:
Code:
$sID = call_user_func_array("getServerIDById", array($sID));
Ich habe für das GSWI verschiedene Tabellen, das eine ist ein Backend in welchem ich die Reseller mit ihren Servern etc. verwalte, die Server selbst weise ich natürlich nicht im Reseller Bereich den Kunden zu sondern in einer eigenen Datenbank, die ID aus der Kundendatenbank entspricht selbstverständlich nicht der ID aus der Reseller Datenbank, die API jedoch braucht die ServerID aus der Reseller Datenbank da dort auch der API Key hinterlegt ist.


Waere folgendes nicht aequivalent und bedeutend weniger komplex?
Code:
$sID = getServerIDById($sid);
Zu Beachten ist dass -da alles aus einer Klasse ist- diese Funktionen wahrscheinlich auch aus einer Klasse sind und somit entweder ueber $this->getServerIDById($sid); oder call_user_func_array(array($this,'getServerIDById'),array($sID)); aufgerufen werden muss.
Natürlich wäre das besser und vorallem weniger Komplex, jedoch handelt es sich hier um eine Function, keine Methode, daher kann ich auch nicht anders darauf referenzieren.

Bei fehlender Funktion beendet der Compiler, und da der Funktionsaufruf dynamisch ist kann er es erst beim Ausfuehren und nicht schon beim Bytecode-Compilen feststellen.
Der Aufruf der externen Funktion klappt ja, einzeln laufen die Methoden ja und liefern genau das was ich will.

Das ist die einfachste Form des debuggen. Du setzt eine Marke und kontrollierst ob sie ausgegeben wird. Wenn ja, die Marke unter den naechsten kritischen Bereich setzen oder nach binary search algorithm (immer die Mitte der Zeilen nehmend) verfahren. Sobald die Marke nicht ausgegeben wird weisst du dass die vorige Zeile das Problem darstellt.
Ahhh, xD

Das habe ich nun Falschrum verstanden :D
 
Das ist die einfachste Form des debuggen. Du setzt eine Marke und kontrollierst ob sie ausgegeben wird. Wenn ja, die Marke unter den naechsten kritischen Bereich setzen oder nach binary search algorithm (immer die Mitte der Zeilen nehmend) verfahren. Sobald die Marke nicht ausgegeben wird weisst du dass die vorige Zeile das Problem darstellt.
Genauso sieht es aus ;)

"Waere folgendes nicht aequivalent und bedeutend weniger komplex?"
Da er auf eine "externe Funktion" setzt, sollte er die sicher nicht anfassen. Er könnte natürlich eine Wrapper-Methode dafür schreiben, aber ob das jetzt Sinn macht sei mal dahingestellt. Für die Übersichtlichkeit auf jeden Fall - funktional sollte es aber vorerst keinen Unterschied machen.

@fragger1991
call_user_func_array("changeObjectInArray", array($this->ftplist($sID)));
Und wo rufst du dort dann "changeObjectArray" auf? Das geschieht in der Methode doch gar nicht?

d4f hat es ja schon angemerkt - ruft er denn überhaupt EINE der beiden externen Methoden korrekt auf? Für mich klang es so, deshalb habe ich das mit dem $this->methodenaufruf erstmal weggelassen als Fehlerquelle. Schien ja zu funktionieren.
Ansonsten wäre es natürlich sinnvoll, die externen Funktionen auch in eine passende Klasse zu stecken und von dort auszuführen.
 
@fragger1991
call_user_func_array("changeObjectInArray", array($this->ftplist($sID)));
Und wo rufst du dort dann "changeObjectArray" auf? Das geschieht in der Methode doch gar nicht?
Doch, die FTP Konten werden als Array- Object mischling abgerufen, in die Function gejagt welche ein Array daraus macht und es an foreach übergibt.

d4f hat es ja schon angemerkt - ruft er denn überhaupt EINE der beiden externen Methoden korrekt auf?
Wie bereits 2x erwähnt, ja tut er, nur nicht zusammen, einzeln klappen diese jedoch schon.
 
Und du bist auch sicher, dass die beiden externen Methoden wirklich fehlerfrei sind?
Hast du dir zwischen den beiden Aufrufen mal angeschaut, wie deine Variableninhalte so aussehen? Nicht, dass da irgendwas schief geht.

Eventuell mal den Variableninhalt NACH dem Aufruf der beiden Methode ausgeben? Läuft das Script nach Aufruf beider Methoden weiter, oder bricht es dort einfach ab?
 
Einzeln klappen die 1000%ig, aber nicht zusammen...

Ich kann die Seite gar nicht mehr wirklich laden, wenn ich beide aufrufen will. Selbst ein echo am Anfang der Datei gibt mir nichts mehr aus.

Innerhalb der Methoden muss ich ja nicht prüfen was da steht wenn das Ergebnis immer exakt das selbe ist wie es in der DB ist kann ich ja definitiv davon ausgehen das die Function fehlerfrei sind, zumal ich diese ja auch außerhalb der Klasse anwende und dort auch keine Probleme habe.

//EDIT:

Meine Function welche das Object Array in ein Array wandelt.

PHP:
function changeObjectInArray($obj) {

	function object2array($obj) {
		$obj = (array)$obj;
		foreach($obj as $key=>$value) {
			if(is_object($value)) $obj[$key] = object2array($value);
		}
  		return $obj;
	}

	$xml = object2array($obj);

	$array = array();

	foreach($xml as $key=>$subobject) {
		if(is_string($subobject)) {
			$array[0][$key] = $subobject;
		} else {
			foreach($subobject as $count=>$value) {
				$array[$count][$key] = $value;
  			}
		}

	}

	return $array;

}

Definiere ich hier nun die Function object2array außerhalb von changeObjectInArray klappt es. Weiß jemand woran das liegt?
 
Last edited by a moderator:
Natürlich wäre das besser und vorallem weniger Komplex, jedoch handelt es sich hier um eine Function, keine Methode, daher kann ich auch nicht anders darauf referenzieren.
Eine Methode ist eine Funktion die in einer Klasse definiert ist und somit nicht eigenstaendig existiert. (Abgesehen vom "Pseudo-Eigenstaendig" klasse::funktion() )

Wenn es eine Methode der oder einer anderen Klasse ist musst du somit wenn du es unbedingt mittels call_user_func_array() aufrufen willst im ersten Parameter ein Array mit dem Klassenobjekt und dem Funktionsnamen angeben. Alternativ $klasse->funktion() (wobei $this eine Referenz auf das eigene Objekt ist)

Falls du die Funktion statisch aufrufen willst und es unbedingt mittels call_user_func_array sein musst du forward_static_call_array() benutzen, die Parameter entsprechen denen von call_user_func_array().

Allerdings werden die beiden genannten Funktionen ausschliesslich genutzt wenn Funktionsname und/oder Paramter dynamisch zu Laufzeit festgelegt werden (zb JIT-Loading von Sub-Klassen)

Definiere ich hier nun die Function object2array außerhalb von changeObjectInArray klappt es. Weiß jemand woran das liegt?
Wenn du eine Funktion in einer Funktion definierst kann diese nur innerhalb dieser Funktion (dessen Scope) benutzt werden; es hat seinen eigenen RAM-Speicher. Allerdings sind Funktionen welche ausserhalb einer Klasser (im 'global' Scope) definiert wurden auch in allen anderen Scopes -innerhalb Funktionen und innerhalb Klassen- abrufbar; sie aehneln damit den PHP-eigenen Funktionen.
 
Eine Methode ist eine Funktion die in einer Klasse definiert ist und somit nicht eigenstaendig existiert. (Abgesehen vom "Pseudo-Eigenstaendig" klasse::funktion() )

Wenn es eine Methode der oder einer anderen Klasse ist musst du somit wenn du es unbedingt mittels call_user_func_array() aufrufen willst im ersten Parameter ein Array mit dem Klassenobjekt und dem Funktionsnamen angeben. Alternativ $klasse->funktion() (wobei $this eine Referenz auf das eigene Objekt ist)

Falls du die Funktion statisch aufrufen willst und es unbedingt mittels call_user_func_array sein musst du forward_static_call_array() benutzen, die Parameter entsprechen denen von call_user_func_array().

Allerdings werden die beiden genannten Funktionen ausschliesslich genutzt wenn Funktionsname und/oder Paramter dynamisch zu Laufzeit festgelegt werden (zb JIT-Loading von Sub-Klassen)
Das ist mir alle wohl soweit bekannt.

Die Klasse würde ziemlich krass aussehen wenn ich das nicht wüsste :P

Wenn du eine Funktion in einer Funktion definierst kann diese nur innerhalb dieser Funktion (dessen Scope) benutzt werden; es hat seinen eigenen RAM-Speicher. Allerdings sind Funktionen welche ausserhalb einer Klasser (im 'global' Scope) definiert wurden auch in allen anderen Scopes -innerhalb Funktionen und innerhalb Klassen- abrufbar; sie aehneln damit den PHP-eigenen Funktionen.
Ist mir ebenfalls bekannt, diese wird ja auch nur innerhalb aufgerufen nicht außerhalb, dennoch Funktionieren beide Aufrufe nun, habe die object2array Function nun ausgelagert.

Die Methode zum Abrufen habe ich nun auch wie folgt gestaltet:
PHP:
	public function getUserDataByFtpId($id, $sID, $value) {

		if($this->checkServerExist($sID) == true) {

			$arr = call_user_func_array("changeObjectInArray", array($this->ftplist($sID)));
			foreach($arr as $key => $val) {
				if($val[id] == $id) return $val[$value];
			}

		} else {
			return 0;
		}

	}
Habe festgestellt das "getServerIDById" dort doch fehl am Platz ist da der Input der korrekten ID entspricht und er es mir somit wieder vertauscht hat, fiel mir allerdings auch erst auf als ich versuchte die Aktion auszuführen :D

Damit klappt nun alles. Vielen Dank an alle beteiligten ;)

P.S. ich stelle fest das Forum ist eine gute Alternative zu dem Layer Ads Forum damals, da gab es ja auch eingeschworene User bzgl. Programmierung etc.
 
Ich weiss nicht wieso du dich so an call_user_func_array klammerst,
aber jedem seine Vorlieben ;) Mit-Entwickler kriegen immer ein Herzinfarkt wenn sie meine ternarischer-Operator-in-ternarischem-Operator Konstruktionen sehen :D

PHP:
 $arr = call_user_func_array("changeObjectInArray", array($this->ftplist($sID)));
Ergibt vereinfacht:
PHP:
$arr = changeObjectInArray($this->ftplist($sID));

ich stelle fest das Forum ist eine gute Alternative zu dem Layer Ads Forum damals, da gab es ja auch eingeschworene User bzgl. Programmierung etc.
In jedem Forum dieser Groessenordnung hast du immer "Spezialisiten" und Tueftler aus so ziemlich allen Bereichen.
Ich bin sicher wenn du jetzt fragst wann genau man Stecklinge eines Rhododendron am besten pflanzen kann wirst du selbst in diesem Forum brauchbare Antworten finden - allerdings auch Hinweise dass du dich im Forum geirrt hast ;)
 
Last edited by a moderator:
Ich weiss nicht wieso du dich so an call_user_func_array klammerst
Weil ich sonst keine Möglichkeit kenne eine Function, welche KEINER Klasse angehört innerhalb einer Klasse in einer Methode aufzurufen.

PHP:
 $arr = call_user_func_array("changeObjectInArray", array($this->ftplist($sID)));
Ergibt vereinfacht:
PHP:
$arr = changeObjectInArray($this->ftplist($sID));
Klar, aber funktioniert ja nicht ;)


Ich bin sicher wenn du jetzt fragst wann genau man Stecklinge eines Rhododendron am besten pflanzen kann wirst du selbst in diesem Forum brauchbare Antworten finden - allerdings auch Hinweise dass du dich im Forum geirrt hast ;)
Die Antwort habe ich bekommen, aber keinen Hinweis :D
Für so was könnte ich allerdings auch meinen Vater fragen, der macht alles rund ums Haus ;)
 
Weil ich sonst keine Möglichkeit kenne eine Function, welche KEINER Klasse angehört innerhalb einer Klasse in einer Methode aufzurufen.
Doch, siehe meine Beitraege oben. Eine im globalen Scope definierte Funktion ist auch in Klassen und anderen Funktionen erreichbar.
Variablen die im globalen Scope liegen koennen uebrigens mit dem Aufruf "global $VARIABLE;" auch fuer Funktionen/Klassen zugaenglich gemacht werden.

Die Antwort habe ich bekommen, aber keinen Hinweis
Ich verweise auf den ersten Google-Eintrag: Link
So :P
 
Back
Top