Tell from where a .php file has been included? - php

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.

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"></script>
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;

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")

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.

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.

Related

Detect if php file is being used in <link> or <script> tag

I have a PHP file called styles.php?id=1. This fetches CSS code from MySQL and using Content-type: text/css. It can be used with <link> tag.
If I use .htaccess to rewrite engine, then it would be /styles/1. I have a similar file which fetches js (/scripts/1) code instead.
Instead I want one file called code.php which can detect which tag it is being used in and fetch the code from the database.
It's impossible. HTTP request to your server does not contain the tag that caused it.
The only way is to include what you want into GET.
Pseudocode:
if (isset($_GET['js'])) {
echo (getJavascriptFromDB());
} elseif (isset($_GET['css'])) {
echo (getCSSFromDB());
} else {
die("Invalid");
}
HTML:
<link href="code.php?css=1" rel="stylesheet" />
<script src="code.js?js=1"></script>
It has been quite a while but I got an answer. Just thought to share it with other people who need something similar to this.
In .htaccess
RewriteEngine On
RewriteBase /
RewriteRule ^code/(\w+).(\w+)$ code.php?id=$1&type=$2
And In PHP, I would check if the parameter type is equal to CSS or JS and set the content-type header

PHP Variables in CSS not working

I have the following code for my html file:
<html>
<head>
<link rel='stylesheet' href='css/style.php' media = "screen"/>
</head>
<body>
<h1 id="foo">My h1 foo element</h1>
</body>
<html>
And for my php file:
<?php
header("Content-type: text/css; charset: UTF-8");
$asd = '#0000ff';
?>
h1#foo {
color: <?php echo $asd;?>;
}
I've followed some tutorials and this is the simplest one i could make but somehow the output is not working the way it should be. Did i miss anything?
P.S. if i was gonna use php variables in css, can it be sort of dynamic? i mean inside the php body, can i overwrite the value of the php variable used in css and the output would change?
Help would be much appreciated ty!
Works fine for me ^^
Use this syntax:
cssman.php
<?php
ob_clean();
header('Content-Type: text/css');
header('Cache-Control: no-cache, must-revalidate');
error_reporting( 0 );
// These are just to show you can use dynamic values and such:
$type = isset($_GET['type']) ? $_GET['type'] : '';
$theme = isset($_GET['theme']) ? $_GET['theme'] : '';
/** Simply print or echo your css here **/
ob_end_flush();
?>
Try your output first, by navigating to the .php file manually. If there is no content at all, there is most likely a mistake in the PHP code, for debugging you could add error repporting (don't forget to also ini_set('display_errors',1), else errors will only be logged).
Then add it to your view:
your view
<style type="text/css">
#import "/Library/Stylesheets/cssman.php?type=cms" screen;
/* any aditional files here aswell */
</style>
you can do it like
echo"
<style>
h1#foo {
color: ".$asd.";
}
</style>
";
Firstly, to include a php file this syntax is absolutely wrong:
<link rel='stylesheet' href='css/style.php' media = "screen"/>
To include a Css file we use following syntax:
<link rel='stylesheet' href='css/style.css' media = "screen"/>
and include a php file we use:
<?php
include_once "a.php"; // this will include a.php
?>
Instead of using PHP to manage the CSS, you may want to consider one of the CSS preprocessors which are specifically intended for that purpose. It also dissociates your client side code from the server side technology.
http://lesscss.org/
https://learnboost.github.io/stylus/
http://sass-lang.com/
Another approach worth considering is to break up the CSS into several files. You can have a common file that applied to all pages on all devices, one that contains the colors, another that manages the layout, perhaps some device specific ones.
The code you post works as expected. The title with id=foo goes blu. The only problem is that it doesn't use the .css extension for a css file. To solve this you could put in css folder a .htaccess with instructions to Apache Web Server to use Php interpreter also for the css files (look this link).
However probably for dynamic-ly change it from php, you mean change the value (e.g after a user input or some other events).
BUT If I understand well your question the answer is no.
Php can only preprocess your page, it can't modify dynamicly your page after it is loaded by the browser from the user. In addiction, using the code above your variable $asd can only be changed in the style.php AND before that it is used in the code.
I suggest you to use javascript instead, it's a lot easier. Use some javascript library like jQuery, to that kind of job.

