【问题标题】:Check for valid gravatar (PHP)检查有效的 gravatar (PHP)
【发布时间】:2009-07-26 20:48:23
【问题描述】:

我对 PHP 还很陌生,所以如果您有任何想法或建议可以为我指明正确的方向,我将不胜感激。

尝试制作一个简单的函数来检查用户的电子邮件地址是否转换为有效的 Gravatar 图片,但似乎 gravatar.com 已更改其标题。

使用 get_headers('urlencoded_bad_email@example.com') 返回 200 而不是 302。

以下是来自不良 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"
}

附言我知道'&d' 参数,但它不符合我的目的。 :)

编辑:

使用'?d' 而不是'&d'。必须是 gravatar.com 'thang.

【问题讨论】:

  • (附注:根据 RFC2607,在文档中请始终使用 @example.com、@example.org 或 @example.net——无需让 address.com 上的人员获取你的垃圾邮件。)
  • 啊啊!我也知道。大声笑,固定。

标签: php gravatar


【解决方案1】:

Gravatar 在 'd' 参数中添加了一个选项,这意味着if you pass in d=404,如果没有图片,你会得到一个 404 页面(而不是一些302 重定向到默认图片),而不必使用启发式.

【讨论】:

    【解决方案2】:

    注意:在撰写本文时,这是唯一的选择。但是,后来添加了?d=404,使Andrew's answer 更加干净。


    虽然您说您知道d parameter,但您知道它在适用时实际上会返回重定向标头吗?所以,下面yields 302 发现因为头像不存在:

    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
    

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

    【讨论】:

    • 这行得通。看来决定因素是使用 '?d=' 而不是使用 '&d=' 作为默认 gravatar。
    • first GET 参数必须始终以问号为前缀;所有后续参数都使用 & 号分隔。
    • 将 302 状态码解释为失败是非常可疑的。只需使用 404 默认值,就可以了。
    • @cweiske,如果 Gravatar 会返回 404,那将是正确的。但是they don't。那么如何处理没有返回的 404 呢?
    • 啊,我明白了,?d=,因为有些时候也可以简单地使用?d=404。 @Jeff,你能接受安德鲁的回答,这样我就可以删除这个吗?
    【解决方案3】:

    我建议您试试 Lucas Araújo 的 php gravatar class

    /**
    *  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 = "youremail@yourhost.com";
    *        $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 <araujo.lucas@gmail.com>
    * @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 = 'name@email.net';
    $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>
    

    【讨论】:

    • 我建议修改类以替换已弃用(自 5.3 起)对 eregi 的调用并将 preg_match 与 /i 一起使用
    • 非常感谢您的回复,但我只需要一个功能来检查有效的 gravatar 图像。如果未找到有效图像,该函数需要返回 FALSE。除非我忽略了它,否则我没有在上面的类中看到代码。
    【解决方案4】:

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

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

    如果您希望空图像返回 404 :)

    【讨论】:

    • 不知道为什么要修改它,我已经在生产环境中完美地工作了。
    • 我也不确定,可能是因为原始问题已经提到了默认参数。对于业力和帮助,投了赞成票。
    • 或者,正如我前一天发布的相同答案?无论如何,这同时已被安德鲁的回答所淘汰,所以我想我的和你的现在都可以删除了!
    【解决方案5】:

    扩展 Andrew Aylett 关于 d=404 的答案,实际上可以使用 d=404(或 default=404)组成 Gravatar 查询,然后如果键 [0] 包含值 404 或 200

    $email = md5(strtolower("myemailaddress@example.com"));
    $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 的 header 内容略有不同。

    【讨论】:

      【解决方案6】:

      文件名 ( Content-Disposition: inline; filename="5ed352b75af7175464e354f6651c6e9e.jpg" ) 对于“未找到/无效”的 Gravatar 图像是否一致?如果是这样,您可以使用它来识别无效图像吗?

      【讨论】:

      • 我希望它是一致的,但每个电子邮件地址都不同,无论它是否是有效的 gravatar。 :(
      • 即使文件名不同,无效邮件地址的内容是否相同?也许您可以获取已知“无效”响应的 MD5 哈希值并使用它来比较...
      • 是的,无效电子邮件地址的内容相同,即使文件名不同。问题是,有效响应与无效响应相同。
      【解决方案7】:

      不确定您在获得此信息后究竟想如何使用它...但是您可以:

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

      例如

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

      【讨论】:

      • 我认为这不会起作用,因为图像永远不会失败...总是 200 响应。
      【解决方案8】:

      一个非常糟糕的解决方案可能是将email 发布到http://en.gravatar.com/accounts/signup 并检查Sorry, 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('test@example.org'));
      

      【讨论】:

      • 我认为 Gravatar 的人们不会对这种方法过分热情。 ;-)
      • 那么他们应该提供一个 API ... ;-)
      • 重新:API;我完全同意。他们最近将无效 gravatar 上的 302 更改为 200……可能正是出于这个目的。为什么他们不允许网站管理员检查无效图片?没有意义。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-24
      • 1970-01-01
      • 2014-08-17
      • 2012-09-03
      相关资源
      最近更新 更多