Verständnis für Logik ...

Hi,

in der autoinclude von IPS gibt’s Zeilen wie:


if(file_exists(IPS_GetKernelDir()."\\scripts\\__ipsmodule.inc.php")) 
	require_once(IPS_GetKernelDir()."\\scripts\\__ipsmodule.inc.php");

Irgendwie fehlt mir wohl das tiefe Wissen über PHP, um zu verstehen, warum man, nach erfolgreicher Abfrage ob eine Datei denn existiert, dann noch mit require statt iclude arbeitet. Ins besondere, wenn man offensichtlich (dafür das „if“) auch „ohne“ leben kann …

Ich würde gerne dazu lernen. Was ist der Grund?

Die Abfrage bedeutet einfach das wenn die Datei nicht vorhanden ist auch kein Fehler ausgeworfen wird.

Warum hier genau ein require anstatt eines includes genommen wurde könnte vielleicht mit der Art des Fehlerhandling beider Befehle zusammenhängen.

require entspricht im Wesentlichen include, wirft aber im Fehlerfall einen E_COMPILE_ERROR Fehler. Es beendet also die Programmausführung während include nur eine Warnung (E_WARNING) generiert und so die weitere Programmausführung gestattet.

Naja, genau darauf zielt ja meine Frage ab:

Oberflächlich könnte man monieren „doppelt gemoppelt“ (oder sogar: beim Überarbeiten nicht aufgepasst?). Aber vielleicht gibt’s ja einen Sinn.

Ne, warum?

ENTWEDER es wird etwas zwingend gebraucht, dann nehme ich require (–> Abbruch, wenn nicht da) ODER es wird nicht gebraucht, dann nehme ich ein include. Zusätzlich zum include kann ich, um eine Meldung zu vermeiden, davor noch abfragen ob die Datei existiert.

WENN ich aber an eine Codezeile gar nicht komme, in der ein require steht (wegen der vorherigen Prüfung) ist das require auch überflüssig („and misleading“ wie der Ami sagt)

Es sei denn im „Erfolgsfalle“, also die Datei existiert, spricht etwas für require - z.B. Ladezeiten oder sonstwas …

[edit]
genau genommen könnten sich die Code-Zeilen sogar konterkarieren:

  • Es ist nicht nötig, die Datei zu laden .
  • Sie existiert noch, wenn der Check stattfindet, wird aber gerade gelöscht
  • dann bricht require ab, obwohl die Datei nicht zwingend gebraucht wird!

Hi,

es handelt sich hier um eine optionalle Datei für IP-Symcon - wenn vorhanden, dann bitte laden.
Da vorher bereits ein Check stattgefunden hat, wird die Datei mit Require eingebunden und es erfogt ein fatal Error sollte die Datei nicht da sein (was ja fast nicht mehr vorkommen kann)!

Stackoverflow ist immer für eine Erklärung gut:
http://stackoverflow.com/questions/2418473/when-should-i-use-require-once-vs-include

Vielleicht vorweg: Ich habe durchaus den Unterschied zwischen include, include_once, require und require_once verstanden.

Es geht mir hier mehr darum, zu verstehen, wie IPS Code schreibt und ob es da vielleicht tiefes Wissen gibt, das mir noch fehlt.

Nach allem, was hier geschrieben wurde ist der code im autoinclude nämlich einfach schlecht, weil das require_once auf eine Notwendigkeit des includierten code hinweist, was er aber - das zeigt die if vornedran - gar nicht ist.

WENN also der tatsächlich einzige Unterschied darin besteht, dass require abbricht und include weiter macht (und die IPS Leute nicht anderen Hintergrund haben), sollte im code include_once verwendet werden.

Die „if“ verhindert dann Fehlermeldungen, was, in Anlehnung an viele Dokuteile für IPS-eigene Funktionen, die ggf. Fehlermeldungen werfen, aber stringenterweise besser mit @include_once geschehen würde.

Ich glaub wir reden wieder mal aneinander vorbei, keine Ahnung, wo Du hier ein Problem siehst.
Für mich geht der Code in Ordnung - Check Datei vorhanden, wenn ja include mit require (da im Fehlerfall ein Programmierfehler vorliegen muss).
Eventuell habe wir auch nur ein anderes Verständnis für Errorhandling …

Dieser Code lässt keinen Fehler entstehen:

if(file_exists(IPS_GetKernelDir()."\\scripts\\__ipsmodule.inc.php"))  
    require_once(IPS_GetKernelDir()."\\scripts\\__ipsmodule.inc.php");

Dieser Code unterdrückt den Fehler nur, er entsteht aber:

@require_once(IPS_GetKernelDir()."\\scripts\\__ipsmodule.inc.php");

Der erste Code unterscheidet einen Programmierer vom Bastler. Fehler müssen bei akkurater Programmierung abgefangen werden und nicht unterdrückt werden. PHP liefert dafür spezielle Error Handler.

Gruß

… und um ganz genau zu sein, braucht der akkurate Programmierer an dieser Stelle kein ‚require_once‘, sondern nur ein ‚require‘, denn er weiss ganz genau, dass er die entsprechende Datei nicht schon vorher ‚required‘ hat.

‚require_once‘ ist in der Ausfuehrung ‚teurer‘ als ‚require‘, denn es findet eine (in diesem Fall ueberfluessige) Pruefung statt, ob die Datei schon geladen wurde ist oder nicht.

