使用 php 进行可靠的用户浏览器检测
尝试仅使用 PHP 检测用户的浏览器, $_SERVER['HTTP_USER_AGENT'] 是可靠的方法吗?我应该选择 get_browser 函数吗?您认为哪一个可以带来更精确的结果?
如果此方法是实用的,是否建议使用它来输出相关的 CSS 链接,例如:
if(stripos($_SERVER['HTTP_USER_AGENT'],"mozilla")!==false)
echo '<link type="text/css" href="mozilla.css" />';
我注意到 这个问题,但是我想澄清这是否有利于面向 CSS 的检测。
更新: 一些非常可疑的东西:我在 IE 7 上尝试了 echo $_SERVER['HTTP_USER_AGENT'];
,这就是它的输出:
Mozilla/4.0(兼容;MSIE 7.0; Windows NT 6.0; SLCC1; .NET CLR 2.0.50727;媒体中心电脑5.0; .NET CLR 3.5.30729; .NET CLR 3.0.30618)
Safari 也给出了一些带有“mozilla”的奇怪内容。什么给?
Trying to detect a user's browser with PHP only, is $_SERVER['HTTP_USER_AGENT'] a reliable way? Should I instead opt for the get_browser function? which one do you find brings more precise results?
If this method is pragmatic, is it ill advised to use it for outputting pertinent CSS links, for example:
if(stripos($_SERVER['HTTP_USER_AGENT'],"mozilla")!==false)
echo '<link type="text/css" href="mozilla.css" />';
I noticed this question, however I wanted to clarify whether this is good for CSS-oriented detection.
UPDATE:
something really suspicious: I tried echo $_SERVER['HTTP_USER_AGENT'];
on IE 7 and this is what it output:
Mozilla/4.0 (compatible; MSIE 7.0;
Windows NT 6.0; SLCC1; .NET CLR
2.0.50727; Media Center PC 5.0; .NET CLR 3.5.30729; .NET CLR 3.0.30618)
Safari gave something weird with "mozilla" in it too. What gives?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
检查此代码,我发现这很有用。不要检查 Mozilla
因为大多数浏览器都使用它作为用户代理字符串
Check this code , I've found this is useful. Don't check Mozilla
because most browser use this as user agent string
使用现有方法(即
get_browser
)可能比自己编写一些东西更好,因为它有(更好的)支持并且将更新为新版本。可能还有一些可用的库可以以可靠的方式获取浏览器 ID。解码
$_SERVER['HTTP_USER_AGENT']
很困难,因为许多浏览器都有非常相似的数据,并且倾向于(错误)使用它来谋取自己的利益。但如果您确实想解码它们,可以使用此页面上的信息对于所有可用的代理 ID。此页面还显示您的示例输出确实属于 IE 7。有关代理 id 本身字段的更多信息可以在 此页面,但正如我所说,浏览器已经倾向于将其用于自身利益,并且它可能采用(稍微)其他格式。
Using an existing method (ie
get_browser
) is probably better than writing something yourself, since it has (better) support and will be updated with newer versions. There might be also usable libraries out there for getting the browser id in a reliable way.Decoding the
$_SERVER['HTTP_USER_AGENT']
is difficult, since a lot of browsers have quite similar data and tend to (mis)use it for their own benefits. But if you really want to decode them, you could use the information on this page for all available agent ids.This page also shows that your example output indeed belongs to IE 7. More information about the fields in the agent id itself can be found on this page, but as I said already browsers tend to use it for their own benefits and it could be in a (slightly) other format.
用户代理可以被伪造,最好不要依赖于用户代理字符串,如果您只想检测方向,则可以使用 CSS3 媒体查询(您可以探索著名的响应式框架引导程序的 CSS,以检查如何处理使用CSS的方向部分)
这里是一点CSS:
阅读更多:关于 CSS 方向检测
或者您可以使用 JavaScript 查找方向:
了解更多信息:关于使用 JavaScript 检测方向JS
最后,如果您真的想使用用户代理字符串,那么这段代码将对您有很大帮助,几乎在每个浏览器上都可以正常工作:
上面的代码几乎在每个浏览器上都适用,我希望它会对您有所帮助。
User Agent can be faked and its better not to depend upon user agent string rather then you can use a CSS3 media queries if you only want to detect orientation (you can explore the CSS of the famous responsive framework bootstrap to check how you can handle the orientation part using CSS)
Here is little CSS :
Read more : About CSS orientation detection
OR You can find the orientation using JavaScript :
Read more : About detect orientation using JS
Finally if you really wants to go with user agent string then this code will help you alot, work fine almost on every browser :
The above code works for me almost on every browser and i hope it will help you a bit.
这不是一个有用的测试,几乎每个浏览器都将自己标识为 Mozilla。
不。
不。
服务器端的浏览器嗅探是一场失败的游戏。除了尝试解析 UA 字符串、撒谎的浏览器、模糊的浏览器以及标头根本不存在的可能性等所有问题之外,如果您为不同的浏览器返回不同的页面内容,则必须设置
Vary
标头包含User-Agent
,否则缓存代理可能会将错误的页面版本返回到错误的浏览器。但是,如果您添加
Vary: User-Agent
IE 损坏的缓存代码就会变得混乱,并且每次都会重新加载页面。所以你赢不了。如果您必须进行浏览器嗅探,则可以在客户端使用 JavaScript 进行操作,特别是在 IE 的情况下,使用条件注释。幸运的是 IE 支持条件注释,因为这是您经常需要解决方法的浏览器。 (有关最常见的策略,请参阅 scunliffe 的答案。)
That's not a useful test, almost every browser identifies itself as Mozilla.
No.
No.
Browser-sniffing on the server side is a losing game. Apart from all the issues of trying to parse the UA string, the browsers that lie, the obscure browsers, and the possibility the header isn't there at all, if you return different page content for a different browser you must set the
Vary
header to includeUser-Agent
, otherwise caching proxies may return the wrong version of the page to the wrong browser.But if you add
Vary: User-Agent
IE's broken caching code gets confused and reloads the page every time. So you can't win.If you must browser-sniff, the place to do it is on the client side, using JavaScript and, specifically in IE's case, conditional comments. It's lucky that it's IE that supports conditional comments, since that's the one browser you often need workarounds for. (See scunliffe's answer for the most common strategy.)
我注意到,真正的浏览器名称总是在最后一个
(括号)
之后,但 IE 除外,在最后一个(括号)
之后没有浏览器名称。我想知道仅在最后一个)
之后阅读是否可以提高准确性。您可能会在不同的用户代理中注意到这一点:
Google Chrome
< a href="https://www.whatismybrowser.com/guides/the-latest-user-agent/safari" rel="nofollow noreferrer">Safari
Firefox
边缘
IE(括号后未定义浏览器的例外)
示例:
完整功能:
我还在 chrome、edge 和 firefox Developer 上对此进行了测试,并且运行准确。 (虽然我还没有测试过这些浏览器的旧版本)
Something I notice, the real browser name always comes after the last
(parentheses)
with the exception of IE, where there is no browser name after the last(parentheses)
. I wonder if only reading after the last)
could improve accuracy.you may notice this in different user agents:
Google Chrome
Safari
Firefox
Edge
IE (the exception where no browser is defined after parentheses)
example:
A full function:
I also tested this on chrome, edge, and firefox developer, and it worked accurately. (although I have not tested older versions of these browsers yet)
我发现的大多数 PHP 包似乎都相当不错,但我找不到一个能提供我所需一切的好包,因此我构建了一个 Laravel 帮助器来组合其中的 3 个。
这里是软件包:
jenssegers/agent
whichbrowser/parser
cbschuld/browser.php
这是我的函数:
下面是如何使用它:
Most PHP packages that I've found seemed to be pretty good but I couldn't find a good one that gave me everything I needed so I built a Laravel helper to combine 3 of them.
Here are the packages:
jenssegers/agent
whichbrowser/parser
cbschuld/browser.php
And here's my function:
Here's how to use it:
旧帖子仍然出现在谷歌中。 get_browser() 是最好的解决方案,但编辑 php.ini 可能是不可能的。根据这篇文章你不能ini_set browscap 属性。那么还剩下什么呢? phpbrowscap 似乎可以完成工作。该文档不是很好,所以如果您不希望它自动更新(默认为打开),那么您需要设置
Old post still comes up in Google. get_browser() is best solution but editing php.ini might be impossible. According to this post you can't ini_set the browscap property. So what's left? phpbrowscap seems to get the job done. The docs aren't great so if you don't want it to auto-update (the default is on), then you need to set
我认为依赖 userAgent 有点弱,因为它经常被伪造。
如果您只想为 IE 提供 CSS,请使用条件注释。
或者如果您只想要 IE6 的一个:
因为它是一条注释,所以浏览器会忽略它...除了 IE 之外,如果 if 测试与当前浏览器匹配,则 IE 会加载它。
I think relying on the userAgent is a bit weak as it can (and is) often faked.
If you want to serve up CSS just for IE, use a conditional comment.
or if you just want one for IE6:
Since its a comment its ignored by browsers... except IE that loads it if the if test matches the current browser.
@Ekramul Hoque 的想法是正确的,但他的答案存在一些缺陷。
首先,我将从 Edge 开始,因为 Internet Explorer 在其任何 UA 中都不包含术语
Edge
。然后,继续向后工作,因为早期版本的 IE 没有使用
Trident
引擎,因此不会将其包含在其 UA 中。接下来我们需要定位 iOS 浏览器,以便后续查询不会干扰此浏览器。所有 iOS 浏览器都使用 webkit,但 Opera Mini 除外,它从远程服务器而不是设备进行渲染。这意味着我们可以将 UA 中的操作系统定位为
iOS
,并排除包含Opera
的 UA。接下来,转向 Firefox 浏览器。虽然可以使用 Firefox 作为搜索词,但它只能识别 Firefox 浏览器,而不是基于 Firefox 的浏览器。 Firefox 在其 UA 中包含 Gecko,因为 Gecko 是它使用的引擎,因此我们可以瞄准它。通过使用
Gecko
,我们可以识别所有运行在Gecko引擎(即SeaMonkey)上的浏览器。但是,出于兼容性原因,许多浏览器使用术语like Gecko
,因此我们必须确保匹配Gecko
而不是like Gecko
。接下来我们将识别 Opera 浏览器。 Opera 在 v12 结束时一直使用
Presto
引擎。从 v15 开始,他们开始像 Chrome 一样使用 Blink 引擎。 v12 及更早版本在 UA 中包含 v15+ 所没有的两个独特单词 -Opera
和Presto
。您可以瞄准其中任何一个,因为它们总是在一起。对于 v15,Opera 开始在 UA 中使用OPR
。接下来是 Safari。 Safari 使用 AppleWebKit 作为其渲染引擎,但我们不能仅仅以此为目标,因为出于兼容性原因,Chrome 在其 UA 中还包含
AppleWebKit
和Safari
。因此,我们需要搜索AppleWebKit
而不是Chrome
。最后,我们来到 Chrome。 Chrome 在 v27 之前一直使用 AppleWebKit。随着 v28 版本的发布,他们切换到了 Blink 引擎。我们可以针对两个引擎,但这需要大量代码。由于 Chrome 现在已经快到 v70 了,我们将只搜索
Chrome
,因为不太可能有人仍在运行 webkit 版本的 Chrome。最后但并非最不重要的一点是你的后备/其他。
现在,我使用引用供应商前缀的 css 文件来定位此处。请根据需要随意调整它,让它做您需要它做的事情。我希望这有帮助。
@Ekramul Hoque was on the right track but there are several flaws to his answer.
First of all, I would begin with Edge as Internet Explorer does not contain the term
Edge
in any of its UAs.Then, continue to work backward as earlier versions of IE didn't use the
Trident
engine and therefore won't contain it in their UA.We need to target iOS browsers next so that the subsequent queries don't interfere with this one. All iOS browsers use webkit with the exception of Opera Mini, which does its rendering from a remote server instead of the device. This means that we can target the OS in the UA with
iOS
and exclude UAs that containOpera
.Next, move on to Firefox browsers. While using Firefox for the search term will work, it will only identify Firefox browsers--not Firefox based browsers. Firefox contains
Gecko
in its UA as Gecko is the engine that it uses, and we can therefore target that. By usingGecko
, we can identify all browsers that run on the Gecko engine (ie SeaMonkey). However, many browsers use the termlike Gecko
for compatibility reasons, so we must be sure to matchGecko
and notlike Gecko
.Moving on we'll identify Opera browsers. Opera used the
Presto
engine to the end of v12. Starting with v15, they began using the Blink engine like Chrome. v12 and earlier contained two unique words in the UA that v15+ doesn't have--Opera
andPresto
. You can target either of them as they were always present together. For v15, Opera began usingOPR
in the UA.Next up is Safari. Safari uses AppleWebKit as its rendering engine, but we can't just target that because Chrome also includes both
AppleWebKit
andSafari
in its UA for compatibility reasons. Therefore, we need to search forAppleWebKit
and notChrome
.Finally, we get to Chrome. Chrome used AppleWebKit until v27. With the v28 release, they switched over to the Blink engine. We could target both engines but it would require a lot of code. Being that Chrome is almost to v70 now, we'll just search for
Chrome
as it's highly unlikely anyone is still running a webkit version of Chrome.And last but not least, your fallback/else.
Now, I used css files referring to the vendor prefix to target here. Feel free to tweak this as needed to have it do what you need it to do. I hope this helped.