views:

105

answers:

4

Does anybody know of an automated way of telling whether a PHP script is being called directly (as a HTML page), or as a JavaScript, or as a CSS Stylesheet?

Without GET variables, or setting a flag in the file ( that is what I am doing right now).

Just curious.

EDIT: Some background because it was asked for in answers: The reason why I want this is a framework that I use when serving HTML pages as well as when serving CSS files. This frameweork has a custom error handler. When I'm in JS "mode", I would like to throw errors as a JS alert(). When I'm in CSS mode, maybe a red body background or something. I would like to avoid working with flags (?mode=css) or constant definitions for the sake of code cleanness, but several answerers have confirmed that there is no "magic" way of finding out what a resource is being used for.

+4  A: 

So you want to distinguish between:

<link type="text/css" rel="stylesheet"
  href="http://example.com/path/to/php-file.php" />

<script type="text/javascript"
  src="http://example.com/path/to/php-file.php"&gt;&lt;/script&gt;

Or simply opening http://example.com/path/to/php-file.php in a browser.

There's no flag set in these cases to distinguish how the file was called. You can examine the $_SERVER array by doing <?php print_r($_SERVER); ?> and they should be identical in each case.

I take it you're adding ?mode=css or ?mode=js to the end of the url -- that seems like a logical way to switch what kind of output you want. Then in the code you can do:

  $mode = (isset($_GET['mode']) ? $_GET['mode'] : '';
  switch ($mode):
    case 'css':
      // css
    break;
    case 'js':
      // js
    break;
    default:
      // default
  endswitch;
artlung
Cheers, but that's what I'm doing right now by "setting a flag" (maybe I was not clear enough, sorry). I'm looking for an automatic, reliable way just to un-clutter the code a bit.
Pekka
Sorry, as Piskvor says in their answer, each request from the browser is simply a `GET` request. There's no magic context provided. HTTP requests are stateless, which I think is **why** no context can be read by PHP. More about statelessness here: http://www.yafla.com/dennisforbes/-Web-Apps-Suck-Because-HTTP-is-Stateless-/-Web-Apps-Suck-Because-HTTP-is-Stateless-.html
artlung
Thanks, that was what I was looking to confirm (or have contradicted).
Pekka
+3  A: 

If I understand you correctly, you have a page which calls itself, (like this):

<?php // page.php
if (is_called_as_js()) {
    header('Content-Type: text/javascript;charset=utf-8');
    echo "alert('hello');";
    exit;
} elseif (is_called_as_css()) {
    header('Content-Type: text/css');
    echo 'body { color: green }';
    exit;
}
?>
<html>
(...)
<script src="page.php"></script>
<link rel="stylesheet" href="page.php" />

In that case, no, there's no way to tell - the browser sends a request saying GET /page.php. No intent is mentioned - just "give me the page and the browser will decide what to do with it". (yeah, yeah, there is Accept and whatnot, haven't seen a modern browser actually using this feature to say "give me this page as CSS", most just say Accept: */*)

If you insist that all your output, be it JS, CSS, or HTML, should be generated with one file, I suggest an URL rewriter (assuming Apache HTTP server, this would be mod_rewrite; most platforms offer this functionality in some way or another). Example using mod_rewrite:

# .htaccess
RewriteEngine On
RewriteRule ^css/(.*) /page.php?type=css&file=$1 [L]
RewriteRule ^js/(.*) /page.php?type=js&file=$1 [L]

This way, request to /css/style.css will look like page.php?type=css&file=style.css when your script is run, similarly for /js/foobar.js.

(Technically, you're still using GET variables to find out if the result is supposed to be HTML,JS,or CSS; but it's not visible to the users, plus you get around some older browsers' limitation "if query string, don't cache or cache brokenly")

Piskvor
The product I am developing must be able to run on other platforms as well, so mod_rewrite is not an option. Still a good idea. +1
Pekka
Most platforms include some form of URL rewriting, I've used mod_rewrite as I'm familiar with it.
Piskvor
Yes, but many (most) shared hosting providers have it turned off for performance reasons.
Pekka
@Pekka I don't know that most shared hosting providers disable url rewriting. I don't have data, but all the shared hosting providers I can think of that are LAMP include .htaccess ability, along with the ability to do mod_rewrite calls. Think: wordpress, drupal and other standard CMS that require it for pretty urls.
artlung
@artlung: Most don't, but still many do; I'd default to pretty URLs and give an option in the config to use your (artlung's) solution.
Piskvor
+1  A: 

No.

There isnt really any reason why you should need to do this though. Either you should have very differnt php files being called as css or js files or you should pass get parameters. They way you layout your code should make this unambiguous.

Toby Allen
See the clarification edited above.
Pekka
A: 

Although it's not entirely clear to me why you'd want to generate such different filetypes through a single script, you could use different wrappers:

 <?php // js.php
 define('TYPE','javascript');
 require('page.php');
 ?>


 <?php // css.php
 define('TYPE','css');
 require('page.php');
 ?>


 <?php // page.php
 if (!defined('TYPE')) {
    ?>
    <script src="js.php"></script>
    <link rel="stylesheet" href="css.php" />
    <?php
 } else if (TYPE == 'javascript') {
    header('Content-Type: text/javascript;charset=utf-8');
    ?>
    alert('hello');
    <?php
 } else if (TYPE == 'css') {
    header('Content-Type: text/css');
    ?>
    BODY { color: red }
    <?php
 }
 ?>

You're still getting to page.php in the end, but you now know with what intent.

Piskvor