krieg die Krise mit dem require_once

dg87

Erfahrenes Mitglied
Hi,

jetzt muss ich mich doch nochmal ans Forum wenden.
Ich bekomme ständig die Meldung:
Code:
Warning: include(../includes/db_const.php) [function.include]: failed to open stream: No such file or directory in I:\Web\cdproject\appl\db\dbfactory.php on line 9

Warning: include() [function.include]: Failed opening '../includes/db_const.php' for inclusion (include_path='.;C:\xampp\php\PEAR;I:\web') in I:\Web\cdproject\appl\db\dbfactory.php on line 9
Konstante sind nicht verfügbar

Ja, er kann die Datei nicht öfffnen, weil am Pfad was nicht passt.
Hier mal die Ordnerstruktur:
Code:
cdproject
               - index.php
               - appl
                        - db
                                - dbfactory.php
                        - includes
                                - dbconst.php
Die index.php lädt übe require_once die dbfactory.php. Und die dbfactory.php lädt die dbconst.php.

dbfactory.php:
Code:
require_once('../includes/dbconst.php');

index.php
Code:
require_once("./appl/db/dbfactory.php");


Was mache ich falsch?

DAnke
 
Grüße,
das Problem an der Sache ist, dass du die dbfactory.php ja in die index.php integrierst.
Solltest du jetzt in deiner dbfactory.php etwas wiederum integrieren wollen, dann geht das aufgrund der Integration in die index.php auch von der Ebene dieser Datei aus.
Du benötigst also im Prinzip die gleiche Struktur wie bei der dbfactory.php:

Code:
require_once('./appl/includes/dbconst.php');
 
Ich sollte wohl doch mit autoloader arbeiten :-)
Wenn ich das jetzt machen würde, muss ich dann bei jeder Datei einmal den Autoloader registrieren oder?

Andernfalls sollte ich dann die requires immer bei der Datei machen, wo die Klassen erstellt werden und nicht bei der klasse selber...


Edit:
Ist es dann immer so, dass ich die Dateien da includieren muss, wo sie auch aufgerufen werden? Weil genau dieses obige Beispiel sagt ja eigentlich aus, dass es nur so geht oder? Weil dann ist es ja schwachsinn, wenn meine Klassendateien wie die DBFactory etwas included, obwohl sie selbst in der index.php includiert wird.
Außer der Request fällt auf die DBFAchtory.php selbst, dann würde es logischerweise gehen, right?
 
Zuletzt bearbeitet:
Jetzt lässt mich das Beispiel von oben nicht in Ruhe. Bleiben wir mal dabei dass ich ohne autoloader arbeite. Kann ich den require nicht irgendwie in der Factory lassen? Ich will dass von der Factory aus die Dbkonst.php geladen wird weil Sie da auch benutzt glaub mit der function dir(_FILE_) könnte das klappen oder?
Warum das ganze? Weil ich nicht alle require in der Index Datei haben will sondern da wo Sie logischerweise hingehören. Oder gut das nicht? Bitte keine Tipps wie man es anders bauen soll.

Ganz kurz die Frage: wie müsste ich den require bauen dass er auch von der dbfactory aus funktioniert ? Muss ja fast dynamisch gemacht werden weil ja nicht unbedingt nur von der Index Datei zugegriffen wird, also nicht einfach sagen ja dann setz den Pfad halt von der Index Datei aus da rein, dann klappt's auch****
 
Du willst jetzt die dbconst.php mit der dbfactory.php einbinden?

Dafür gibt es auch die magischen Konstante __DIR__:
PHP:
$ds = DIRECTORY_SEPARATOR;
require_once( __DIR__.$ds.'..'.$ds.'includes'.$ds.'dbconst.php');

Hier ist mal ein Artikel über verschachtelte Includes: yaslaw.info.


Wenn ich das jetzt machen würde, muss ich dann bei jeder Datei einmal den Autoloader registrieren oder?
Nein, du musst nur einmal global die Funktion __autoload() definieren.