In stark verzweigten Projekten verhindert require_once, dass Programmteile doppelt in den Speicher gelegt werden.

Wenn eine Programmbibliothek von einem PHP Script verwendet wird und beide, das Script und die Bibliothek, eine dritte Datei benötigen, dann würde sie mit require innerhalb eines Prozesses doppelt in den Speicher geladen. Einmal vom Script und einmal von der Bibliothek. require_once verhindert das weil es nur unnötig Speicher belegen würde.

Teil zwei der Frage lautet also eigentlich nur noch macht es Sinn eine Datei nur zu laden wenn es sie auch wirklich gibt. Gegenfrage: Macht es denn Sinn wenn sie nicht vorhanden ist?

Hier hat der Autor beschlossen dass an dieser Stelle keine Fehlermeldung geworfen werden soll. Entweder weil sie eh nicht aussagekräftig wäre, vielleicht möchte er an anderer Stelle statt unverständlichem PHP eine Meldung auf Deutsch oder Englisch erzeugen, vielleicht weil sie nur einmal geworfen werden soll und nicht 30 mal, vielleicht weil sie statt in den User-Browser (PHP ist ja eigentlich für Webseiten) an anderer Stelle in ein Server-Log geschrieben werden soll oder vielleicht ist der Inhalt dieser Datei sogar optional und der Autor reagiert darauf in einer Art „Fallback“. Kann man so nicht sagen.

Gruß,

Toni

Über „teuer“ müssen wir hier (leider, leider) ob der unsäglichen compatibility.php (73k!) seit 3.0 nicht reden.

Die ist m.E. ein Desaster. Wie kann man nur X if-Abfragen machen (die alle und immer ausgeführt werden), wenn man dasselbe mit einer einzigen (bzw. in diesem Falle ggf. 3) if-Abfrage(n) der Versionsnummer erschlagen könnte, um dann ggf. weitere und nötige includes zu laden?

Ich drück’ die Daumen, dass der interne IPS Code nicht auch so ist …

Der code ist sehr flexibel. Es ist nicht zu erwarten, dass er in Zukunft sehr viel Pflege braucht. Klar könnte man auch eine Version des Funktionsumfang der 3.0 in Beton meisseln. Und eine Weitere für die 3.1, die 3.1.1 und #2978 und die Patches aus #2990 :rolleyes:

Dazu kommt, dass die Rechner heute so schnell sind und Entwicklungszeit so teuer.

@Toni, Exchange, Axbigo und Brownson

Danke für Eure sachlichen Beiträge, es ist immer wieder schön zu sehen, dass man Polemik auch auf sachlicher Ebene entgegentreten kann. Gefällt mir gut, bei Euren Beiträgen lerne ich etwas über programmieren.

Und…ich habe herzlich gelacht. :smiley:

Kann man so nicht sagen.

Kann nur der Autor oder eben jemand, der „mehr weiss“. Genau deshalb habe ich die Frage gestellt.

Denn wie axbigo schon dargestellt hat, wäre - wenn denn - ein require völlig ausreichend, denn wir befinden uns VOR dem UserScript in der Autoinclude, der ersten Datei, die abgearbeitet wird und „Property“ von IPS ist.

Um noch einen drauf zu setzen: ich behaupte, dass ein include reichen würde (und im Sinn dann auch nicht irreführend wäre), denn:

Selbst im unwahrscheinlichen Falle einer „race condition“ - dass zwischen Interpretation des "file_exist) und include die Datei gelöscht wird - gibt’s noch keinen Grund, dann auszusteigen, denn beim nächsten Scriptaufruf, z.B. wenn ein Timer das Script jede Sekunde startet, würde wieder alles „normal“ abgearbeitet.

So, wie es im Moment steht, gaukelt das require eine Notwendigkeit vor, die nicht gegeben ist.

@wupperi: Netter Versuch, vom Thema abzulenken.

jemand, der „mehr weiss“

Als Jemand, der seit über 10 Jahren anderen Leuten versucht „gutes Programmieren“ beizubringen möchte ich es nochmal ganz kurz so zusammen fassen: Es ist piep-strunzen-egal

Es ist die Zeit nicht wert sich länger als 15 Sekunden drüber Gedanken zu machen.

Ich sehe es wie Tonic1024 und die anderen:

Jo, besser hätte ich es auch nicht sagen können :rolleyes:

Zusammenfassung meinerseits auch wenn’s gegen die heilige Kuh geht:

Es ist einfach schwacher Code. Daran ändern auch die Rechnergeschwindigkeiten nix.

Wer ordentlich recherchiert wird auch finden, dass file_exist() z.B. gar nicht ausreicht, um das sicher zu stellen, was die Absicht war. Denn es ist auch bei file_exist=true nicht sicher, dass die Datei auch gelesen werden kann.

Man hätte auch einfach @include nutzen können und damit den der tatsächlichen Bedeutung der Datei entsprechenden Befehl benutzt: optional.

p.s.: Es wird viel diskutiert was keine 15 Sekunden Beschäftigung Wert ist. Die Bewertung darüber liegt im Auge des Betrachters. Gegen ein Aufarbeiten und möglicherweise Lernen, spricht m.E. nie etwas.

Gegen lernen hat niemand etwas, und heilige Kühe gibt es hier nicht. Ich würde aber darauf tippen, dass die Art und Weise wie kommunziert wird eher das Problem ist.

In diesem Sinne sollten wir diesen thread dann hier beenden.