Can I load javascript from a php file?

Can I do something like this?
<script src="/js/custom-user.php" type="text/javascript"></script>
The reason behind it is that I want the .php file to die() when the user is not logged in, so that other visitors (not authenticated) cannot see what the javascript looks like. Is it possible/safe to do like this?
Yes, but I do have two recommendations. First, it is better, in your circumstance, to only output the <script> if the user is logged in. Seriously, you don't want the thing which is outputting you js to really know or care about whether the user is logged in.
If you do output js in PHP, then you should include the appropriate header:
header("Content-type: text/javascript");
// either readFile or custom stuff here.
echo "alert('i canz have data!')";
// or, if you're less silly
readFile('/path/to/super-secret.js');
Actually, I once had CSS output by PHP (oh, you can do that too) which completely changed based on the get variable. I literally could have:
rel="stylesheet" type="text/css" href="css.php?v=#FF0000">
And it would use #FF0000 as a base color to completely re-define the color schemes in the website. I even went so far as to hook it in to imagemagick and re-color the site logo. It looked hideous because I'm not a designer, but it was really neat.
Certainly, so long as the php file being reference sends the appropriate content-type header when being downloaded.
Yes, you can do this, and it is safe.
In custom-user.php you will have to set a proper Content-Type header:
header('Content-Type: text/javascript');
And then output the javascript:
readfile('script.js');
Yes, but... You should better do it like this:
<?php
if ($loggedIn) { echo '<script src="/js/custom-user.js" type="text/javascript"></script>'; }
?>
That would prevent loading of empty file. All functions should be put in outer file, if you want some specific javascript changes, make a code in HEAD SCRIPT
Yes, that will work.
That's how JavaScript minifiers are able to dynamically serve minified scripts. (e.g. http://code.google.com/p/minify/)
You can but it will slow down your pages since every time someone accesses your page modphp will have to run your php/javascript script.

Combining CSS in a single request

Does anyone know how to achieve something like TypeKit when combining multiple CSS request? Maybe I'am not aware of that but when you list some fonts the site would generate (maybe dynamic) CSS like 567,568,569.css lo load the font-file. I thought of it as dynamic as it would change if you use other combination (in this case font ID).
I use the technique described by Carpetsmoker, but I didn't like the fact that the PHP script is invoked every time. On Apache, you can set the following rewrite rule (in .htaccess):
RewriteCond %{REQUEST_URI} ^/css/cache
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^css/cache/(.*)$ /css/csscacher.php?files=$1 [L]
So say a request comes in for /css/cache/file1.css-file2.css, Apache will test for its existence. If it doesn't exist, the request will be forwarded to the csscacher.php script with the filename passed as the value of the "files" param. csscacher.php will load and combine the multiple files, send the result to the browser, but also write the result to /css/cache/file1.css-file2.css. All subsequent requests will be served as a static file.
To clear the cache, you'd just delete everything in the /css/cache folder. csscacher.php will recreate them from the source files as requests come in. More detail here.
You could also just use
#import url('reset.css');
at the top of your main css fiel to import other css files on the fly.
Have a look at the Google minify project. It offers a good solution to combine and also compress your JavaScript or CSS files. It is a PHP library that you can set up on your webserver with a script that takes a list of JS or CSS files and outputs a concatenated version. It also caches the result.
The implementation could be separated into three steps. Firstly, define a control wraps all the reference JS files.
Secondly, during the rendering of that control, using any kind of algorithm (e.g. encoding / encrypting) for all file paths to a string, and generate the script tag with a src which points to a certain handler with that generated as querystring.
e.g. Image we have two files: a.js and b.js, we have a control wraps them and generates the script tag like:
<script type='text/javascript' src='/js.php?include=encodeab'></script>
Thirdly, when client side displays the html page and sends request for that script tag, a certain server side handler (js.php in above case) will decode / decrypt that querystring to a list of included files, then read content of them, combile together and output to stream.
Hope this helps.
Be wary using dynamic js or css files as you may accidentally force the user to download them on each page (instead of using browser caching).
You can include multiple javascript/php files into one file, then give it a header of type javascript:
header("Content-type: text/javascript");
include('javascript1.php');
include('javascript2.js');
The same holds true for CSS.
Resources:
http://www.javascriptkit.com/javatutors/externalphp.shtml
http://www.webmasterworld.com/php/4239826.htm
You can use something along the lines of:
<?php
header('Content-Type: text/css');
if (isset($_GET['files']))
{
$files = explode(',', $_GET['files']);
foreach ($files as $file)
{
# BEWARE!
# What happens if the file is ../../../../../../../../etc/passwd?
$file = str_replace('..', '', ltrim($file, '/'));
include($file);
}
}
?>
test.html
<html>
<head>
<link rel="stylesheet" type="text/css" href="css.php?files=style1.css,style2.css" />
</head>
<body>
<h1>This should be red</h1>
<p>red border</p>
</body>
</html>
style1.css
p { border: 1px solid red; }
style2.css
h1 { color: red; }
This is a simple example, you can easily expand it to allow javascript files. Another good optimisation would be setting the Last modified headers based on the mtime of the .css files (use stat()) ... But the general idea should be clear.
BEWARE, to be honest, I'm not sure if the escaping/parsing of the $_GET['files'] is enough ... Please research this topic to be sure, this can a very dangerous security problem :-)
Hope this is enough to get you in the right direction.
You can do something close by calling a dynamic JS file:
start with a php file and then in it:
<?php
if(isset($_GET['jsOne'])){
include'example.com/js/one.js'; // points to some .js file
}
if(isset($_GET['jsTwo'])){
include'example.com/js/two.js'; // points to some other .js file
}
if(isset($_GET['jsThree'])){
include'example.com/js/three.js'; // points to yet a another .js file
}
?>
and in the header just have:
<script type="text/javascript" src="js/allScripts.php?jsOne=yes&jsThree=yes"> and so on
Hope this helps.

