Funktion mit Array als Return - ERROR
lima-city → Forum → Programmiersprachen → PHP, MySQL & .htaccess
apache
argumentation
array
art
assembler
code
compiler
dienen
fehler
funktion
interpreter
operator
problem
sagen
test
tun
unterschied
url
vermeiden
zeile
-
Hi,
ich habe bereits in einem anderen Post nach einem Fehler gesucht, finde aber, dass ich dem dabei aufgetauchten Problem ein eigenes Thema schenken sollte, zumal es sich hier um ein echtes Problem handelt.
Ich versche in einer PHP-Funktion ein Array zurückzugeben und dieses anschließend außzugeben:
<?php function test($value){ $array = Array(); $array['name'] = 'testname'; $array['passwort'] = 'testpasswort'; $array['value'] = $value; return($array); } echo test('hallo')['password']; ?>
Auf meinem XAMPP localost läuft das problemlos, hier Bei limacity wirft die'echo-line' (also da, wo eben auf das return array zugegriffn wird) einen Fehler aus, der sagt, dass das '[' da nicht hingehört.
Hat jemand eine Ahnung woran das liegen könnte, und viel wichtiger, was man dagegen machen kann??
vielen Dank und liebe Grüße -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage
-
programtools schrieb:
Zwar nicht woran, aber ich habe das hier irgendwie schon öfter mal beobachtet…
Hat jemand eine Ahnung woran das liegen könnte
programtools schrieb:
Ja
und viel wichtiger, was man dagegen machen kann??function test($value){ $array = Array(); $array['name'] = 'testname'; $array['passwort'] = 'testpasswort'; $array['value'] = $value; return($array); } $tmp = test('hallo'); // Hilfsvariable echo $tmp['password'];
-
vermutlich selbes Problem wie bei C:
die ausführungsreihenfolge.
du versuchst auf eine Subskribtion zuzugreifen, die noch nicht da ist, weil der funktionsaufruf erst danach erfolgt.
lösung des problems:
<?php function test($value){ $array = Array(); $array['name'] = 'testname'; $array['passwort'] = 'testpasswort'; $array['value'] = $value; return($array); } $cache = test('hallo'); echo $cache['password']; ?>
ungetestet, aber sollte das problem erschlagen... und nur um eine zeile code zu sparen, sollte man nicht unsauber scripten, denn das fällt dir eines tages auf die Füße...
dass das bei dir zuhause auf dem xampp ging, wundert mich etwas, weil es eigentlich nicht funktionieren darf... der rückgabewert ist ja erst nach funktionsausführung bekannt...
übrigens weiche davon ab, ein array array zu nennen... das sind schlüsselwörter, die man nicht für variablennamen einsetzt. -
Das es bei dir lokal funktioniert, liegt daran, das du eine neuere PHP-Version benutzt (5.4). Hier bei Lima-City ist allerdings immer noch PHP 5.3 im Einsatz.
Die Lösung für dein Problem wurde ja schon gepostet. -
Okay vielen Dank!
ich verstehe nur nicht ganz, wieso das unsauber sein soll.
Ich dachte, er springt beim Funktionsaufruf in die Funktion und die Funktion nimmt anschließend den Wert des Rückgabewertes an und dann mache ich mit dem Arrayaufruf weiter...
Ausserdem ist es so schön schlank und erzeugt keine sinnlose Variable die im Weg rum steht :D
Nur so aus Interesse, denkt Lima darüber nach 5.4 zu Installieren oder sollte ich da die Hoffnung lieber aufgeben?
LG -
Ob das wirklich unsauber ist, darüber lässt sich streiten (wie bei vielen Code-Gestaltungen).
Ich werde es nicht benutzen, aber es ist logisch was gemeint ist und nicht schwer zu lesen.
Unsauber finde ich z.B. diesen Ternären Operator, besonders wenn man sowas auch noch verschachtelt...
Irgendwann wird 5.4 sicher kommen, aber das wird wohl noch einige Zeit dauern. Vor gut einem Jahr wurde erst auf 5.3 umgestellt. -
der ternäre operator ist sauber, nur hässlich zu lesen...
mit unsauber meine ich einfach, dass gerade in PHP, wo datentypen nicht explizit(außer beim array) von vornherein angegeben werden, auf den Rückgabewert einer Funktion(welcher erst durch das angesprungene return definiert ist) ein Operator gesetzt wird, der diesem Datentyp eigen ist.
Mit dem sauber/unsauber bekommt man auch erst mit, wenn man mehrere Programmiersprachen anwendet und dann zwischen denen switcht und sich dreckige Angewohnheiten geholt hat (die zudem nur für das Codebild förderlich sind, jedoch kaum für die Ausführungszeit...). wer eine Hochsprache beherrscht, wird das schon verstehen, wer nicht und wer sich dafür nicht interessiert und der meinung ist, kurzer code impliziert geringe Ausführungszeit, braucht ab hier nicht weiter lesen...
Spätestens wenn in PHP möglich wird, einen Operator(und Funktionen) zu überladen, werdet ihr feststellen, warum diese Code-Zeile unsauber ist. Nicht alles was möglich ist und irgendwie funktioniert, ist sauberes Programmieren. Wer schonmal in C/C++ programmiert hat, und somit den Computer nicht als Blackbox verwendet hat, sondern auch weiß, was drinnen vorgeht, wird meine Argumentationsweise verstehen.
Wer das nicht getan hat, sollte sich dahingehend informieren, was der Unterschied zwischen Interpreter und Compiler ist, was dahinter steht und warum mancher Code schneller ausgeführt wird als anderer... obwohl dasselbe passiert... (wer nen Compiler bereits verwendet hat, kennt bestimmt das lustige debug fenster, mit dem man die asm-Anweisungen lesen kann...)
--------------------------------------
das ist eine temporäre Variable, die nicht im weg rumsteht. Wenn du sie nicht grad in die session schreibst, verschwindet die nach scriptausführung... ansonsten mach ein unset drauf danach... das wär übrigens auch sauber, macht aber keiner... zumal ich grad nicht weiß, ob PHP das array über ein unset am stück behandelt, oder ob du über eine foreach jedes element einzeln ansprechen musst(wie es in C der fall ist, wenn du deine eigene array/string) klasse verwendest...
und es kann passieren, dass wenn du, wie in diesem fall 1 zeile im Code sparst, dem interpreter 20 instruktionen oder so mehr aufdrückst, die er ausführen muss...
bei 100 leuten macht sich das noch nicht all zu sehr bemerkbar, aber mach das mal in ein projekt, wo 5-6 stellig leute zugreifen täglich...
du kannst ja beides mal bei dir auf dem xampp zuhause testen, welche variante mehr ausführungszeit erfordert... simuliere einfach mal 10000 durchläufe und stoppe die Zeit... nimm 2 mal microtime() (vorher + nachher) und subtrahiere... dann bekommst du ein genaueres ergebnis als mit der hand zu stoppen...
Beitrag zuletzt geändert: 26.10.2012 9:17:04 von sebulon -
Hi, Danke erstmal an die sehr ausführlichen Beiträge!
@sebulon
Ich bin mir nicht ganz sicher ob ich richtig verstanden habe, was du meinst.
Performance technisch sollte es doch keinen Unterschied geben, ob ich jetzt erst in eine variable zwischenspeicher oder nicht?
Und die verwendung einer Funktion an dieser Stelle hat nicht nur optische Gründe (obwohl ich sagen muss, das ich es vom Aussehen so schon recht schick und übersichtlich finde), sondern gibt mir ja die Möglichkeit große / oft wiederholende, parameterabhängige Rechnereien nicht nur auszulagern sondern kann ich hier zB auch die ergebnisse cachen und bei einem erneuten Aufruf schauen, ob das Ergebniss bereits vorliegt.
MFG
-
PHP ist eine SCRIPT-Sprache und wird interpretiert. Des Weiteren ist Apache, der Webserver, welcher den PHP-Code interpretiert, in C gechrieben. das heißt, dass eine Funktion hinterlegt sein muss, um diese Flexible Datenhaltung zu ermöglichen. Die Art ausdruck, wie du sie verwendest, würde in C einen L-Value-fehler produzieren. demzufolge muss ein workaround angesteuert werden, um diesen fehler zu vermeiden. das witzige ist, im Apache würde er auch eine Cache-variable anlegen(zumindest würde ich es so lösen),ab version 5.4, weil es anders nicht geht. Zwar sind die Methoden durch den Rückgabewert definiert, aber jeder Compiler, den ich kenne, lässt es einfach nicht zu.
und da du nicht wießt(und ich auch nicht) wie dieser Workaround gecoded ist und wie effektiv er ist, ist es immer besser, fehlerquelen in der Instanz drunter zu vermeiden und den Weg sauber zu beschreiten. Nur weil die Scriptsprache etwas zuläst, heißt es nicht, dass der Interpreter das auch effektiv umsetzt... kann man nur durch einen Laufzeittest herausfinden. -
sebulon schrieb:
Kennst du die Programmiersprache Java? Hast du dort mal versucht ein solches Konstrukt zu verwenden? Wie sieht es in JavaScript aus? Was ist mit jQuery, wo ein Objekt zurückgegeben wird, das du direkt weiterverwendest und nicht zwischenspeicherst, also so verwendest:
… aber jeder Compiler, den ich kenne, lässt es einfach nicht zu.funktion().f1().f2(wert).f3('bla');
Das ist in meinen Augen das gleiche wie die Sache mit dem Array in PHP…
sebulon schrieb:
Was hat PHP mit Apache zu tun? Nichts! PHP kann zufällig vom Apache an den PHP-Interpreter "weitergeleitet" werden. Mit der Ausführung von PHP durch den Interpreter hat der Apache aber (fast) nichts zu tun.
PHP ist eine SCRIPT-Sprache und wird interpretiert. Des Weiteren ist Apache, der Webserver, welcher den PHP-Code interpretiert, in C gechrieben. das heißt, dass eine Funktion hinterlegt sein muss, um diese Flexible Datenhaltung zu ermöglichen. Die Art ausdruck, wie du sie verwendest, würde in C einen L-Value-fehler produzieren. demzufolge muss ein workaround angesteuert werden, um diesen fehler zu vermeiden. das witzige ist, im Apache würde er auch eine Cache-variable anlegen(zumindest würde ich es so lösen),ab version 5.4, weil es anders nicht geht.
Wie kommst du auf die Idee, dass es eine Zwischenvariable braucht? Du hast den Wert bereits in einer Variablen (z.B. am Stapel), wenn er aus der Funktion zurückgegeben wird. Eine weitere temporäre Variable brauchst du deshalb nicht.
Auch wenn das mit C nicht möglich ist, in Assembler funktioniert es
Beitrag zuletzt geändert: 29.10.2012 10:14:30 von hackyourlife -
hackyourlife schrieb:
Auch wenn das mit C nicht möglich ist, in Assembler funktioniert es
1. welcher Webserver wird hier verwendet? folglich wird welcher Interpreter verwendet? Worauf basiert das
2. Warum ist Java nur 1/5 so schnell wie C++?
3. Was hat das Interpretieren hier mit Java zu tun?
nur weil in anderen Programmiersprachen andere Konstruktionen möglich sind, muss es nicht zwangläufig hier gehen.
dass es in assembler so geht ist das natürlichste der Welt, weil du quasi dein eigener Compiler bist...
und jetzt willst du tatsächlich kein Compiler(asm) mit Compiler(c/c++) mit JIT/IL-Compiler(JAVA) vergleichen? du merkst schon, dass das mehr als unangemessen ist?
ist genauso als würde ich sagen: ich kann 300kg schwere Hanteln stemmen, aber nur auf dem Mond... ist dasselbe... du kannst dienen Webserver ja gerne in Java schreiben, müch würde interessieren, bei wie vielen Usern der zusammenbricht... Ich hoffe, du stimmst mit mir überein, dass die Progammiersprachen unterschiedliche bereiche haben auf denen sie stark sind, und warum der PHP-Interpreter in C geschrieben ist und nicht in Java leuchtet hoffentlich auch ein... -
Schön langsam wirds hier etwas Off-topic, aber trotzdem:
sebulon schrieb:
In Assembler würdest du die Funktionsweise sehen, die ich dir versucht habe zu beschreiben.
hackyourlife schrieb:
1. welcher Webserver wird hier verwendet? folglich wird welcher Interpreter verwendet? Worauf basiert das
Auch wenn das mit C nicht möglich ist, in Assembler funktioniert es
…
dass es in assembler so geht ist das natürlichste der Welt, weil du quasi dein eigener Compiler bist...
1) Die Funktion wird aufgerufen
2) Die Funktion baut sich irgendwie einen Rückgabewert zusammen
3) Wie wird nun dieser Rückgabewert in die aufrufende Funktion übertragen? Mit Magie?
Die Funktion wird den Rückgabewert irgendwo ablegen. Die aufrufende Funktion wird dann auf diesen Speicher zugreifen und den Wert von dort weiterverwenden.
Erkennst du jetzt die Ähnlichkeit zu der von dir aufgestellten Behauptung, dass du für
eine temporäre Variable brauchst? Die brauchst du egal wie, ob du sie jetzt noch in einfunktion()[7]
kopierst ($irgendwas
) oder nicht… einen Workaround wie du es nennst brauchst du hingegen nicht$irgendwas = funktion();echo($irgendwas[7]);
sebulon schrieb:
Und warum ist PHP immernoch langsamer als Java? Wer hat hier jemals von C++ gesprochen?
2. Warum ist Java nur 1/5 so schnell wie C++?
3. Was hat das Interpretieren hier mit Java zu tun?
[…]
und jetzt willst du tatsächlich kein Compiler(asm) mit Compiler(c/c++) mit JIT/IL-Compiler(JAVA) vergleichen? du merkst schon, dass das mehr als unangemessen ist?
Ich will gar nichts
Schau dir lieber diesen Code an, das ist das was ich mit dem Java-Vergleich gemeint habe:public class sebulon { public static int[] funktion(int x) { return new int[] { x, 2 * x, 3 * x }; } public static void main(String[] args) { // mit temporärer Variable int[] tmp = funktion(1); System.out.println(tmp[1]); // ohne temporärer Variable System.out.println(funktion(2)[1]); } }
Da du C++ erwähnt hast gleich noch ein weiteres Beispiel (ob der Code gut ist oder nicht ist hier völlig egal; ja, ich weiß, dass man das so nicht macht):#include <iostream> using namespace std; int* funktion() { int* array = new int[3]; array[0] = 1; array[1] = 2; array[2] = 3; return array; } int main(int argc, char** argv) { int* array1 = funktion(); cout << array1[1] << endl; // mit tmp cout << funktion()[2] << endl; // ohne tmp return 0; }
Wie war das doch hier noch?… aber jeder Compiler, den ich kenne, lässt es einfach nicht zu.
sebulon schrieb:
Interessanterweise gibt es das sogar: Jetty, Tomcat, … um nur die frei verfügbaren zu nennen. Möglicherweise erkennst du jetzt auch schon in welche Richtung das geht: große Anwendungen die auf Java basieren und mitunter auch auf Mainframes laufen. Wie viele Benutzer es braucht bis das zusammenbricht kannst du dir ja selbst ausrechnen
du kannst dienen Webserver ja gerne in Java schreiben, müch würde interessieren, bei wie vielen Usern der zusammenbricht... -
du hast ein argument von mir völlig ignoriert: der vordefinierte Rückgabewert. Ist bei PHP nicht realisiert. deswegen workaround, über die anderen Punkte brauche ich mit dir nicht zu diskutieren, da du meine Posts anscheinend nicht richtig liest, sondern praxisfern was anderes dazu erzählst...
und tomcat hat mit PHP wohl nix am hut... hier gings um die Interpretation von PHP und nicht JSP/servlets... aber es hat in deine argumentation grad gut reingepasst, gell?
das asm den rückgabewert direkt im stack hat wieß ich selbst, dachte eigentlich, dass ich das klar ausgedrückt hätte... demzufolge ist deine argumentation dazu überflüssig...
und wegen der zwischenvariable hängts ganz einfach mit dem typ zusammen, die funktion könnte genau so gut nen string zurückliefern, obwohl du ein assoc-array erwartest... dann hab mal dienen spaß damit... deswegen brauchst du auf interpreterebene einen workaround...
und JAVA kannst du nciht als vergleich liefern, weil bei Java der Rückgabetyp vordefiniert ist...
C++ ist der rückgabetyp vordefiniert. wo ist er nicht vordefiniert?
richtig, PHP... und warum geht das so nicht? weil wir zwar eine rückgabe haben, aber wir nicht wissen welchen typs, um damit sinnvoll arbeitne zu können... anhand des Typs definiert sich die menge ausführbarer funktionen(Subscriptionsoperator ist durch eine Funktion hinterlegt, da stimmst du mir hoffentlich zu)
und es ging um C compiler... somit ist diene ganze argumentation wacklig, weil du auf die gesamtmenge der compiler spekuliert hast und nicht auf die betroffene kategorie...
wär dasselbe als würdest dubehaupten, du kannst kein auto mit mehr als 2t zuladen, weil das dann die Hufe breit macht und ich erzähl dir vom 40Tommer, wo du das 10fache ohne probleme reinpacken kannst... das wäre haargenau dasselbe... naja, damit klinke ich mich aus der Diskussion aus, egal was für ein murks hier noch entsteht... ich persönlich mag die art diskussion nicht, wo irgendwelche halbstudierten der meinung sind aufgrund ihres studiums sich einfach nur die situation anpassen, wie sie es brauchen, um die passende Argumentation zu bekommen und schließlich und letztendlich sind wir fernab vom ausgangsproblem um das es eigentlich ging.
ich will damit nciht sagen, dass du falsch liegst, ganz und gar nicht, ich will damit nur sagen, dass du dir die argumentation zurechtbiegst, damit es so passt und mich mit binsenweisheiten überhäufst, in dem glauben ich hätte davon noch nie was gehört... -
Ich muss sagen es ist schon recht interessant, allerdings interessiert mich die Sache mit dem Workaround.
sebulon schrieb:
PHP ist eine SCRIPT-Sprache und wird interpretiert. Des Weiteren ist Apache, der Webserver, welcher den PHP-Code interpretiert, in C gechrieben. das heißt, dass eine Funktion hinterlegt sein muss, um diese Flexible Datenhaltung zu ermöglichen. Die Art ausdruck, wie du sie verwendest, würde in C einen L-Value-fehler produzieren. demzufolge muss ein workaround angesteuert werden, um diesen fehler zu vermeiden. das witzige ist, im Apache würde er auch eine Cache-variable anlegen(zumindest würde ich es so lösen),ab version 5.4, weil es anders nicht geht. Zwar sind die Methoden durch den Rückgabewert definiert, aber jeder Compiler, den ich kenne, lässt es einfach nicht zu.
und da du nicht wießt(und ich auch nicht) wie dieser Workaround gecoded ist und wie effektiv er ist, ist es immer besser, fehlerquelen in der Instanz drunter zu vermeiden und den Weg sauber zu beschreiten. Nur weil die Scriptsprache etwas zuläst, heißt es nicht, dass der Interpreter das auch effektiv umsetzt... kann man nur durch einen Laufzeittest herausfinden.
Klar PHP ist eine Scriptsprache und muss daher (ob von c oder Java compiler sollte hier einmal ausser Acht gelassen werden) interpretiert werden. Ich frage mich jedoch, wo jetzt genau der Unterschied liegt zwischen
1) ich nutze in PHP eine $cache Variable
und
2) der Interpreten nutzt (in seinem 'Workaround') eine cache Variable.
Das sollte doch auf das Gleiche hinaus laufen?
MFG
-
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage