2011-02-10 8 views
6

OK, może to zabrzmi trochę szaleńczo, ale trzymajcie mnie tutaj przez chwilę.Parser SSI napisany w PHP?

Pracuję na stronie, w której standard ma używać SSI do umieszczania nagłówków, stopek i menu stron. Załączone pliki używają warunkowości SSI do obsługi różnych przeglądarek, niektórych zagnieżdżeń #include i niektórych sztuczek #set/#if w celu podświetlenia bieżącej strony w menu. Innymi słowy, jest to więcej niż tylko #instrukcja dyrektyw w SSI.

Jestem pewien, że niektórzy mogą spierać się z estetyką, ale w rzeczywistości działa całkiem ładnie, dla statycznego HTML.

Teraz problem: chciałbym "#include" te same pliki html z nagłówka i stopki SSI ze skryptów PHP, unikając w ten sposób duplikowania kodu i zachowując jednolity wygląd witryny. Gdyby PHP działało w zwykłym środowisku mod_php, byłbym w stanie to zrobić za pomocą funkcji wirtualnej() PHP. Niestety strona używa FastCGI/suexec do uruchomienia PHP (aby każdy VirtualHost mógł działać jako inny użytkownik), a to zrywa wirtualne().

Używam dość prostego parsera SSI napisanego w PHP (obsługuje #includes i kilka naprawdę prostych instrukcji #if), ale chciałbym bardziej ogólnego rozwiązania. Więc, zanim wyjdę na jaw i napiszę jakiś prawdopodobnie błędny, bardziej kompletny parser SSI, czy ktoś wie o pełnym parserie SSI napisanym w PHP? Oczywiście jestem również otwarty na inne rozwiązania, które działają zgodnie z ograniczeniami, które opisałem.

Dziękuję bardzo za poświęcony czas.

+1

Nie będę wzywał plików dołączonych do SSI z zagnieżdżaniem "# include' i' # ustawieniem'/'# jeśli' oszustwem "* statycznym * HTML. ;) W przeciwnym razie ciekawe pytanie. : D – deceze

+0

Jedyną implementacją, o której wiem, jest http://nanoweb.si.kz/manual/mod_include.html - ale to tylko implementuje trzy standardowe funkcje i nie stanowi większego parsera. – mario

+0

@deceze: Cóż ... są "statyczne" w tym sensie, że każdy plik HTML żądany przez użytkownika generuje za każdym razem ten sam wynik. Zgadzam się jednak, że pliki dołączone do SSI w ogóle nie są statyczne. –

Odpowiedz

2

Spójrz na ESI: http://en.wikipedia.org/wiki/Edge_Side_Includes

Można utworzyć PHP-proxy, aby je obsłużyć, to jest HttpCache w Symfony2: https://github.com/fabpot/symfony/blob/master/src/Symfony/Component/HttpKernel/HttpCache/Esi.php

Albo korzystać z serwera proxy HTTP, takich jak lakiery, bardziej wydajnych niż Symfony2. ..

+0

Interesujące pomysły. Niestety nie mam pełnej kontroli nad serwerem, więc nie mogę zainstalować pełnego proxy takiego jak Varnish. Symfony wygląda na użyteczne, a ja na pewno zbadam to dalej dla innych celów, ale naprawdę mam nadzieję na znacznie mniejsze rozwiązanie. Symfony wydaje się mieć ponad 20 megabajtów na instalację podstawową. Nie wiem, jak dobrze jest ładować modułowo, ale z pewnością wydaje się to poważnym przesadą dla tego stosunkowo prostego problemu. –

1

Zdaję sobie sprawę, że jest to stare pytanie, ale wpadłem na ten sam problem kilka lat temu, choć z implementacją Perla. Poszedłem do przodu i rozwinąłem poprzednią próbę, ale dość daleko zaimplementowałem emulator/parser o pełnej apache (2.2.22) mod_include jako moduł perlowy http://search.cpan.org/dist/CGI-apacheSSI/lib/CGI/apacheSSI.pm Niedługo potem znalazłem apache output filters, i zdałem sobie sprawę, jak doskonałe rozwiązanie jest dla moich potrzeb . Zasadniczo można powiedzieć apache, aby przeanalizował dane wyjściowe skryptu tak, jakby był plikiem .shtml lub .php (lub czymkolwiek innym). Możesz więc wyprowadzać znaczniki SSI ze skryptu perl lub php (lub cokolwiek innego) i analizować je przez apache. W ten sposób można to zrobić (w pliku .htaccess):

AddOutputFilter INCLUDES .cgi 

To dla zwykłych plików CGI, ale uwaga, to dodaje trochę napowietrznych do wszystkich plików .cgi wykonywane, więc co ja właściwie zrobić jest utworzenie specjalnego rozszerzenia, tak, że działa jako CGI, który następnie został jego wyjście analizowany, bez narzutu dodanego do normalnych plików cgi:

<Files ~ ".pcgi$"> 
    Options +SymLinksIfOwnerMatch +Includes 
    AddOutputFilter INCLUDES .pcgi 
</Files> 

dla PHP można po prostu zrobić coś takiego:

<Files ~ ".pphp$"> 
    Options +SymLinksIfOwnerMatch +Includes 
    AddOutputFilter INCLUDES .pphp 
</Files> 

i to powinno wystarczyć! Mam nadzieję, że pomaga komuś tam.