SSI parser written in PHP?
Asked Answered
N

2

6

OK, this might sound a little crazy, but bear with me here for a minute.

I'm working on a site where the standard is to use SSI to include page headers, footers, and menus. The included files use SSI conditionals to handle different browsers, some #include nesting, and some #set / #if trickery to highlight the current page in the menu. In other words, it's more than just #include directives in the SSI.

I'm sure some might argue with the aesthetics, but it actually works quite nicely, for static HTML.

Now, the problem: I'd like to just "#include" the same SSI-parsed header and footer html files from my PHP scripts, thus avoiding code duplication and still maintaining the site's uniform look. If PHP were running in the usual mod_php environment, I'd be able to do just that by using PHP's virtual() function. Unfortunately, the site is using FastCGI/suexec to run PHP (so that each VirtualHost can run as a different user), and this breaks virtual().

I've been using a fairly simple SSI parser I wrote in PHP (it handles #includes, and some really simple #if statements), but I'd like a more general solution. So, before I go nuts and write some probably-buggy, more complete SSI parser, does anyone know of a complete SSI parser written in PHP? Naturally, I'm also open to other solutions that work under the constraints I've outlined.

Thanks so much for your time.

Nutrient answered 10/2, 2011 at 2:9 Comment(4)
I wouldn't call SSI included files with "#include nesting and #set / #if trickery" static HTML. ;) Otherwise, interesting question. :DOutrush
The only implementation I know about is nanoweb.si.kz/manual/mod_include.html - but that just implements the three standard functions, and does neither constitute much of a parser.Elsworth
@deceze: Well... they're "static" in the sense that each user-requested HTML file produces the same output every time. I agree, though, that the SSI-included files are not static at all.Nutrient
@mario: I agree, that module definitely doesn't have enough functionality for what I'm doing.Nutrient
I
2

Take a look at ESI : http://en.wikipedia.org/wiki/Edge_Side_Includes

You can create a PHP-proxy to handle them, it's the HttpCache in Symfony2 : https://github.com/fabpot/symfony/blob/master/src/Symfony/Component/HttpKernel/HttpCache/Esi.php

Or use a HTTP proxy like Varnish, more performant than Symfony2...

Impertinent answered 10/2, 2011 at 12:3 Comment(1)
Interesting ideas. Unfortunately, I don't have full control over the server, so I can't install a full proxy like Varnish. Symfony looks useful, and I'll definitely investigate it further for other purposes, but I'm really hoping for a considerably smaller solution. Symfony appears to be over 20 megabytes for a base installation. I don't know how good it is at loading modularly, but it definitely seems like severe overkill for this comparatively-simple problem.Nutrient
L
1

I realize this is an old question, but I ran into that same problem a few years ago, though with a perl implementation. I went ahead and forked a previous attempt and got pretty far into implementing a full apache (2.2.22) mod_include emulator/parser as a perl module http://search.cpan.org/dist/CGI-apacheSSI/lib/CGI/apacheSSI.pm Soon after that I found apache output filters, and realized how perfect a solution that is for my needs. Basically, you can tell apache to parse the output of your script as if it was a .shtml or .php (or whatever) file. So you can output SSI markup from a perl or php (or whatever) script, and have apache parse that. This is how you can do it (in your .htaccess file):

AddOutputFilter INCLUDES .cgi

That's for normal cgi files, but beware, this adds quite a bit of overhead to all .cgi files being executed, so what I actually do is create a special extension so that it runs as a cgi that then has its output parsed, without having the overhead added to normal cgi files:

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

for php you could just do something like:

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

and that should do the trick! Hope that helps someone out there.

Logue answered 6/7, 2015 at 20:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.