检查有效的 gravatar (PHP)

Check for valid gravatar (PHP)

提问人:Jeff 提问时间:7/27/2009 最后编辑:Jeff 更新时间:8/7/2012 访问量:5970

问:

我是PHP的新手,所以如果你有任何想法或建议,为我指明正确的方向,我将不胜感激。

尝试制作一个简单的功能来检查用户的电子邮件地址是否转换为有效的Gravatar图像,但似乎 gravatar.com 更改了他们的标题。

using 返回 200 而不是 302。get_headers('[email protected]')

以下是来自不良 gravatar 图像的标题,它们似乎都无济于事,因为它们与有效的 gravatar 图像相同:

array(13) {
  [0]=>
  string(15) "HTTP/1.1 200 OK"
  [1]=>
  string(13) "Server: nginx"
  [2]=>
  string(35) "Date: Sun, 26 Jul 2009 20:22:07 GMT"
  [3]=>
  string(24) "Content-Type: image/jpeg"
  [4]=>
  string(17) "Connection: close"
  [5]=>
  string(44) "Last-Modified: Sun, 26 Jul 2009 19:47:12 GMT"
  [6]=>
  string(76) "Content-Disposition: inline; filename="5ed352b75af7175464e354f6651c6e9e.jpg""
  [7]=>
  string(20) "Content-Length: 3875"
  [8]=>
  string(32) "X-Varnish: 3883194649 3880834433"
  [9]=>
  string(16) "Via: 1.1 varnish"
  [10]=>
  string(38) "Expires: Sun, 26 Jul 2009 20:27:07 GMT"
  [11]=>
  string(26) "Cache-Control: max-age=300"
  [12]=>
  string(16) "Source-Age: 1322"
}

p.s. 我知道这个参数,但它不符合我的目的。:)'&d'

编辑:

使用代替 .一定是 gravatar.com'thang。'?d''&d'

php gravatar

评论

