I want to serve mobile content for text browsers or browsers without CSS support. Is this possible using PHP?
There's the native function get_browser, that returns a bunch of information based on the $_SERVER['HTTP_USER_AGENT'] variable.
http://php.net/manual/en/function.get-browser.php
You can look at the http User-Agent header via the php global $_SERVER['HTTP_USER_AGENT']. Of course you'll need to know what User-Agents to look for... You could start by searching here: http://www.user-agents.org/
There aren't that many text based browsers. (I'm using w3m, and then there's only lynx, links, elinks; the others are mostly historic.)
But as a more deterministic alternative (however: cookie dependency!) you could build a trap:
<link rel="stylesheet trap" ref="ping-css.php">
Which simply updates a session or cookie value to check later:
<?php setcookie("css_supported", "yay"); ?> #faux-css { }
A note of concern would be that screenreaders (which are quasi text browsers too) also can consume CSS declarations. And some variants of elinks do too. But then again, you could built a more elaborate trap using #media tty or check via #media screen if it's a graphical browser.
Related
I need to limit what browsers can user use to view on my page. I want to allow only Chrome, FireFox 4+ and all WebKit based browsers. If user use i.e. explorer, PHP will produce output i.e.: "You have not supported browser, use Chrome, Firefox 4+ or WebKit based browser!"
How can I do it?
PHP sniffer is a library that handles extracting information about the user and user-agent (browser).
It uses the same data that get_browser() or $_SEREVER['HTTP_USER_AGENT'] can give you but it formats it into a nicely structured object that you can use in your code.
Use $_SERVER\['HTTP_USER_AGENT'\] or get_browser().
But you should really ask yourself why this is necessary. If your site doesn't work with all feature, than it's ok to show a message saying:
Please upgrade your browser in order to use all features.
You can also detect whether specific JS functions/objects exists so you won't run into Undefined identifier errors (credits to epascarello).
$_SERVER['HTTP_USER_AGENT'] will give you browser details, and from that you can work your way up to verification good luck
This may be so lame, since I am PHP newbie but, I would check if someone is using Mozilla (firefox)
by doing this:
$browser = $_SERVER['HTTP_USER_AGENT'];
if (strpos($browser,'Mozilla') !== false) {
echo 'You are using Mozilla';
} else {
echo 'You are not using Mozilla';
}
You can check server variable:
<?php
echo $_SERVER['HTTP_USER_AGENT'];
?>
Reasoning for this Question
I am aware that browser detection can never be 100% reliable as the User Agent header can always be forged, however, I am not bothered by this.
Although there are many questions on this topic, they all seem to be quite old, so to get an up to date answer I felt I should ask this question again.
I am currently detecting the browser name and version server side using the PHP browscap, and then returning the name and version into javascript variables (not a very good method). The reason why I need to do this is simply to display a message to visitors if they are not using a supported browser.
Current method (something similar):
<script type="text/javascript">
var browser = new Array();
browser['browser'] = '<?php echo $browser_name; ?>';
browser['version'] = '<?php echo $browser_version; ?>';
browser['error'] = '<?php echo $browser_error; ?>';
</script>
It would be much better to do this client side as the browscap can be quite slow, and it would prevent me having to pass values into javascript variables from PHP. If you think using PHP is a better method then please state in your answer, this is just my opinion.
Question
Therefore, my question quite simply, is the following link a reliable method for determining the browser name and version?
Javascript Detect
I am aware that new browsers will need to be added to this, this does not bother me. I am more concerned about whether the algorithm used is reliable.
Thanks in advance
UPDATE 1
To see what I mean, take a look at https://www.icloud.com/ in Internet Explorer 7 or less. You will receive a message saying that the browser is not supported. This is easy to do for IE as you can simply use the <!--[if gt IE..., however, I need to test all browsers.
This does not look right, you can fetch browser information from Javascript. No need to mix JS and PHP code to do that.
You can do something like this to fetch, and detect user browser with just JavaScript:
var userAgent = navigator.userAgent.toLowerCase();
var old = false;
// Internet Explorer 7
if (userAgent.indexOf('msie 7.0b') !== -1) { old = true; }
else if (userAgent.indexOf('msie 7.0') !== -1) { old = true; }
// Internet Explorer 6
else if (userAgent.indexOf('msie 6.1') !== -1) { old = true; }
else if (userAgent.indexOf('msie 6.01') !== -1) { old = true; }
else if (userAgent.indexOf('msie 6.0b') !== -1) { old = true; }
else if (userAgent.indexOf('msie 6.0') !== -1) { old = true; }
...
// Detect any other browser versions you consider old
if(old = true) {
// Show notification and alert users that they are using old browser
}
This is how you can do it using JS, but you can also use HTML to achieve this:
<!--[if lte IE 6]>
// include your .css style or do whatever you want to alert users their browser is old
<![endif]-->
Short answer to your question is YES, its wrong to detect user browser the way you do it, since you can do it with plain JavaScript, or even with HTML. No need to mix PHP and JS code here, and at the end, both PHP and JS will get the same UserAgent info.
Explanation
After extensive research and discussing amongst other developers, it is clear that there is no reliable method for retrieving the browser name and version from the User Agent. This is down to several reasons:
The format of a browsers User Agent can change at any time if the developers of the browser so wish to do so. This could immediately prevent some scripts from working correctly.
Users can forge their User Agents to mimic other browsers, and therefore would appear to be using a browser they are not.
Possible Solutions
Whilst I hugely discourage the use of these scripts as they could stop working at the release of an update to any browser anytime, if you do wish to detect the browser name and version in Javascript then I would advise using this script:
Javascript Detect
However, the most reliable method for retrieving the details of the browser is without a doubt the browscap supplied by Gary Keith. The browscap project offers extensive information about each browser and OS gathered from the User Agent. It is very easy to implement and even easier to use. To read more, take a look at:
Gary Keith - Browscap
If you choose to use the browscap by Gary Keith, you will need to ensure it is updated weekly at the very least.
Answer
Whilst I am contradicting myself with this answer, it is clear that detecting the browser information with any sort of script is not advised. The only reliable method of browser detection is that of the Internet Explorer HTML conditions, and as stated, these only cover Internet Explorer.
Try to avoid browser specific functions and notices, and make use of the built in features such as:
media="only screen and (device-width: 768px)"
and
<!--[if IE 8]>I am IE 8<![endif]-->
This question needs an updated answer. I think the best option these days for client-side detection is WURFL.
Its an updated library of devices based on Useragents - think Browscap for the client side.
Load the JS and it returns JSON based on the device that requested the js. Perfect!
<script type="text/javascript" src="//wurfl.io/wurfl.js"></script>
Because it does the parsing on the WURFL server side, you need to load the js remotely and not save it in your dir tree.
A super easy
WURFL.is_mobile
is all it takes to determine mobile for example.
Good luck.
You could try having a look at navigator.appName and navigator.userAgent.
The yepnopejs IE detection (!ie prefixes) works by utilizing the MS conditional comments.
A short snippet for detecting versions of IE prior to IE10 in JavaScript without resorting to user-agent sniffing.
while (
div.innerHTML = '<!--[if gt IE ' + (++v) + ']><i></i><![endif]-->'
);
// …
https://github.com/SlexAxton/yepnope.js/blob/master/prefixes/yepnope.ie-prefix.js
yepnope usage example:
yepnope({
load: ['normal.js', 'ie6!ie7!ie-patch.js'] // patch for ie6 or ie7 only
});
You can use a perfect plugin for this information written in jQuery (like javascript)
look at this link:
https://github.com/jquery/plugins.jquery.com
Be sure to do feature detection instead of browser detection when you want to determine if a certain feature is available in a browser, apply bugfixes, etc.
I have a script that works fine in all browsers except ie6 (including ie7 and ie8).
Is there any semi reliable way I can exclude this nefarious browser.
I've tried this:
<!--[if !IE 6]>
<?php include("fconditionals.php"); ?>
<![endif]-->
and this:
$user_agent = getenv("HTTP_USER_AGENT");
if (preg_match("MSIE 6", $user_agent))
{
include("fconditionals.php");
}
The first version would never work. PHP only cares about <?php ?> pairs and utterly ignores anything outside of them. The IE conditional comments are only used by the browser, so the include would get executed on the server every time.
The second version has the logic reversed - you're including the file anytime IE6 is detected. you'd want !preg_match instead. However, remember that the user agent string is under user control and can be faked/hacked/subverted. There's no 100% reliable method of detecting the remote browser that can't be subverted somehow.
The first thing you tried (Conditional Comments) won't work because the include is done on the server, while the page is being generated, and the conditional comments are only checked by the browser after the page has been downloaded.
The conditional comments will exclude the generated code from being displayed in IE6, but it will still be run by the server.
Additionally, the conditional comments in the format you've used them here will also exclude the code from being displayed by all non-IE browsers. If you only want to affect IE, you need to re-format it so that the other browsers don't treat the code inside as a comment, by using the <![if !IE 6]> syntax instead of <!--[if !IE 6]>.
That method still won't stop the code from being run on the server though.
The second method you tried is more likely to be closer to what you actually want to do. However, please note that although PHP does receive the USER_AGENT string, it is possible in most browsers to spoof the USER_AGENT, and some privacy/security products actively remove it, as do some web proxies. In other words, the USER_AGENT string is not a 100% reliable way of determining what browser someone is using.
That said, if you have specific PHP code that you want to exlude from being executed only for IE6, then it may be the only viable solution.
The reason this didn't work for you is that your code includes only IE6 rather than excluding it. You need to add a 'not' operator (!) in front of the preg_match().
By the way: In your example code, you have $user_agent = getenv("HTTP_USER_AGENT");. It's worth pointing out that $_SERVER['USER_AGENT'] is already available as a variable, you don't need to use getenv().
if (!strstr($_SERVER['HTTP_USER_AGENT'],"MSIE 6")
{
include("fconditionals.php");
}
I'd like to use this function:
ob_start('no_returns');
function no_returns($a) {
return str_replace(
array("\r\n","\r","\n","\t",'','',''),
'', $a);
}
But when I do, it completely kills Disqus comments so I'd like to ignore the DIV "disqus_thread". How would I go about doing that without using some heavy search?
If you are looking to speed up the download of the web page, you might try another method:
<?php
ob_start('ob_gzhandler');
// html code here
This will compress the output in a much more efficient manner and your browser will automatically decompress the output in real-time before the visitor sees it.
A related thread on-line is here: http://bytes.com/topic/php/answers/621308-compress-html-output-php
(This is the PHP way to compress web pages without using the webserver configuration. For example apache+gzip/mod_deflate on apache as mentioned above)
Try Regular Expression and preg_replace
I occasionally come across pages where some Javascript is included via a PHP file:
<html>
<head>
<script type="text/javascript" src="fake_js.php"></script>
</head>
<body onload="handleLoad();">
</body>
</html>
where the contents of fake_js.php might look something like this:
<?php header('Content-type: text/javascript') ?>
function handleLoad() {
alert('I loaded');
}
What are the advantages (or disadvantages) to including Javascript like this?
It makes it easy to set javascript variables from the server side.
var foo = <?=$foo?>
I usually have one php/javascript file in my projects that I use define any variables that need to be used in javascript. That way I can access constants used on the server-side (css colors, non-sensitive site properties, etc) easily in javascript.
Edit: For example here's a copy of my config.js.php file from the project I'm currently working on.
<?php
require_once "libs/config.php";
if (!function_exists("json_encode")) {
require_once "libs/JSON.php";
}
header("Content-type: text/javascript");
echo "var COLORS = ". json_encode($CSS_COLORS) .";\n";
echo "var DEBUG = ". ((DEBUG == true) ? "true" : "false").";";
?>
If you don't need it, don't use it:
The first thing you need to keep in
mind is YAGNI. You Ain't Gonna
Need It. Until a certain feature,
principle, or guideline becomes useful
and relevant, don't use it.
Disadvantages:
Added complexity
Slower than static files.
Caching problems (server side)
Scalability issues (load balancers offload static files from the heavy PHP/Apache etc processes)
Advantages:
User specific javascript - Can be achieved by initializing with the right variables / parameters in the <head> </head> section of the HTML
Page specific javascript - JS could also be generalized to use parameters
JSON created from database (usually requested via AJAX)
Unless the javascript is truely unique (i.e. JSON, parameters/variables) you don't gain much. But in every case you should minimize the amount of JS generated on the server side and maximize the amount of code in the static files. Don't forget that if it's dynamic, it has to be generated/downloaded again and again so it's not wanted for it to be a heavy process.
Also:
This could also be used to minimize the amount of server configuration (for example if the web server doesn't serve file.js with the correct content type)
There's no benefit for the example you gave above (beyond peculiar deployment scenarios where you have access to .php files and not .js files, which would be insane but not unheard of).
That said, this approach allows you to pass the JS through the php parser - which means you can generate your JS dynamically based on server variables.
Agree with tj111. Apart from what tj mentioned, I also found php-generated javascripts a great weapon to fight the browser's caching tricks. Not that long ago I was cursing the whole javascript for its being constantly cached by the browser. Refreshing the page helped me not, had to clear the whole cache in order to force the browser to reload the javascript files. As soon as I built a php wall in front of my javascripts:
fake_js.php:
<?php
header('Content-type: text/javascript')
include('the_real_javascript.js');
?>
A fresh new javascript would always show up at the client side. However this approach is obviously only good in the development phase, when it can save the developer quite some headache to have the correct javascript loaded in the browser. Of course when connecting to localhost, the penalty of repeatedly loading the same file is not as big.
In a live web application/site client-side caching is welcome to reduce network traffic and overall server load.
Advantage (not PHP specific - I used this technique in EmbPerl and JSP) would be the ability to dynamically generate or tweak/customize the JavaScript code on the server side.
An example usage would be population of an array based on the contents of a DB table.
Or application of localization techniques.
If you don't have full server access and can't turn on gzip encoding then it's pretty useful to put the following in your javascript file (note: will need to be renamed to file.js.php or parsed as PHP through .htaccess directive):
<?php
ob_start( 'ob_gzhandler' );
header("Content-type: text/javascript");
?>
// put all your regular javascript below...
You could also use it for better cache control, visitor tracking, etc in lieu of server-controlled solutions.
Absolutely none, IMHO. I use a js framework that I wrote to handle the setting of whatever server-side variables I need to have access to. It is essentially the same as embedding PHP in JavaScript, but much less ambiguous. Using this method allows you to also completely separate server-side logic and html away from javascript. This results in much cleaner, more organized and lowly-coupled modular code.
You could do something like this in your html:
<script type="text/javascript">
registry = {
myString : '<?php echo $somePhpString; ?>',
myInt : <?php echo $somePhpInteger; ?>
}
</script>
And then do something like this in your js:
if (registry.myInt === 1) {
alert(registry.myString);
}