Ensuring that websites can adapt to multiple devices – particularly mobile devices – has become both increasingly important and complex. The variety of ways in which people browse the web having mushroomed. Much of this has been driven by the rise in the use of mobile devices to access the web, although it also applies to devices such as tablets, Internet TV, and so on.

确保网站可以适应多种设备(尤其是移动设备)已经变得越来越重要和复杂。 人们浏览网络的各种方式如雨后春笋般冒出。 尽管移动设备也适用于平板电脑,互联网电视等设备,但其中很大一部分是由使用移动设备访问网络的兴起推动的。

In recent years, Responsive Web Design has become all the rage as a mechanism for adapting websites and applications to cater to multiple devices by using information client-side to adapt layouts accordingly. In a sense, this is a “one-size-fits-all” approach. However, there’s often a case for providing different versions of the same site or using a slightly different approach.

近年来,作为一种通过使用信息客户端相应地调整布局来适应网站和应用程序以适应多种设备的机制,响应式Web设计已成为一种流行。 从某种意义上说,这是“一刀切”的方法。 但是,通常存在提供同一网站的不同版本或使用略有不同的方法的情况。

An alternative solution to the problem is to use server-side device detection and then take certain actions based on that information. One possibility is to simply forward requests for a mobile site to a different URL. Another possibility is to adapt the layout – or indeed content – programmatically as it’s generated on the server.

解决该问题的另一种方法是使用服务器端设备检测,然后根据该信息采取某些措施。 一种可能性是简单地将对移动站点的请求转发到其他URL。 另一种可能性是,在服务器上生成布局时,以编程方式调整布局,甚至调整内容。

Taking a server-side approach is the basis of this article, which looks in detail at the Browser Capabilities Project, or Browscap for short, to provide the information on which to base these decisions.

采用服务器端方法是本文的基础,本文将详细介绍“浏览器功能项目”(简称Browscap),以提供决策依据。

用户代理字符串简介 (An Introduction to User Agent Strings)

Before we can look at server-side detection, we need to understand the information available to the web application which comes in the form of user agent strings.

在查看服务器端检测之前,我们需要了解Web应用程序可用的信息,这些信息以用户代理字符串的形式出现。

When you make an HTTP request to retrieve a page from a web browser, it includes a piece of information called the user agent string. This provides information about who’s making the request and includes a variety of elements.

当您发出HTTP请求以从Web浏览器检索页面时,它包含一条称为用户代理字符串的信息 。 这提供了有关谁在发出请求的信息,并包括各种元素。

Typically the user agent string specifies what browser is used – it’s how analytics services can determine whether you’re using Chrome, Firefox, Safari, IE, or one of a multitude of other browsers. Furthermore, it can also provide information about the version of the requesting application. This is great for identifying the dwindling numbers of IE6 users, for example.

通常,用户代理字符串指定使用哪种浏览器–分析服务可以通过这种方式确定您使用的是Chrome,Firefox,Safari,IE还是其他多种浏览器之一。 此外,它还可以提供有关请求应用程序版本的信息。 例如,这对于识别IE6用户的数量减少非常有用。

Of course a browser is really just a specific type of application. Remember, HTTP requests aren’t just issued when your web browser accesses a web page or other resource. The request may be from a web crawler, a feed reader (ie: RSS), a validator, a library such as cURL, or one of a potentially infinite number of web service clients.

当然,浏览器实际上只是一种特定类型的应用程序。 请记住,当您的Web浏览器访问网页或其他资源时,不仅发出HTTP请求。 该请求可以来自Web爬网程序,提要阅读器(即RSS),验证器,库(例如cURL)或可能无限多个Web服务客户端之一。

The user agent string is also used to provide information about the operating system. Windows, Linux or Mac? iOS or Android? That, too is qualified with version numbers.

用户代理字符串还用于提供有关操作系统的信息。 Windows,Linux或Mac? iOS或Android? 那也符合版本号。

The user agent string will often also provide information about the physical device being used, whether it is a desktop, laptop, mobile, tablet, etc.

用户代理字符串通常还会提供有关正在使用的物理设备的信息,无论它是台式机,笔记本电脑,移动设备,平板电脑等。

Let’s look at some examples of user agent strings:

让我们看一些用户代理字符串的示例:

Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:24.0) Gecko/20100101 Firefox/24.0

Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:24.0) Gecko/20100101 Firefox/24.0

– This says that the request has been made by Firefox (version 24, to be specific) from an Intel-based Mac.