5赞 Arjan 7/27/2009
(附带说明:根据RFC2607,在文档中,请始终使用 @example.com、@example.org 或 @example.net - 无需让 address.com 的人收到您的垃圾邮件。
0赞 Jeff 7/27/2009
啊啊!我也知道这一点。哈哈,固定的。

答:

2赞 pixeline 7/27/2009 #1

我建议你试试卢卡斯·阿劳霍(Lucas Araújo)的php gravatar类

/**
*  Class Gravatar
*
* From Gravatar Help:
*        "A gravatar is a dynamic image resource that is requested from our server. The request
*        URL is presented here, broken into its segments."
* Source:
*    http://site.gravatar.com/site/implement
*
* Usage:
* <code>
*        $email = "[email protected]";
*        $default = "http://www.yourhost.com/default_image.jpg";    // Optional
*        $gravatar = new Gravatar($email, $default);
*        $gravatar->size = 80;
*        $gravatar->rating = "G";
*        $gravatar->border = "FF0000";
*
*        echo $gravatar; // Or echo $gravatar->toHTML();
* </code>
*
*    Class Page: http://www.phpclasses.org/browse/package/4227.html
*
* @author Lucas Araújo <[email protected]>
* @version 1.0
* @package Gravatar
*/
class Gravatar
{
    /**
     *    Gravatar's url
     */
    const GRAVATAR_URL = "http://www.gravatar.com/avatar.php";

    /**
     *    Ratings available
     */
    private $GRAVATAR_RATING = array("G", "PG", "R", "X");

    /**
     *    Query string. key/value
     */
    protected $properties = array(
        "gravatar_id"    => NULL,
        "default"        => NULL,
        "size"            => 80,        // The default value
        "rating"        => NULL,
        "border"        => NULL,
    );

    /**
     *    E-mail. This will be converted to md5($email)
     */
    protected $email = "";

    /**
     *    Extra attributes to the IMG tag like ALT, CLASS, STYLE...
     */
    protected $extra = "";

    /**
     *    
     */
    public function __construct($email=NULL, $default=NULL) {
        $this->setEmail($email);
        $this->setDefault($default);
    }

    /**
     *    
     */
    public function setEmail($email) {
        if ($this->isValidEmail($email)) {
            $this->email = $email;
            $this->properties['gravatar_id'] = md5(strtolower($this->email));
            return true;
        }
        return false;
    }

    /**
     *    
     */
    public function setDefault($default) {
        $this->properties['default'] = $default;
    }

    /**
     *    
     */
    public function setRating($rating) {
        if (in_array($rating, $this->GRAVATAR_RATING)) {
            $this->properties['rating'] = $rating;
            return true;
        }
        return false;
    }

    /**
     *    
     */
    public function setSize($size) {
        $size = (int) $size;
        if ($size <= 0)
            $size = NULL;        // Use the default size
        $this->properties['size'] = $size;
    }

    /**
     *    
     */
    public function setExtra($extra) {
        $this->extra = $extra;
    }

    /**
     *    
     */
    public function isValidEmail($email) {
        // Source: http://www.zend.com/zend/spotlight/ev12apr.php
        return eregi("^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$", $email);
    }

    /**
     *    Object property overloading
     */
    public function __get($var) { return @$this->properties[$var]; }

    /**
     *    Object property overloading
     */
    public function __set($var, $value) {
        switch($var) {
            case "email":    return $this->setEmail($value);
            case "rating":    return $this->setRating($value);
            case "default":    return $this->setDefault($value);
            case "size":    return $this->setSize($value);
            // Cannot set gravatar_id
            case "gravatar_id": return;
        }
        return @$this->properties[$var] = $value;
    }

    /**
     *    Object property overloading
     */
    public function __isset($var) { return isset($this->properties[$var]); }

    /**
     *    Object property overloading
     */
    public function __unset($var) { return @$this->properties[$var] == NULL; }

    /**
     *    Get source
     */
    public function getSrc() {
        $url = self::GRAVATAR_URL ."?";
        $first = true;
        foreach($this->properties as $key => $value) {
            if (isset($value)) {
                if (!$first)
                    $url .= "&";
                $url .= $key."=".urlencode($value);
                $first = false;
            }
        }
        return $url;    
    }

    /**
     *    toHTML
     */
    public function toHTML() {
        return     '<img src="'. $this->getSrc() .'"'
                .(!isset($this->size) ? "" : ' width="'.$this->size.'" height="'.$this->size.'"')
                .$this->extra
                .' />';    
    }

    /**
     *    toString
     */
    public function __toString() { return $this->toHTML(); }
} 

这就是你使用它的方式:

include 'gravatar.php';
$eMail = '[email protected]';
$defImg = 'http://www.example.com/images/myphoto.jpg';
$avatar = new Gravatar($eMail, $defImg);
$avatar->setSize(90);
$avatar->setRating('G');
$avatar->setExtra('alt="my gravatar"');

<p>
<?php echo $avatar->toHTML(); ?>
</p>

评论

1赞 hobodave 7/27/2009
我建议修改类以替换对 eregi 的已弃用(自 5.3 起)调用,并将 preg_match 与 /i 一起使用
0赞 Jeff 7/27/2009
非常感谢回复,但我只需要一个函数来检查有效的 gravatar 图像。如果未找到有效图像,则该函数需要返回 FALSE。除非我忽略了它,否则我在上面的类中没有看到代码。
0赞 Richy B. 7/27/2009 #2

文件名(内容处置:内联;文件名=“5ed352b75af7175464e354f6651c6e9e.jpg”)是否与“未找到/无效”Gravatar图像一致?如果是这样,您可以使用它来识别无效图像吗?

评论

0赞 Jeff 7/27/2009
我希望它是一致的,但每个电子邮件地址都不同,无论它是否是有效的 gravatar。 :(
0赞 Ken Keenan 7/27/2009
即使文件名不是,无效电子邮件地址的内容是否相同?也许您可以获取已知“无效”响应的 MD5 哈希值,并用它来比较......
0赞 Jeff 7/27/2009
是的,即使文件名不是,无效电子邮件地址的内容也是相同的。问题是,有效响应与无效响应相同。
-1赞 Philippe Gerber 7/27/2009 #3

一个真正不高性能的解决方案可能是发布到 http://en.gravatar.com/accounts/signup 并检查......emailSorry, that email address is already used!

编辑

好的,他们使用一些cookie来指示是否发生了错误... ;-)

function isUsed($email)
{
    $url   = 'http://en.gravatar.com/accounts/signup';
    $email = strtolower($email);

    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, 'commit=Signup&email=' . urlencode($email));
    curl_setopt($ch, CURLOPT_HEADER, true);
    $response = curl_exec($ch);
    curl_close($ch);

    return (false !== strpos($response, 'Set-Cookie: gravatar-notices'));
}

var_dump(isUsed('[email protected]'));

评论