Dynamic CSS and Javascript

How does one create Dynamic CSS and JavaScript On-The-Fly (using PHP).
This needs to be done as different pages have different set of elements sometimes, so wrapping and sending a large CSS/JS everytime would be overkill.
And why do many sites have link tags like this:
<link rel='stylesheet' type='text/css' href='css/style.css?pg_id=43&post=62'>
How does the CSS come to know the GET parameters?
Since this might involve URL rewriting or using the header function, please supply short examples
So, there's a few different approaches you can take here. First, if you have access to apache's virtualhost files, you can set CSS to be read by a php interpreter. I've never done this and wouldnt exactly recommend it but an example is:
<VirtualHost *:80>
AddType application/x-httpd-php .css
</VirtualHost>
This can also be done in your .htaccess file.
Alternatively, you can make a link like
<link rel='stylesheet' type='text/css' href='css/style.php?pg_id=43&post=62'>
and put
<?php header("Content-type: text/css"); ?>
as the first line.
I've never considered Vinicius' technique but I don't doubt that has its own set of advantages and disadvantages too.
PS - sometimes GET variables are uses for caching purposes (or actually to prevent caching by appending the current unix timestamp to the css link with php like
<link href="style.css?<?php echo time()" type="text/css" rel="stylesheet" />
A request to a .css or .js file can be redirected to a PHP script using, for example, an .htaccess (in Apache), so even if the src attribute is "style.css", it's actually a PHP script that is responding to the user.
Your CSS and Javascript files are cached, I would not recommend serving different style sheets / js files unless they're >200KB or so in size.
And yes, you can reference any server-side page with parameters (.php or whatever extension) as long as it returns the correct Content-Type for that file.
Sidenote: Usually if you have parameters and are dynamically serving files in this manner, I believe they will not be cached automatically unless you set it up to do so.
Simple example:
<link rel="stylesheet" type="text/css" href="/css.php?color=wide-red">
<?php
header('Content-Type', 'text/css; charset=utf-8');
$colorScheme = (string)$_GET['color'];
switch ( $colorScheme ) {
case 'wide-red':
$bgColor = 'c0c0c0';
$fgColor = 'ffffff';
$width = '1280px';
break;
case 'normal-gray':
$bgColor = '333333';
$fgColor = 'ffffff';
$width = '960px';
}
break;
}
?>
body {
background:<?php echo $bgColor;?>;
color:<?php echo $fgColor;?>;
width:<?php echo $width;?>;
}
You can use echo, you can use a templating system, you can pull in other css files with file_get_contents, key thing is you need to send the right Content-Type, grab the right parameters and have a default fallback if no parameters are given.

Categories