我有一个多语言页面,我想检测客户端浏览器的语言,然后制作一个 301 主页或其他东西。但我不确定哪种方式更适合 seo。不知道web spider喜欢哪一个?还是其他方式?
<?php
$LG=$_SERVER['HTTP_ACCEPT_LANGUAGE'];
if (preg_match('/^[zZ][hH]/', $LG)) {
header("HTTP/1.1 301 Moved Permanently");
header("Location: http://mydomain.com/cn/");
exit();} //jump to chinese version
else {
header("HTTP/1.1 301 Moved Permanently");
header("Location: http://mydomain.com/en/");
exit();} //jump to english version
?>
或
<?php
$LG=$_SERVER['HTTP_ACCEPT_LANGUAGE'];
if (preg_match('/^[zZ][hH]/', $LG)) {
include ("http://mydomain.com/cn/");
} //include chinese version
else {
header("HTTP/1.1 301 Moved Permanently");
include ("http://mydomain.com/en/");
} //include english version
?>
或者其他方式?谢谢。
最佳答案
正如您在问题中已经假设的那样,您需要解析 Accept-LanguageHTTP/1.1 header ,在 $_SERVER['HTTP_ACCEPT_LANGUAGE'] 中的 PHP 中可用。首先需要将其解析为您可以在 PHP 中更好地处理的结构,例如数组:
/**
* Convert Accept Language to sorted PHP array
*
* Related HTTP Specs:
* <http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4>
* <http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.9>
*
* @param string $accept header value
* @return array ([language-range] => qvalue, ...)
*/
function http_accept_language_array($accept = NULL)
{
if (!$accept && isset($_SERVER['HTTP_ACCEPT_LANGUAGE']))
$accept = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
$accept = (string) $accept;
$pattern = '/([a-z]{1,8}(-[a-z]{1,8})?)(;q=([01](?:\.[0-9]{0,3})?))?(?=$|,[ ]*)/i';
preg_match_all($pattern, $accept, $matches);
$array = array();
if (count($matches[1]))
{
list(, $ranges,,, $qvals) = $matches;
# normalize ranges
foreach ($ranges as &$range)
$range = strtolower($range);
unset ($range);
# set default qvalue 1
foreach ($qvals as &$qval)
if ('' === $qval) $qval = '1';
unset ($qval);
$array = array_combine($ranges, $qvals);
arsort($array, SORT_NUMERIC);
}
return $array;
}
da, en-gb;q=0.8, en;q=0.7 将返回:
array(3) {
["da"] => string(1) "1"
["en-gb"] => string(3) "0.8"
["en"] => string(3) "0.7"
}
然后您需要解析这个排序数组以找到您的第一个匹配项,使用 en 默认值设置您的首选项:
$lang = 'en';
foreach (http_accept_language_array() as $range => $qvalue)
{
if (preg_match('/^zh[$-]/', $range))
{
$lang = 'cn';
break;
}
}
最后,您可以根据 $lang(或 include 或其他)进行重定向:
header("HTTP/1.1 301 Moved Permanently");
header("Location: http://mydomain.com/$lang/");
如果您正在寻找一个现成的库来处理这个问题,一个现有的解决方案是 Symfony's HttpFoundation\Request或者在 PEAR 中有 HTTP::negotiateLanguage .
PHP intl 扩展有另一个相关的低级函数,但它不提供数组,而是提供单个值:locale_accept_from_http
更多 HTTP 相关信息的另一个通用资源是 Advanced handling of HTTP requests in PHP .
关于php - 哪个是检测浏览器语言并将301重定向到主页的最友好的seo方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8091296/
我想使用spawn(针对多个并发子进程)在Ruby中执行一个外部进程,并将标准输出或标准错误收集到一个字符串中,其方式类似于使用Python的子进程Popen.communicate()可以完成的操作。我尝试将:out/:err重定向到一个新的StringIO对象,但这会生成一个ArgumentError,并且临时重新定义$stdxxx会混淆子进程的输出。 最佳答案 如果你不喜欢popen,这是我的方法:r,w=IO.pipepid=Process.spawn(command,:out=>w,:err=>[:child,:out])
我想解析一个已经存在的.mid文件,改变它的乐器,例如从“acousticgrandpiano”到“violin”,然后将它保存回去或作为另一个.mid文件。根据我在文档中看到的内容,该乐器通过program_change或patch_change指令进行了更改,但我找不到任何在已经存在的MIDI文件中执行此操作的库.他们似乎都只支持从头开始创建的MIDI文件。 最佳答案 MIDIpackage会为您完成此操作,但具体方法取决于midi文件的原始内容。一个MIDI文件由一个或多个音轨组成,每个音轨是十六个channel中任何一个上的
我需要一个非常简单的字符串验证器来显示第一个符号与所需格式不对应的位置。我想使用正则表达式,但在这种情况下,我必须找到与表达式相对应的字符串停止的位置,但我找不到可以做到这一点的方法。(这一定是一种相当简单的方法……也许没有?)例如,如果我有正则表达式:/^Q+E+R+$/带字符串:"QQQQEEE2ER"期望的结果应该是7 最佳答案 一个想法:你可以做的是标记你的模式并用可选的嵌套捕获组编写它:^(Q+(E+(R+($)?)?)?)?然后你只需要计算你获得的捕获组的数量就可以知道正则表达式引擎在模式中停止的位置,你可以确定匹配结束
有没有办法跳过CSV文件的第一行,让第二行作为标题?我有一个CSV文件,第一行是日期,第二行是标题,所以我需要能够在遍历它时跳过第一行。我尝试使用slice但它会将CSV转换为数组,我真的很想将其读取为CSV,以便我可以利用header。 最佳答案 根据您的数据,您可以使用另一种方法和skip_lines-option此示例跳过所有以#开头的行require'csv'CSV.parse(DATA.read,:col_sep=>';',:headers=>true,:skip_lines=>/^#/#Markcomments!)do|
eruby和erb有什么区别?哪些考虑因素会促使我选择其中之一?我的应用程序正在为网络设备(路由器、负载平衡器、防火墙等)生成配置文件。我的计划是对配置文件进行模板化,在源文件中使用嵌入式ruby(通过eruby或erb)来执行诸如迭代生成路由器的所有接口(interface)配置block之类的操作(这些block都非常相似,仅在标签上有所不同和IP地址)。例如,我可能有这样一个配置模板文件:hostnamesample-routerlogging10.5.16.26当通过嵌入式ruby解释器(erb或eruby)运行时,会产生以下输出:hostnamesample-rout
我要下载http://foobar.com/song.mp3作为song.mp3,而不是让Chrome在其native中打开它浏览器中的播放器。我怎样才能做到这一点? 最佳答案 您只需要确保发送这些header:Content-Disposition:attachment;filename=song.mp3;Content-Type:application/octet-streamContent-Transfer-Encoding:binarysend_file方法为您完成:get'/:file'do|file|file=File.
我在这方面尝试了很多URL,在我遇到这个特定的之前,它们似乎都很好:require'rubygems'require'nokogiri'require'open-uri'doc=Nokogiri::HTML(open("http://www.moxyst.com/fashion/men-clothing/underwear.html"))putsdoc这是结果:/Users/macbookair/.rvm/rubies/ruby-2.0.0-p481/lib/ruby/2.0.0/open-uri.rb:353:in`open_http':404NotFound(OpenURI::HT
随着ruby被引入为新的编程救世主,我想知道是否有人基于易用性、运行所需的资源、可用性和易定制性而有偏好。两者有更好的吗? 最佳答案 好吧,任何基于Rails的社交网络应用程序的比较都应该包括insoshi(http://portal.insoshi.com/)。话虽这么说,这三个都非常相似,区别在于实现细节。Lovd和Insoshi都是完整的Rails应用程序;它旨在供您将它们用作入门工具包,并使用您自己的自定义功能对其进行扩展。另一方面,CommunityEngine是一个Rails插件。这意味着您可以更轻松地向现有Rail
我有1.8.6附带的VanillaMacOSXLeopard。我是RoR的新手,所以会学习网上的教程。在使用更高版本的Ruby时,我是否可能会发现遵循它们的问题?我目前正在查看提到1.8.6和1.8.7的这个-http://www.railstutorial.org/book 最佳答案 RoR教程对两者都适用,但如果您正在学习Ruby,则应该学习1.9。Rails3将不支持1.8.6,所以我会选择1.8.7或1.9。我还推荐使用RVM在Ruby版本之间切换。 关于ruby-on-rail
使用ruby的watir测试网络应用程序时,浏览器最后会保持打开状态。网上的一些建议是,要进行真正的单元测试,您应该在每次测试时(在拆卸调用中)打开和关闭浏览器,但这很慢而且毫无意义。或者他们做这样的事情:defself.suites=superdefs.afterClass#Closebrowserenddefs.run(*args)superafterClassendsend但这会导致摘要输出不再显示(诸如“100次测试、100次断言、0次失败、0次错误”之类的内容仍应显示)。我怎样才能让ruby或watir在我的测试结束时关闭浏览器? 最佳答案