3赞 scunliffe 7/27/2009
我不认为Gravatar的人会对这种方法过于热情。;-)
0赞 Philippe Gerber 7/27/2009
然后他们应该提供一个 API ... ;-)
1赞 Jeff 7/27/2009
re: API;我完全同意。他们最近将无效重力上的 302 更改为 200......可能正是出于这个目的。他们为什么不允许网站管理员检查无效图像?毫无意义。
0赞 scunliffe 7/27/2009 #4

一旦你得到这些信息,不确定你想如何使用它......但是你能:

将图像加载到网页上,并附加 onload 或 onerror 处理程序...如果 OnLoad 触发,则您有一个匹配项,如果 OnError 触发,则它不存在(或加载它时出现问题)

例如

<img
  src="http://www.gravatar.com/avatar/282eed17fcb9682bb2816697482b64ec?s=128&d=identicon&r=PG"
  onload="itWorked();"
  onerror="itFailed();"/>

评论

0赞 Jeff 7/27/2009
我认为这行不通,因为图像永远不会失败......始终是 200 个响应。
4赞 Arjan 7/27/2009 #5

注意:在撰写本文时,这是唯一的选择。然而,后来增加了一些时间,使安德鲁的答案更加清晰。?d=404


虽然你说你知道 d 参数,但你知道它在适用时实际上会返回一个重定向标头吗?因此,由于头像不存在,因此产生了 302 Found:

http://www.gravatar.com/avatar/3b3be63a4c2a439b013787725dfce802?d=http%3A%2F%2Fwww.google.com%2Fimages%2Flogo.gif

HTTP/1.1 302 Found  
...  
Last-Modified: Wed, 11 Jan 1984 08:00:00 GMT  
Location: http://www.google.com/images/logo.gif  
Content-Length: 0  
...  
Expires: Sun, 26 Jul 2009 23:18:33 GMT  
Cache-Control: max-age=300

在我看来,您需要做的就是添加该参数并检查HTTP结果代码。d

评论

1赞 Jeff 7/27/2009
这行得通。似乎决定因素是使用“?d=”与使用“&d=' 表示默认重力。
2赞 Arjan 7/27/2009
第一个 GET 参数必须始终以问号为前缀;所有后续参数都使用与号分隔。
0赞 cweiske 8/5/2012
将 302 状态代码解释为失败是非常可疑的。只需使用 404 默认值,即可设置。
0赞 Arjan 8/5/2012
@cweiske,如果 Gravatar 返回 404,那将是真的。但事实并非如此。那么,如何对未退回的 404 采取行动呢?
0赞 Arjan 8/5/2012
啊,我明白了,因为有些时间也允许简单地.@Jeff,你能接受安德鲁的回答,这样我就可以删除这个了吗??d=?d=404
1赞 Jason 7/27/2009 #6

在检查 Gravatar 时将“default”参数添加到图像 URL,如果找不到图像,这将提供 302 重定向。

$grav_url = 'http://www.gravatar.com/avatar/'.md5(mb_strtolower($email)).'?default=http://www.mysite.com/null.jpg&size=310';

然后,如果希望 null 图像:),则 null 图像可以返回 404

评论

0赞 Jason 7/27/2009
不知道为什么它被修改了,我让它在生产环境中完美运行。
0赞 Jeff 7/27/2009
我也不确定,可能是因为原始问题已经提到了默认参数。为了因果报应和帮助,投了赞成票。
0赞 Arjan 8/5/2012
或者,正如我一天前发布的相同答案?无论如何,安德鲁的回答已经过时了,所以我想我的和你的现在可以删除了!
6赞 Andrew Aylett 1/25/2010 #7

Gravatar在“d”参数中添加了一个选项,这意味着如果你传入d=404,如果没有图片,你会得到一个404页面(而不是重定向到默认图片),而不必使用启发式方法。302

1赞 Salvador #8

扩展 Andrew Aylett 关于 d=404 的答案,实际上可以用 (或 ) 编写 Gravatar 查询,然后查看 key 是否包含值 404200 的标头。d=404default=404[0]

$email = md5(strtolower("[email protected]"));
$gravatar = "http://www.gravatar.com/avatar/$email?d=404";
$headers = get_headers($gravatar,1);
if (strpos($headers[0],'200')) echo "<img src='$gravatar'>"; // OK
else if (strpos($headers[0],'404')) echo "No Gravatar"; // Not Found

最初的问题可以追溯到三年前。也许在那个时候,Gravatar的头球略有不同。