–这表示请求是由Firefox(具体来说是版本24)从基于Intel的Mac发出的。

Mozilla/5.0 (iPad; CPU OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5355d Safari/8536.25

Mozilla/5.0 (iPad; CPU OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5355d Safari/8536.25

– Safari on an iPad (running iOS6)

– iPad上的Safari(运行iOS6)

Opera/9.80 (J2ME/MIDP; Opera Mini/9.80 (S60; SymbOS; Opera Mobi/23.348; U; en) Presto/2.5.25 Version/10.54

Opera/9.80 (J2ME/MIDP; Opera Mini/9.80 (S60; SymbOS; Opera Mobi/23.348; U; en) Presto/2.5.25 Version/10.54

– Version 9 of Opera Mini on a Java-based mobile phone

–基于Java的手机上的Opera Mini版本9

Mozilla/5.0 (Linux; U; Android 4.0.3; ko-kr; LG-L160L Build/IML74K) AppleWebkit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30

Mozilla/5.0 (Linux; U; Android 4.0.3; ko-kr; LG-L160L Build/IML74K) AppleWebkit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30

– Mobile Safari on an Android phone

– Android手机上的Mobile Safari

You can view hundreds of user agent strings online at useragentstring.com/pages/useragentstring.php.

您可以在useragentstring.com/pages/useragentstring.php上在线查看数百个用户代理字符串。

访问Browscap数据 (Accessing Browscap Data)

Considering the number of variables, the number of possible versions, and of course the ever-expanding range of physical devices being used, you’ll realize that the number of different permutations is quite large and growing every day. The Browser Capabilities Project is an attempt to catalogue these permutations. You can think of it of a database of user agent strings which associates them with some of the information which we can glean from them.

考虑到变量的数量,可能的版本的数量以及当然所使用的物理设备的范围不断扩大,您将意识到,不同排列的数量非常大,并且每天都在增加。 浏览器功能项目试图对这些排列进行分类。 您可以想到一个用户代理字符串数据库,该数据库将它们与我们可以从中收集的一些信息相关联。

In reality it’s not simply a database keyed by user agent string; it’s a series of rules and patterns used to extract relevant pieces of information, cross-referenced against known browsers, devices, and other information.

实际上,它不只是一个由用户代理字符串作为键的数据库。 它是一系列规则和模式,用于提取相关信息,并与已知的浏览器,设备和其他信息进行交叉引用。

PHP offers a native wrapper to Browscap data in the form of the get_browser() function. (See php.net/get-browser). However, there are two key disadvantages to its use. Because PHP doesn’t ship with a browscap.ini data file, you’ll need to manually download one and set your php.ini to point to the appropriate location. More significantly, because the database is updated regularly you’ll need to manually replace it when it does.

PHP以get_browser()函数的形式为Browscap数据提供了本地包装。 (请参阅php.net/get-browser )。 但是,其使用有两个主要缺点。 由于PHP并未附带browscap.ini数据文件,因此您需要手动下载一个文件,并将php.ini设置为指向适当的位置。 更重要的是,由于数据库会定期更新,因此您需要在此时手动进行替换。

Fortunately, there are libraries which take care of both of these issues and don’t require any additional configuration. There are a number of them available, but I recommend github.com/browscap/browscap-php.

幸运的是,有一些库可以解决这两个问题,并且不需要任何其他配置。 有很多可用的,但是我推荐github.com/browscap/browscap-php 。

集成Browscap库 (Integrating a Browscap Library)

I’m going to use the Slim Framework for the following examples. You might prefer a different framework, or indeed none at all, but as this article is specifically about Browscap I don’t want to get bogged down in fundamentals such as autoloading, routing, or middleware. The code for this article is available so you can follow along.

我将在以下示例中使用Slim Framework。 您可能会喜欢一个不同的框架,或者根本不喜欢它,但是由于本文是专门针对Browscap的,因此我不想陷入自动加载,路由或中间件等基础知识的困扰。 本文的代码可用,因此您可以继续进行。

The easiest way to get started is to use Composer to download the dependencies. There are two to start with – the Slim framework and the Browscap library. Create a project directory, and in its root a composer.json file to specify these dependencies:

最简单的入门方法是使用Composer下载依赖项。 首先有两个– Slim框架和Browscap库。 创建一个项目目录,并在其根目录中创建一个composer.json文件来指定以下依赖关系:

{
"require": {
"slim/slim": "2.2.*",
"browscap/browscap-php": "1.0.*@dev"
}
}

(Note: At time of writing, the current version of the Slim Framework is 2.3.0. However, I’m deliberately using 2.2.x for compatibility with a layout view library that we’ll be using later.)

(注意:在撰写本文时,Slim Framework的当前版本为2.3.0。但是,我故意使用2.2.x以与稍后将使用的布局视图库兼容。)

Then run composer:

然后运行作曲家:

php composer.phar install

You should now have a vendor folder in your project root containing both libraries, as well as an autoloader. Create a public folder in the project root, and in that an index.php file. Start by including the autoloader:

现在,您应该在项目根目录中有一个供应商文件夹,其中包含两个库以及一个自动加载器。 创建一个public项目中的根文件夹,并在一个index.php文件。 首先包括自动装带器:

<?php
require '../vendor/autoload.php';

Let’s now create the bare bones of a Slim application, which is beautifully simple:

现在让我们创建一个Slim应用程序的基础知识,它非常简单:

$app = new SlimSlim();
$app->get('/', function () {
print 'Hello World';
});
$app->run();

At this stage, you’ll probably want to verify that everything is installed properly by browsing to your new index page.

在此阶段,您可能需要通过浏览到新的索引页面来验证是否已正确安装所有内容。

Next, we’re going to set up the Browscap library. This takes care of three key tasks:

接下来,我们将建立Browscap库。 这照顾了三个关键任务:

  • downloading the actual data file (browscap.ini)

    下载实际数据文件( browscap.ini )

  • processing the data to make lookups more efficient
    处理数据以提高查找效率
  • keeping the data up-to-date
    保持数据最新

Since the library needs to download and create some files, we need a cache directory. Let’s keep it simple and create a cache directory in the project root – just don’t forget to make it writeable by the web server.

由于该库需要下载并创建一些文件,因此我们需要一个缓存目录。 让我们保持简单,并在项目根目录中创建一个缓存目录–只是不要忘记使其可被Web服务器写入。

We specify the cache directory when we construct an instance of the Browscap class:

当我们构造Browscap类的实例时,我们指定缓存目录:

use phpbrowscapBrowscap;
// create a new Browscap object (loads or creates the cache)
$bc = new Browscap('../cache');

Let’s check it out by grabbing the information and dumping it straight to the screen:

让我们通过获取信息并将其直接转储到屏幕上来进行检查:

// get information about the current browser's user agent
$current_browser = $bc->getBrowser();
echo '<pre>';
print_r($current_browser);
echo '</pre>';

This might take a little while to run first time as the library needs to download the INI file and perform some processing on it – thankfully, subsequent requests will be considerably faster.

第一次运行可能需要一些时间,因为该库需要下载INI文件并对其执行一些处理-幸运的是,后续请求将大大加快。

If you take a look in the cache directory you’ll notice two files; browscap.ini is the original data file, and cache.php is the same data but optimized for quicker lookups. Different libraries process and optimise the INI data in different ways – you might wish to try a few and perform benchmark tests to see which is the most efficient.

如果您看一下缓存目录,您会注意到两个文件。 browscap.ini是原始数据文件, cache.php是相同的数据,但已针对快速查找进行了优化。 不同的库以不同的方式处理和优化INI数据-您可能希望尝试一些并执行基准测试,以查看哪种效率最高。

解释Browscap数据 (Interpreting Browscap Data)

Here’s example output from the code in the previous section:

这是上一部分代码的示例输出:

stdClass Object
(
[browser_name] => Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.116 Safari/537.36
[browser_name_regex] => ^mozilla/5.0 (.*intel mac os x.*) applewebkit/.* (khtml, like gecko).*chrome/27..*safari/.*$
[browser_name_pattern] => Mozilla/5.0 (*Intel Mac OS X*) AppleWebKit/* (KHTML, like Gecko)*Chrome/27.*Safari/*
[Parent] => Chrome 27.0
[Platform] => MacOSX
[Win32] =>
[Comment] => Chrome 27.0
[Browser] => Chrome
[Version] => 27.0
[MajorVer] => 27
[MinorVer] => 0
[Beta] => 1
[Frames] => 1
[IFrames] => 1
[Tables] => 1
[Cookies] => 1
[JavaScript] => 1
[JavaApplets] => 1
[CssVersion] => 3
[Platform_Version] => unknown
[Alpha] =>
[Win16] =>
[Win64] =>
[BackgroundSounds] =>
[VBScript] =>
[ActiveXControls] =>
[isMobileDevice] =>
[isSyndicationReader] =>
[Crawler] =>
[AolVersion] => 0
)

What you actually see here will of course depend on your machine, the browser you’re using, and what versions. But notice that key pieces of information have been extracted into properties of the returned object, for example:

当然,您在此处实际看到的内容将取决于计算机,所使用的浏览器以及什么版本。 但是请注意,关键信息已被提取到返回对象的属性中,例如:

  • browser_name is the original user agent string. Notice the ambiguity – it mentions both Chrome and Safari; which one is it?

    browser_name是原始用户代理字符串。 注意模棱两可–它同时提到了Chrome和Safari; 哪一个?

  • Browser tells us I’m using Chrome

    Browser告诉我们我正在使用Chrome

  • Version is the version of Chrome I’m using

    Version是我使用的Chrome版本

  • Platform tells us I’m using an Apple Macintosh

    Platform告诉我们我正在使用Apple Macintosh

Furthermore there are a number of characteristics of my setup that are identified.

此外,可以确定我的设置的许多特征。

Tables, Cookies, Frames, IFrames, Javascript, JavaApplets, BackgroundSounds, VBScript, and ActiveXControls provide some information about the capabilities of my browser – perhaps some more useful than others nowadays!

TablesCookiesFramesIFramesJavascriptJavaAppletsBackgroundSoundsVBScriptActiveXControls提供了有关我的浏览器功能的一些信息-也许比当今的其他功能有用!

We can glean even more information about the browser’s capabilities from CssVersion, which specifies the maximum version of the CSS specification the browser supports.

我们可以从CssVersion收集有关浏览器功能的更多信息, CssVersion指定了浏览器支持CSS规范的最高版本。

isSyndicationReader and Crawler are useful for identifying specific types of application. For example, were you to write an analytics service, you may wish to use Crawler to exclude those “hits” from your visitor data. Alternatively, an application or website that caches heavily may wish to ensure it’s fresh when a request has been identified by a crawler that’s likely to be a search engine.

isSyndicationReaderCrawler对于识别特定类型的应用程序很有用。 例如,如果您要编写分析服务,则可能希望使用Crawler从访问者数据中排除这些“匹配项”。 另外,大量缓存的应用程序或网站可能希望在爬虫识别出可能是搜索引擎的请求后,确保它是最新的。

isMobileDevice is an interesting one – and arguably the most useful. What actually constitutes a mobile device is open to interpretation, but generally speaking it will give us that all important distinction between, say, a desktop computer and a mobile phone.

isMobileDevice是一个有趣的–可以说是最有用的。 真正构成移动设备的是可以解释的,但总的来说,它将为我们提供台式计算机和移动电话之间的所有重要区别。

Dealing with the “edge cases” of isMobileDevice is outside the scope of this article, and furthermore often depends on the project. For example, should an iPad or Android tablet get the desktop of mobile version of a site – or should there be a specific tablet version?

处理isMobileDeviceisMobileDevice情况”不在本文的讨论范围之内,而且通常取决于项目。 例如,iPad或Android平板电脑应该使用网站的移动版本的台式机,还是应该有特定的平板电脑版本?

We’ve called getBrowser() without any additional arguments in the example, which means that the user agent string will be taken from the request. If you want to play around or do some additional testing, you can pass a user agent string as the first parameter, for example:

在示例中,我们没有任何其他参数地调用了getBrowser() ,这意味着用户代理字符串将从请求中获取。 如果您想玩转游戏或进行其他测试,则可以将用户代理字符串作为第一个参数传递,例如:

$current_browser = $bc->getBrowser(
"Opera/9.80 (J2ME/MIDP; Opera Mini/9.80 (S60; SymbOS; Opera Mobi/23.348; U; en) Presto/2.5.25 Version/10.54"
);

Additionally, passing true as a third argument will cause the function to return the Browscap data as an array, rather than an object, as its default format.

此外,将true作为第三个参数传递将使该函数将Browscap数据作为数组(而不是对象)作为其默认格式返回。

使用Browscap重定向到移动网站 (Using Browscap to Redirect to a Mobile Site)

Now let’s look at some practical examples of how you might use Browscap data. Suppose you have a separate mobile website, perhaps on a subdomain – e.g. m.example.com – or perhaps using a different TLD, e.g. example.mobi. You could simply intercept all requests to the desktop site, and redirect mobile visitors to the corresponding site by using a hook. In this case we use slim.before, which is invoked before the Slim application is run:

现在,让我们来看一些有关如何使用Browscap数据的实际示例。 假设您有一个单独的移动网站,可能位于子域(例如m.example.com)上 ,或者使用其他TLD(例如example.mobi)。 您可以简单地拦截对桌面站点的所有请求,然后使用挂钩将移动访问者重定向到相应的站点。 在这种情况下,我们使用slim.before ,它在运行Slim应用程序之前被调用:

$app->hook('slim.before', function () use ($app) {
// create a new Browscap object (loads or creates the cache)
$bc = new Browscap('../cache');
// get information about the current browser's user agent
$current_browser = $bc->getBrowser();
// redirect to the mobile site if this is mobile
if ($current_browser->isMobileDevice) {
$url = 'http://m.example.com';
$app->response()->redirect($url, 301);
}
});

Of course this isn’t terribly useful in iteslf; a request for, say, http://example.com/about would be redirected to http://m.example.com, that is to say the mobile site’s homepage. However if you know that the site structure of the mobile site matches that of the desktop site, you can make it a little more useful by analyzing the requested URL:

当然,这在iteslf中不是非常有用; 对http://example.com/about的请求将重定向到http://m.example.com ,即移动网站的首页。 但是,如果您知道移动网站的站点结构与桌面站点的站点结构相匹配,则可以通过分析请求的URL使它更有用:

if ($current_browser->isMobileDevice) {
$path = $app->request()->getResourceUri();
$url = 'http://m.example.com' . $path;
$app->response()->redirect($url, 301);
}

使用Browscap进行布局切换 (Using Browscap for Layout Switching)

Another common use for Browscap data is to perform server-side layout switching for desktop vs. mobile sites. Let’s take our bare-bones Slim-based application, and do exactly that.

Browscap数据的另一个常见用法是为台式机站点与移动站点执行服务器端布局切换。 让我们来看看基于Slim的基本应用程序,并做到这一点。

The first thing to do is update the composer.json file to specify a new dependency, a handy little library we’ll be using to implement layouts: github.com/petebrowne/slim-layout-view.

要做的第一件事是更新composer.json文件以指定新的依赖关系,这是我们将用于实现布局的便捷的小库: github.com/petebrowne/slim-layout-view 。

{
"require": {
"slim/slim": "2.2.*",
"browscap/browscap-php": "1.0.*@dev",
"petebrowne/slim-layout-view": "0.1.*"
}
}

Now run:

现在运行:

php composer.phar update

This should install the code for a new View class which will wrap the output of our application in a layout view.

这应该为新的View类安装代码,该类会将应用程序的输出包装在布局视图中。

Now in your project root, create a templates directory. Within that a layouts directory, and in that two files – desktop.php and mobile.php.

现在,在项目根目录中,创建一个templates目录。 在该layouts目录中,以及在两个文件中– desktop.phpmobile.php

Keeping it simple for now, desktop.php would look something like this:

现在保持简单, desktop.php看起来像这样:

<!DOCTYPE html>
<html>
<body>
<h1>This is the Desktop Layout</h1>
<?php echo $yield ?>
</body>
</html>

mobile.php would look something like this:

mobile.php看起来像这样:

<!DOCTYPE html>
<html>
<body>
<h1>This is the Mobile Layout</h1>
<?php echo $yield ?>
</body>
</html>

These are extremely simple examples, but they’re enough to test out layout switching.

这些是非常简单的示例,但是足以测试布局切换。

Now change the instantiation of Slim to:

现在将Slim的实例化为:

$app = new SlimSlim(array(
'view' => 'SlimLayoutView',
'templates.path' => '../templates',
'layout' => 'layouts/desktop.php'
));

What we’re doing here is telling Slim to use layouts, specifying the templates directory we created a moment ago, and defaulting to our desktop layout.

我们在这里所做的就是告诉Slim使用布局,指定我们刚才创建的模板目录,并默认使用桌面布局。

Now create a file in templates called home.php, for example:

现在,在名为home.php模板中创建一个文件,例如:

<p>Hello World!</p>

And change your route to:

并将您的路线更改为:

$app->get('/', function () use ($app) {
$app->render('home.php');
});

Visit the page and you should see the heading “This is the Desktop Layout” followed by “Hello World!”.

访问页面,您应该看到标题“ This is the Desktop Layout”,然后是“ Hello World!”。

Okay, now we need to add the ability to dynamically switch layouts for mobile. To do this we’re going to build some middleware. This middleware will be run during the request life cycle and will be responsible for detecting a mobile visitor and switching the layout accordingly.

好的,现在我们需要添加动态切换手机布局的功能。 为此,我们将构建一些中间件。 该中间件将在请求生命周期内运行,并将负责检测移动访问者并相应地切换布局。

To create middleware, we simply extend SlimMiddleware and define a call() method. Keep in mind it’s also the responsibility of each item of middleware to call the next one in Slim.

要创建中间件,我们只需扩展SlimMiddleware并定义一个call()方法。 请记住,在Slim中调用下一个中间件也是每个中间件的责任。

Here’s our skeleton middleware:

这是我们的骨架中间件:

class LayoutSwitcherMiddleware extends SlimMiddleware
{
public function call() {
// get reference to application
$app = $this->app;
// call the next middleware
$this->next->call();
}
}

Now we need to add this to the application, so right after we instantiate the Slim framework, add this line:

现在我们需要将其添加到应用程序中,因此在实例化Slim框架之后,添加以下行:

$app->add(new DeviceSwitcherMiddleware());

If you visit the page, the device switcher should run – feel free to echo something out to verify that this is the case.

如果您访问该页面,则设备切换器应运行-随时回显某些内容以验证是否是这种情况。

Switching layouts is straightforward; all we need to do is grab the device information from the Browscap library, try and identify a mobile visitor, and if that’s the case then override the default layout.

切换布局很简单; 我们需要做的就是从Browscap库中获取设备信息,尝试识别移动访问者,如果是这种情况,则覆盖默认布局。

To do this, add these lines before the line $this->next->call():

为此,请在$this->next->call()行之前添加以下行:

// create a new Browscap object (loads or creates the cache)
$bc = new Browscap('../cache');
// get information about the current browser's user agent
$current_browser = $bc->getBrowser();
// switch to the corresponding layout if this is mobile
if (!$current_browser->isMobileDevice) {
$app->config('layout', 'layouts/mobile.php');
}

If you visit the page using a mobile device, you should see the mobile layout being used.

如果您使用移动设备访问该页面,则应该看到正在使用的移动布局。

In practice, your desktop and mobile layouts can include separate stylesheets, handle navigation differently, include or exclude regions, and so on.

实际上,您的桌面布局和移动布局可以包括单独的样式表,以不同方式处理导航,包括或排除区域等等。

The eagle-eyed among you will notice that I’ve made a big but all-to-common oversight. It’s my view – a common one, I hope – that whilst it’s all good-and-well to serve a mobile website by default, it should always be possible for a mobile user to visit the desktop version of a site if they so wish. I won’t go into too much detail, but one approach might be to provide a link with a flag – e.g. ?desktop=true, which sets a cookie that overrides the automatic layout-switching behaviour.

你们当中鹰眼的人会注意到,我做了一个很大但却很普遍的疏忽。 我的看法-我希望这是一种常见的看法-尽管默认情况下为移动网站提供服务是件好事,但移动用户始终可以根据需要访问桌面版网站。 我不会赘述过多,但是一种方法可能是提供带有标志的链接–例如?desktop = true ,它设置一个cookie来覆盖自动布局切换行为。

将服务器端布局切换与RWD相结合 (Combining Server-Side Layout Switching with RWD)

Although server-side layout switching and responsive web design are two different approaches to the same problem, there’s no reason they can’t be used in unison. For example, there’s no reason why you cannot have different layouts for different groups of devices, but keep these layouts responsive too – after all, even among what you might classify mobile devices, the possible variation in things like screen resolution can be huge.

尽管服务器端布局切换和响应式Web设计是解决同一问题的两种不同方法,但没有理由不能同时使用它们。 例如,没有理由不能为不同的设备组设置不同的布局,而是使这些布局也保持响应性-毕竟,即使是在对移动设备进行分类的过程中,诸如屏幕分辨率之类的变化也可能很大。

另一个例子–软件网站 (Another Example – a Software Website)

Knowing what operating system someone is using when browsing a website can be useful too. Let’s suppose you’re building a simple website to promote an application which is available for Windows, Mac, and Linux. It’s common on such websites to simplify such a website’s download page to try and guess which version the user is looking for. For example, if you access the site using a Mac, it’d show the corresponding download link most prominently – not forgetting, of course, that people may still wish to download alternate versions.

知道某人在浏览网站时使用的操作系统也很有用。 假设您正在构建一个简单的网站来推广适用于Windows,Mac和Linux的应用程序。 在此类网站上通常会简化此类网站的下载页面,以尝试猜测用户正在寻找哪个版本。 例如,如果您使用Mac访问该网站,则会最显眼地显示相应的下载链接-当然,不要忘记人们仍然希望下载其他版本。

Here’s one way in which you might do this in a template file:

这是在模板文件中执行此操作的一种方法:

<?php if (!strncmp($current_browser->Platform, 'Win', 3)): ?>
<p><a href="/downloads/windows.zip" class="btn btn-large btn-primary">Download for Windows</a></p>
<p>Alternatively, download for <a href="/downloads/mac.dmg">Mac</a> or <a href="/downloads/linux.tar.gz">Linux</a>.</p>
<?php elseif (!strncmp($current_browser->Platform, 'Mac', 3)): ?>
<p><a href="/downloads/mac.dmg" class="btn btn-large btn-primary">Download for Mac</a></p>
<p>Alternatively, download for <a href="/downloads/windows.zip">Windows</a> or <a href="/downloads/linux.tar.gz">Linux</a>.</p>
<?php elseif ($current_browser->Platform == 'Linux'): ?>
<p><a href="/downloads/linux.tar.gz" class="btn btn-large btn-primary">Download for Linux</a></p>
<p>Alternatively, download for <a href="/downloads/windows.zip">Windows</a> or <a href="/downloads/mac.dmg">Mac</a>.</p>
<?php else: ?>
<p>Select your version:</p>
<ul>
<li><a href="/downloads/windows.zip">Windows</a></li>
<li><a href="/downloads/mac.dmg">Mac</a></li>
<li><a href="/downloads/linux.tar.gz">Linux</a></li>
</ul>
<?php endif; ?>

You’ll find an implementation of this (with styles and icons) in the accompanying code.

您将在随附的代码中找到此实现(带有样式和图标)。

A Windows machine could be indicated by a variety of strings, e.g. Win2000, WinXP, WinVista, Win7… As such, we attempt to identify Windows by looking at the start of the string. Another way would be to examine the Win16, Win32 and Win64 flags in Browscap’s device data. Of course if you’re targeting different versions of Windows, for example separating Vista and Windows 7 versions, you can check for WinVista and Win7 respectively.

Windows机器可以用各种字符串表示,例如Win2000,WinXP,WinVista,Win7等。因此,我们尝试通过查看字符串的开头来识别Windows。 另一种方法是检查Browscap设备数据中的Win16,Win32和Win64标志。 当然,如果您要针对不同版本的Windows(例如,将Vista和Windows 7版本分开),则可以分别检查WinVista和Win7。

最后的例子 (A Final Example)

This one’s pretty self-explanatory!

这是不言自明的!

$current_browser = $bc->getBrowser();
if (($current_browser->Browser == 'IE') && ($current_browser->MajorVer == 6)) {
header('Location: http://www.ie6countdown.com/');
exit;
}

摘要 (Summary)

In this article I’ve introduced the idea of server-side device detection, looking in detail at the Browser Capabilities Project (Browscap). I’ve shown how it can be used as an alternative to – or even to supplement – client-side techniques for adapting websites for multiple devices, such as Responsive Web Design. While my examples use the Slim framework, the principles remain the same whatever your preferred approach.

在本文中,我介绍了服务器端设备检测的概念,详细介绍了浏览器功能项目(Browscap)。 我已经展示了如何将其用作替代或什至补充客户端技术的网站,以使网站适应多种设备,例如响应式Web设计。 尽管我的示例使用了Slim框架,但是无论您采用哪种首选方法,其原理都相同。

I’ve also given you a few ideas about how else you might use Browscap data – if you can think of others, be sure to let me know in the comments!

我还为您提供了一些其他有关如何使用Browscap数据的想法-如果您可以想到其他人,请务必在评论中告知我!

Image via Fotolia

图片来自Fotolia

翻译自: https://www.sitepoint.com/server-side-device-detection-with-browscap/

使用Browscap进行服务器端设备检测相关推荐

  1. win10用什么软件测试硬件,Win10系统下硬件设备检测工具的使用方法

    在win10系统中,自带有硬件设备检测工具,当电脑遇到故障的时候就可以用这个工具来检测并处理,可是许多win10系统用户并不知道要怎么使用硬件设备检测工具,接下来小编就给大家分享一下Win10系统下硬 ...

  2. php cve-2014-9427漏洞,WEB应用漏洞-温州特种设备检测研究院.DOC

    WEB应用漏洞-温州特种设备检测研究院 附件3:重点网站技术检测报告 重点网站 技术检测报告 网站属地:浙江温州 网站名称:温州市特种设备检测研究院 域名:_ 重点网站技术检测报告 经技术检测发现,你 ...

  3. win10系统自带的计算机无法使用吗,Win10如何使用系统自带的硬件设备检测工具?...

    Win10如何使用系统自带的硬件设备检测工具?在Win10操作系统中,自带有硬件设备检测工具,当我们遇到电脑故障时,可以使用这些检测工具来处理故障.下面小编就来教大家使用电脑自带的硬件设备检测工具! ...

  4. CoreAudioApi-音频端点设备-检测耳机插拔

    术语"端点设备"是指位于数据路径一端的硬件设备,该数据路径源自或终止于应用程序.音频终端设备的例子有扬声器.耳机.麦克风和CD播放器.沿着数据路径移动的音频数据可能在应用程序和端点 ...

  5. usb设备检测linux,Linux下USB设备检测全教程(转)

    Linux下USB设备检测全教程(转)[@more@] USB设备检测也是通过/proc目录下的USB文件系统进行的.为了使一个USB设备能够正常工作,必须要现在系统中插入USB桥接器模块.在检测开始 ...

  6. linux usb检测工具,Linux下USB设备检测全教程

    USB设备检测也是通过/proc目录下的USB文件系统进行的.为了使一个USB设备能够正常工作,必须要现在系统中插入USB桥接器模块.在检测开始时,一般要先检测是否存在/proc/bus/usb目录, ...

  7. linux 怎么查看usb设备端口号,嵌入式Linux USB设备检测端口和地址

    我发展我的板USB应用.它有两个USB端口.当我插上USB驱动器在他们每个人我得到控制台以下消息:嵌入式Linux USB设备检测端口和地址 端口1: usb 1-1: new high speed ...

  8. Linux 系统USB设备检测

    Linux 系统USB设备检测 Linux下查看USB设备命令: 参考链接: https://wenku.baidu.com/view/a33c0d616aeae009581b6bd97f192279 ...

  9. 计算机自带的配置检测,Windows10系统自带电脑硬件设备检测工具的使用步骤

    windows10系统在使用过程中,有时候会遇到一些系统故障,那么我们可以使用自带的电脑硬件设备检测工具来进行处理,但是很多用户不知道Windows10系统自带电脑硬件设备检测工具如何使用,本文就给大 ...

最新文章

  1. O027、看nova-scheduler如何选择计算节点
  2. lambda表达式_在Java 7或更早版本中使用Java 8 Lambda表达式
  3. Spring MVC 4.1 支持jsonp
  4. 【NLP】文本生成?还不快上知识库
  5. 汇编常用命令、指令一览
  6. 赌场圣手(从不失手)——隐马尔可夫!
  7. JAVA描述算法和数据结构(01):稀疏数组和二维数组转换
  8. mysql(mariadb)重装
  9. 程序员私活app排行_iOS程序员,失业就等于成为废人?
  10. SAP License:为什么一些现有成熟客户不愿意上S/4
  11. 爬虫-芒果TV-弹幕评论
  12. elk日志收集系统 linux_ELK 日志分析系统
  13. 随手记--计算机网络原理
  14. 极化码理论及算法研究3-Arikan原版论文学习总结
  15. java填空题_JAVA填空题复习(有答案).doc
  16. 摄像头视频直播方案比较之方案二:乐橙云
  17. CHERRY 键盘 alt 组合键失灵或开始菜单键失灵
  18. From Nand to Tetris Week1 超详细2021
  19. WANLSHOP 直播短视频种草多用户电商系统源码自营+多商户+多终端(H5+小程序+APP)
  20. MYSQL数据库设计和数据库设计实例(二)

热门文章

  1. 【JS】原始值与引用值、执行上下文与作用域链、作用域链增强、变量声明、标识符查找
  2. php项目中国站,index.php · WordPress中国本土化项目/wp-china-yes - Gitee.com
  3. 三星I699 基带FK20 刷机超详细教程,实测!
  4. 新版中日交流标准日本语初级第八课之基本课文I
  5. 【Lecture 3.1】a nested data structure
  6. 数据中台的业务价值与技术价值 | 文末有福利
  7. TabLayout的使用
  8. 【MySQL】左连接右连接内连接与Hash连接、子查询原理与实战(MySQL专栏启动)
  9. 一种通过刷写替换boot的方法
  10. 关于爬取吉他堂的吉他谱----Python爬虫