Das Yii 2 - Framework und der Base-Path URLs ohne Public-Root und ganz ohne Virtual Host

Sebastian Bork | Montag, 12 Oktober 2015. paxistipp, yii

Yii - aktuell in der Version 2 vorliegend - ist nicht nur ein sehr mächtiges und wahnsinnigs schnelles PHP-Framework, sondern auch eines der flexibelsten, welches mir je unter die Hände gekommen ist. Es gibt demnach nur sehr wenige Paradigmen, an die man als Entwickler in Yii wirklich gebunden ist; Denn es lässt sich nahezu alles auf die eigenen Bedürfnisse hin konfigurieren.

Das Problem

Eine diese Vorgaben - nicht unbedingt eine Yii-Eigenheit, eher eine generelle Sicherheitsregel in der Web-Entwicklung - ist die Limitierung des Verzeichnisbaums auf ein einziges öffentlich zugängliches Verzeichnis. In diesem sogenannten "Public Root" befinden sich alle vom Benutzer abrufbaren Dateien (Bilder, Stylesheets, Javascript und andere evtuellen Assets); Aber eben auch die zentrale index.php (das sogenannte Entry-Script) findet hier ihren Platz.

Im Basic Template von Yii 2 (der Einfachheit halber behalten wir diesen Beispielfall in diesem Beitrag auch bei) heißt dieses öffentliche Verzeichnis zu Beginn "/web". Auch dies kann natürlich gern umbenannt und, mit entsprechender Konfiguration, der Apllikation - unter neuem Namen - bekanntgemacht werden. Diese Art der Anpassung wollen wir aber hier und heute nicht besprechen.

Yii geht also per Default davon aus, dass das Public Root {approot}/web lautet und passt hierauf auch alle vom Framework generierten URLs automatisch an. Das Resultat ist "leider", dass auch bei den vom System erzeugten Links immer dieses Verzeichnis mitgeschleift wird. Eine vom System erzeugte Route (mal davon ausgegangen man hat bereits SEO-freundliche URLs in der Konfiguration bewerkstelligt) lautet dann bspw. http://www.irgendwas.net/web/site/index

Natürlich ist es kein Problem den Server via Virtual Host gleich auf das Verzeichnis /web zu leitetn; Das würde das Problem nahezu automatisch aus der Welt schaffen (die meisten Yii-Tutorials im Web gehen auch genau diesen Weg). Was ist aber, wenn man (wie ich) ein Pragmatiker ist und einfach darauf besteht, dass sich das jeweilige Framework an den eigenen Willen anpasst?!

Die Lösung heisst .htaccess

Im Web-Root bzw. dem Application-Root schreibt man folgendes in seine .htaccess


RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* web/index.php?$0 [PT,L,QSA]

Dieser Teil leitet ersteinmal alle Anfragen (welche keine reellen Dateien in reelen Verzeichnissen betreffen) an die index.php im Verzeichnis /web um.

Das hält aber Yii noch nicht davon ab, weiterhin URLs mit /web zu bilden. Um dies zu erreichen müssen wir nun in unserer Konfiguration etwas tricksen.Per Default ist die Konfiguration für die Web-Application des Yii-Basic-Templates zu finden unter {approot}/config/web.php

Hier erstellen wir zuerst (am besten gleich ganz oben, denn wir benötigen ohnehin hierfür ein use-Namespace) den neuen Base-Path ohne das /web


use \yii\web\Request;
$baseUrl = (new Request)->getBaseUrl();
$strippedBaseUrl = str_replace('/web', '', $baseUrl);

Bitte nicht genervt mit den Augen rollen: Die im Moment noch etwas unsinnig wirkenden zwei Schritte zur neuen Base-URL werden gleich Sinn ergeben.

Nun machen wir aber diesen neuen Base-Path ersteinmal der Request-Komponente von Yii (zuständig für das Parsen und Generieren der URLs im Framework) bekannt.


...
'components' => [
	...
    'request' => [            
        'cookieValidationKey' => '...',
        'baseUrl' => $strippedBaseUrl,
    ]
    ...
]

Ab hier bildet Yii nun alle URLs ohne /web (also bspw. http://www.irgendwas.net/site/index). Aber - und das ist leider etwas problematisch - eben ALLE URLs. Auch die für die Assets des Systems, wodurch diese nun nicht mehr ohne Weiters funktionieren.

Hier machen wir uns nun wiederum die Flexibilität von Yii zu nutzen! Denn, Wir konfigueren uns einfach noch den AssetManager um. Und hier wird nun auch der erste der beiden Schritte zur neuen Base-Url nützlich


...
'components' => [
	...
    'assetManager' => [
        'baseUrl' => $baseUrl.'/assets'
    ]
    ...
]

Nun haben wir ein Yii, welches ohne den Namen des Public Root in den URLs auskommt und das ganz ohne Virtual Host.

Kommentare aktivieren?

Diese Seite verwendet das externe Kommentarsystem DISQUS. Da es durch die Nutzung externer Dienste zwangsläufig dazu kommt, dass Daten des Nutzers an die Server dieses Dienstes gesendet werden, möchte ich jedem Nutzer diese Entscheidung selbst überlassen!.
DISQUS aktivieren