General Error - Illegal use of $_SERVER

In diesem Forum gibt es Starthilfe zum neuen Extension-System von phpBB 3.1/3.2. Fragen zur Entwicklung von Extensions und zur Konvertierung von phpBB 3.0.x MODs sind ebenfalls willkommen.
uwe.ha
Mitglied
Beiträge: 838
Registriert: 18.05.2001 02:00

General Error - Illegal use of $_SERVER

Beitrag von uwe.ha »

Hallo zusammen,

ich habe vor ein paar Jahren was "gebastelt", deshalb frag ich hier in der Bastelstube ;-)

Ich habe eine Seite; Content + Forum (phpbb3.0).
Auf den Contentseiten (also außerhalb, bzw. eine Ebene oberhalb des Forums) hatte ich "aktuelle Themen" und (zum Content der Seite) "ähnliche Beiträge" (similar) aus dem Forum angezeigt.

Für die beiden Funktionen habe ich im root des Forums (Ordner phpBB) jeweils eine separate Datei angelegt (aktuelle-themen.inc.php und similar.inc.php). Die similar.inc.php sieht z.B. am Anfang und Ende so aus:

Code: Alles auswählen

<?php
define('IN_PHPBB', true);
$phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './';
$phpEx = substr(strrchr(__FILE__, '.'), 1);
include_once($phpbb_root_path . 'common.' . $phpEx);

// Start session management
@$user->session_begin();
$auth->acl($user->data);
$user->setup();