Ich würde empfehlen du setzt in der index.php diese Konstante:
PHP:
define('PROJ_ROOT', __DIR__);
Dann würde obiges Beispiel so aussehen:
PHP:
$ds = DIRECTORY_SEPARATOR;
require_once( PROJ_ROOT.$ds.'appl'.$ds.'includes'.'dbconst.php');
 
Ich Teste das nochmal ich wil halt ned dass die dbconst.php in der Index.php steht aber sonst kommt ja die Meldung wie ganz oben. Der Pfad stimmte ja nicht weil der Request auf die Index.php geht. Ich will dass alles so bleibt aber der entsprechende include in der dbfactory bleibt

(ohne autolader erstmal)

Aber sonst muss ich ja immer die dbconst.php.php einbinden wenn ich auf die dbfactory greife. Deshalb will ich dass die Dbkonst in der Factory included wird damit das entfallt.
 
Zuletzt bearbeitet:
Teste mal meine Variante #1. Diese fügst du in die dbfactory.php ein.

Das __DIR__ wird zu '.../db' aufgelöst und durch die zwei Punkte '..' wird eine Stufe in der Hierarchie "höhergesprungen".

PS: Ich hatte auch schonmal solche Probleme, v.a. mit __autoload() und Namespaces. Da bekommt echt die Krise ;)
 
Habs grad getest, das klappt ja wunderbar. Sogar wenn ich die DBfactory von einer anderen Datei aus einbinde, die nicht in der Höhe von der index.php ist, funktioniert es.
Jetzt muss ich mir nur noch ansehen warum es funktioniert. Aber dazu werde ich mir deinen Link anschauen. Aber auf den ersten Blick siehts so aus, als würde es deshalb immer funktoinieren, weil der Pfad komplett immer zur Datei angegeben ist, also zB I:\Web\cdproject\appl\includes\dbconst.php
Denke ich oder :-)

Dann mache ich doch am besten immer so, dass ich die includes bzw requires dynamisch halte (wie es bei anderen projekten ja auch der fall ist, was ich gesehen hab)

PS: autloader mach ich ja nicht ,aber wenn, dann kann man ja in der php.ini eine Datei angeben, die immer am anfang geladen wird, dann würd ich da den loader reinmachen. ich will aber erstmal ohne Autoloader arbeiten, um eben sowas zu lernen :_)

Edit: steht ja eigentlich super in dem Link :)

DAnke dir nochmal
 
Jetzt muss ich mir nur noch ansehen warum es funktioniert.
Normalerweise verändert sich der Ausgangspfad bei verschachtelten [phpf]require[/phpf]'s oder [phpf]include[/phpf]'s.
Deshalb muss man statt einem relativen Pfad ('../includes/dbconst.php') einen absoluten nehmen ('I:\Web\cdproject\appl\includes\dbconst.php').
Genau dann kann man Gebrauch von der magischen Konstante __DIR__ machen. Sie ist "magisch", da der Inhalt sich je nach Verwendungsort ändert. __DIR__ enthält nun den Ordner der Datei, in der es steht:
php.net hat gesagt.:
The directory of the file. If used inside an include, the directory of the included file is returned. This is equivalent to dirname(__FILE__). This directory name does not have a trailing slash unless it is the root directory. (Added in PHP 5.3.0.)

Dann können wir relativ zu diesem (absoluten) Pfad den Dateinamen der dbconst.php angeben.

Dann mache ich doch am besten immer so, dass ich die includes bzw requires dynamisch halte (wie es bei anderen projekten ja auch der fall ist, was ich gesehen hab)
Schadet auf jeden Fall nicht. Allerdings würde ich eher eine Konstante wie PROJ_ROOT wie in meinem Beispiel verwenden.
Ich finde, dass der Pfad dann eindeutiger wirkt. Naja das ist meine subjektive Meinung.
PHP:
require_once( PROJ_ROOT . DS . 'includes' . DS . 'dbconst.php' );
/* oder */
require_once( __DIR__ . DS . '..' . 'includes' . DS . 'dbconst.php' );
Ein weiterer Vorteil vom zweiten Befehl ist, dass er immer noch funktioniert, wenn du die Datei ('dbfactory.php') verschiebst.
 
Zurück