您需要做两件事。首先,您需要将网站图标请求重定向到脚本。您可以通过两种方式做到这一点。第一个是在您的.htaccess
文件中添加类似以下内容
RewriteEngine on
RewriteRule ^/favicon.ico /favicon.php [L]
或者您可以在 html 代码中发送另一个网站图标位置。但是,我不会使用它直接重定向到 php 脚本,因为某些浏览器在正确使用 favicon 时会出现问题,如果它不是真正的 a.ico
或.png
文件。也许您可以使用它来重定向到另一个favicon.ico
位置并将其与.htaccess
. 我为所有设置使用了一个图标位置,这并不是真正需要的。但是这样你就知道如何改变它了。
<link rel="icon" href="/favicon.ico" type="image/x-icon">
<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
<link rel="icon" href="/favicon.ico" type="image/x-icon" sizes="32x32">
<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon" sizes="32x32">
由于您正在重定向到 PHP 脚本,因此您可以使用下面的代码来处理实际请求。
<?php
//the location of the actual favicon
$favicon = '/favicon.ico';
$protocol = (isset($_SERVER['SERVER_PROTOCOL'])) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0';
//try to get the file info, to be able to get the correct content type
//if it doesnt work, return 404 error
$size = @getimagesize($favicon);
if (!$size) {
header($protocol . ' 404 Not Found');
exit();
}
// Content type
header('Content-type: ' . $size[2]);
//when is the icon last modified
//Keep in mind that if you modify the icon, all returning visitors will be handled as new visitors
$last_modified_time = @filemtime($favicon);
header("Accept-Ranges: bytes");
//set a long max-age with a recheck marker, so people check if the icon is still the same and thus access this script.
header("Cache-Control: max-age=15724800, public, must-revalidate");
header("Vary: Accept-Encoding");
//some say the Etag is bad, some say it isnt. You can remove this part if you dont want to use it.
header("Etag: " . md5($favicon . $last_modified_time));
// exit if not modified
if (array_key_exists('HTTP_IF_MODIFIED_SINCE', $_SERVER)) {
if (@strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == $last_modified_time) {
header($protocol .' 304 Not Modified');
/*
At this point you have a returning visitor.
*/
DoSomethingWithReturningVisitor();
exit();
}
}
// exit if not modified using Etag, remove it if you dont want to use it.
if (array_key_exists('HTTP_IF_NONE_MATCH', $_SERVER)) {
if ($_SERVER['HTTP_IF_NONE_MATCH'] == md5($favicon . $last_modified_time)) {
header($protocol.' 304 Not Modified');
/*
At this point you have a returning visitor.
*/
DoSomethingWithReturningVisitor();
exit();
}
}
//you are sending a new image to the user. Add the last modified time.
header("Last-Modified: ".gmdate("D, d M Y H:i:s", $last_modified_time)." GMT");
//log that he is a new visitor
//If you dont to this, the user will be marked as returning visitor when he visits the 2nd page of your website
$_SESSION['newVisitor'] = true;
//return the content of the actual image
echo file_get_contents($favicon);
//A single point to handle returning visitors
//make sure you dont have any output in this function, because you are still returning a valid favicon. If you have any output the returned icon will be corrupted.
function DoSomethingWithReturningVisitor() {
if (!empty($_SESSION['newVisitor']) && $_SESSION['newVisitor'] === true) {
//already marked as new visitor, so skip for this session
return;
}
//do something to give this user special treatment
$_SESSION['returningVisitor'] = true;
}
?>
现在,在对您的网页的第一次请求中,这将很难跟踪。因为首先会向您的主页发出请求,然后它会尝试加载favicon.ico
. 因此,新/回访者的信息不能直接在 php 中获得。检查主页顶部是否是回访者的最佳方法是
<?php
if (empty($_SESSION['returningVisitor']) && empty($_SESSION['newVisitor'])) {
//unknown if user is new or not
} else if (!empty($_SESSION['returningVisitor']) && $_SESSION['returningVisitor']===true) {
//returning visitor
} else {
//new visitor
}
?>
如果您真的需要在主页(或用户请求作为此会话的第一页的任何其他页面)上知道它,您最好的选择是在加载文档时进行 ajax 调用,即使超时时间很短,因为favicon.ico 请求并不总是正文的一部分。