// Begin Precise Similar Topics
    $sql_array = array(
       'SELECT'   => 'f.forum_id, f.forum_name, t.topic_id, t.topic_title, t.topic_time, MATCH (t.topic_title) AGAINST (\'' . $db->sql_escape($keyword) . '\' ) as score',

[...]

    $template->set_filenames(array(
        'body' => 'similar-content.html',
    ));

    $template->display('body');
//	page_footer();
?>
In den Contentdateien werden diese Funktions-Dateien wiefolgt eingebunden:

Code: Alles auswählen

<?
define('PHPBB_ROOT_PATH', './../phpBB/');
$keyword = 'skiurlaub';
include (PHPBB_ROOT_PATH . 'similar.inc.php');
?>
und

Code: Alles auswählen

<?
include ($_SERVER['DOCUMENT_ROOT']."/neu-meist.inc.php")
?>
Unter phpBb 3.0.* funktioniert das problemlos.
Aber in meiner Testumgebung mit 3.1.4 kommt folgende Fehlermeldung:

Code: Alles auswählen

Warning: Cannot modify header information - headers already sent by (output started at /www/htdocs/xxxxxx/test.php:16) in /www/htdocs/xxxxxx/phpBB-test/includes/functions.php on line 2531
	
General Error
Illegal use of $_SERVER. You must use the request class or request_var() to access input data. Found in /www/htdocs/xxxxxx/test.php on line 347. This error message was generated by deactivated_super_global.
Die aktuellen Themen bzw. ähnlichen Beiträge werden zwar angezeigt (die Funktion scheint also noch zu funktionieren), aber die CSS des Contents funktioniert nur teilweise, teilweise wird sie überschrieben von der CSS des Forums.

die die Fehlermeldung kommt an der Stelle, an der eine WEITERE Datei mit

Code: Alles auswählen

<?
include ($_SERVER['DOCUMENT_ROOT']."/eigener-footer")
?>
"included" werden soll.

Kann das jemand nachvollziehen / verstehen, und mir einen Lösungsansatz geben?

DANKE!
Uwe
Benutzeravatar
tas2580
Ehemaliges Teammitglied
Beiträge: 3029
Registriert: 01.07.2004 05:42
Wohnort: /home/tas2580
Kontaktdaten:

Re: General Error - Illegal use of $_SERVER

Beitrag von tas2580 »

In phpBB 3.1 darf man kein $_SERVER mehr verwenden. Verwende stattdessen

Code: Alles auswählen

include ($request->server('DOCUMENT_ROOT', '')."/eigener-footer"); 
Btw. wirklich gut/sicher ist das was du da machst nicht, aber das war ja nicht die Frage.

Gruß Tobi
Heute ist ein guter Tag um dein Forum zu testen.
Ehemaliger Benutzername: [BTK] Tobi
uwe.ha
Mitglied
Beiträge: 838
Registriert: 18.05.2001 02:00

Re: General Error - Illegal use of $_SERVER

Beitrag von uwe.ha »

[BTK] Tobi hat geschrieben:In phpBB 3.1 darf man kein $_SERVER mehr verwenden.
Aber die Content-Seite und der eigene footer liegen beide außerhalb des Forenordners. Wieso dann der Konflikt, bzw. was wäre besser/sicherer (außerhalb des Forums ... innerhalb des Forums mach ich keine Codeänderungen, da mach ich jetzt meine eigene Extension ... hat mir jemand erklärt :D ).
Uwe
Benutzeravatar
tas2580
Ehemaliges Teammitglied
Beiträge: 3029
Registriert: 01.07.2004 05:42
Wohnort: /home/tas2580
Kontaktdaten:

Re: General Error - Illegal use of $_SERVER

Beitrag von tas2580 »

Du bindest die common.php ein und ab da ist dann $_SERVER böse. Wenn du stattdessen $request->server('DOCUMENT_ROOT', '') verwendest sollte es funktionieren da phpBB dann denkt alles wäre gut.

Leider hat phpBB in deinem Fall da nicht ganz Recht, denn man sollte $_SERVER Variablen nie in includes verwenden, $_SERVER['DOCUMENT_ROOT'] kommt zwar nicht vom User sondern aus der Webserver config und ist daher nicht ganz so kritisch, aber besser wäre es trotzdem wenn du das irgendwie anders lösen kannst.

Gruß Tobi
Heute ist ein guter Tag um dein Forum zu testen.
Ehemaliger Benutzername: [BTK] Tobi
uwe.ha
Mitglied
Beiträge: 838
Registriert: 18.05.2001 02:00

Re: General Error - Illegal use of $_SERVER

Beitrag von uwe.ha »

Hallo Tobi,
da ich mich mit PHP nicht so gut auskenne, habe ich jetzt hin und her probiert, komme aber nicht wirklich weiter.
[BTK] Tobi hat geschrieben: aber besser wäre es trotzdem wenn du das irgendwie anders lösen kannst.
Wie denn?
Der Vorteil von

Code: Alles auswählen

<?
include ($_SERVER['DOCUMENT_ROOT']."/datei.inc.php")
?>
war wohl, dass der Pfad absolut war ... nehme ich an.

Funktionieren tut auch

Code: Alles auswählen

<?php include './../datei.inc.php'; ?>
oder

Code: Alles auswählen

<?php include ("./../adtag_300x250-2.inc.php"); ?>
(welche Variante ist richtig/besser?)
Aber hierbei muss ich immer wieder den (relativen) Pfad anpassen, was beim mehrfachen includen dann irgendwann nicht mehr passt.

Was wäre die beste/sicherste Variante mit absolutem Pfad?

DANKE!
Uwe
Benutzeravatar
tas2580
Ehemaliges Teammitglied
Beiträge: 3029
Registriert: 01.07.2004 05:42
Wohnort: /home/tas2580
Kontaktdaten:

Re: General Error - Illegal use of $_SERVER

Beitrag von tas2580 »

Hallo Uwe,
uwe.ha hat geschrieben:(welche Variante ist richtig/besser?)
Das ist eigentlich egal solange du in der Datei die du includest kein Return verwendest. Siehe Beispiel 4

Der Vorteil von $_SERVER['DOCUMENT_ROOT'] ist mir schon klar, aber $_SERVER Variablen im include verwenden ist eben nicht besonders schön/sicher. Wobei es bei DOCUMENT_ROOT noch geht.

Schöner wäre es so zu lösen wie es u.A. phpBB auch macht:

Code: Alles auswählen

<?php
$root_path = '../';

DEIN CODE

include($root_path . 'datei.php'); 
Die Variable $root_path bleibt dir auch bei mehrfachem includen erhalten. Du musst sie also nur bei Dateien die direkt aufgerufen werden angeben.

Gruß Tobi
Heute ist ein guter Tag um dein Forum zu testen.
Ehemaliger Benutzername: [BTK] Tobi
uwe.ha
Mitglied
Beiträge: 838
Registriert: 18.05.2001 02:00

Re: General Error - Illegal use of $_SERVER

Beitrag von uwe.ha »

[BTK] Tobi hat geschrieben:Die Variable $root_path bleibt dir auch bei mehrfachem includen erhalten.
"erhalten" ... aber nur in der gleichen Datei, richtig? logisch!

Ich habe aber folgendes Problem ... wegen der relativen Pfade:

Ich habe grob:

/index.php
/neues.inc.php
/ordner-a/index-a.php
/ordner-b/altes.inc.php

In der "neues.inc.php" ist aus ordner-b die "altes.inc.php" included.

Wenn ich nun die "neues.inc.php" in die "index.php" include, dann wird die "altes.inc.php" richtig aufgerufen, da die zuerst includete "neues.inc.php" ja im gleichen Verzeichnis liegt, wie die "Index.php".
Wenn ich nun aber die "neues.inc.php" in die "index-a.php" (im ordner-a) include, dann stimmt der Pfad zur "altes.inc.php" nicht mehr.
Verstanden, was ich meine?

Denn im Prinzip funktioniert

Code: Alles auswählen

<?php
$root_path = '../';

DEIN CODE

include($root_path . 'datei.php'); 
?>
nicht anders, als

Code: Alles auswählen

<?php include '../datei.php'; ?>
(Außer, dass ich root-path mehrfach verwenden könnte)

Ich brauche also einen ABSOLUTEN Pfad beim includen.
Sehe ich das richtig?
Und wie wäre das machbar?

DANKE!

PS: Ich nehme an, dass durch

Code: Alles auswählen

$_SERVER['DOCUMENT_ROOT']
der Pfad ABSOLUTER ist. Stimmt das überhaupt?
Uwe
Benutzeravatar
tas2580
Ehemaliges Teammitglied
Beiträge: 3029
Registriert: 01.07.2004 05:42
Wohnort: /home/tas2580
Kontaktdaten:

Re: General Error - Illegal use of $_SERVER

Beitrag von tas2580 »

Du gehst wie der Name schon sagt immer von Root aus, so weiß jede Datei wo sie anfangen muss zu suchen.

./index.php => $root_path = './'
./neues.inc.php => $root_path = './'
./ordner-a/index-a.php => $root_path = '../'
./ordner-b/altes.inc.php =>$root_path = '../'

Wenn du jetzt egal in welcher Datei die altes.inc.php includen willst machst du include($root_path . 'ordner-b/altes.inc.php'); aus der ./index.php wird daraus dann include('./ordner-b/altes.inc.php'); aus der ./ordner-a/index-a.php wird daraus include('../ordner-b/altes.inc.php');
Du wechselst also immer zu erst zum Root und gehst dann von da aus in den jeweiligen Pfad.

Mit $_SERVER['DOCUMENT_ROOT'] ist das eigentlich nichts anders nur das der Pfad absolut statt relativ angegeben wird. Nehmen wir mal an dein Webspace liegt unter /home/user/web/ dann wird include($_SERVER['DOCUMENT_ROOT'] . ordner-a/index-a.php) zu include(/home/user/web/ordner-a/index-a.php) was von der ./ordner-b/altes.inc.php aus gesehen das gleiche wie include(../ordner-a/index-a.php) ist.

Mit der Angabe von $root_path sagst du also in jeder Datei wie es nach $_SERVER['DOCUMENT_ROOT'] geht. Von da aus ist der Weg zur Datei ja dann der gleiche egal was du verwendest.

Gruß Tobi
Heute ist ein guter Tag um dein Forum zu testen.
Ehemaliger Benutzername: [BTK] Tobi
uwe.ha
Mitglied
Beiträge: 838
Registriert: 18.05.2001 02:00

Re: General Error - Illegal use of $_SERVER

Beitrag von uwe.ha »

Hallo Tobi,

ja, das ist soweit klar, und funktioniert ja auch, wenn man jede Datein DIREKT included.

Ich habe aber ein VERSCHACHTELTES / INdirektes includen.
Die ./ordner-b/altes.inc.php wird NUR in die ./neues.inc.php included mit dem RELATIVEN Pfad "im Unterordner-b".

Wenn ich dann die ./neues.inc.php in die ./index.php include, dann wird (von der ./index.php aus) die ./neues.inc.php in der GLEICHEN Ebene gefunden, und die ./ordner-b/altes.inc.php auch korrekt "im (relativen) Unterordner-b". Da stimmt ja auch alles.

Nur wenn ich die ./neues.inc.php in die ./ordner-a/index-a.php include, dann wird (vom (Unter)ordner-a heaus) die ./neues.inc.php eine Ebene HÖHER gefunden. Soweit ok.
Nur dann sagt die neues.inc.php (die sich jetzt nicht mehr im root, sondern im (Unter)ordner-a befindet): include die altes.inc.php, sie befindet sich (relativ) "im Unterordner-b". Nur im ordner-a gibt es keinen Unterordner-b ... und das funktioniert somit nicht :(
Uwe
Benutzeravatar
gn#36
Ehrenadmin
Beiträge: 9313
Registriert: 01.10.2006 16:20
Wohnort: Ganz in der Nähe...
Kontaktdaten:

Re: General Error - Illegal use of $_SERVER

Beitrag von gn#36 »

Wenn du die Verwendung von $root_path konsequent umsetzt dann muss das auch bei indirekten includes funktionieren. Du darfst $root_path nur in der ersten Datei setzen - alle weiteren Includes, auch in untergeordneten Dateien beziehen sich ja immer auf diese Datei. In diesen Dateien musst du das dann natürlich auch benutzen. Wenn als erste Datei mehrere in Frage kommen, dannn setzt du das eben in allen davon und lässt es unabhängig von der Position der Datei immer auf die selbe Stelle im Dateisystem zeigen. Den übrigen Pfad kannst du dann von diesem Punkt aus fest eingeben. Du kannst das auch mit einer Konstante namens ROOT_PATH oder sowas machen - dann kriegst du gleich eine Warnung serviert, wenn du versuchst das in irgend einer Datei zu ändern.

Mal ein Beispiel. Gehen wir mal von dieser Dateistruktur aus:

Code: Alles auswählen

/
subfiles/
    search.php
includes/
    pdf/
        pdf.php
    common.php
    functions.php
index.php
Aufgerufen werden nur index.php und search.php, diese binden jeweils common.php ein, die dann entscheidet, was sonst noch so eingebunden wird.
In die index.php würde man dann z.B. sowas reinschreiben:

Code: Alles auswählen

define('IN_HP', true);
$root_path = './';
include($root_path . 'includes/common.php');
in der search.php würde das gleiche so aussehen:

Code: Alles auswählen

define('IN_HP', true);
$root_path = '../';
include($root_path . 'includes/common.php');
in der includes/common.php kann man dann z.B. sowas machen:

Code: Alles auswählen

if(!defined('IN_HP'))
    exit;

include($root_path . 'includes/functions.php');

//Wenn $irgend_eine_bedingung wahr ist, dann auch PDF einbinden:
if($irgend_eine_bedingung == true)
{
    include($root_path . 'includes/pdf/pdf.php');
}
Du siehst: In allen Dateien sind die include Befehle für die selbe Datei absolut identisch. Nur der Inhalt von $root_path ändert sich.

Um den absoluten Pfad zur aktuellen Datei ohne den Dateinamen zu erhalten kannst du übrigens auch die Konstante __DIR__ verwenden. Das liefert in jeder Datei den jeweils direkt übergeordneten Ordner.
Begegnungen mit dem Chaos sind fast unvermeidlich, Aber nicht katastrophal, solange man den Durchblick behält.
Übertreiben sollte man's im Forum aber nicht mit dem Chaos, denn da sollen ja andere durchblicken und nicht nur man selbst.
Antworten

Zurück zu „Extension Bastelstube“