Проверить действующий граватар (PHP)

Я новичок в PHP, поэтому, если у вас есть какие-либо мысли или предложения, чтобы указать мне правильное направление, я был бы признателен.

Попытка сделать простую функцию, чтобы проверить, транслируется ли адрес электронной почты пользователя в действительное изображение Gravatar, но, похоже, gravatar.com изменил свои заголовки.

Использование get_headers('[email protected]') возвращает 200 вместо 302.

Вот заголовки из плохого изображения граватара, ни один из которых, кажется, не может помочь, потому что они идентичны правильному изображению граватара:

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', но он не будет служить моей цели. :)

ИЗМЕНИТЬ:

Используйте '?d' вместо '&d'. Должно быть, это gravatar.com.


person Jeff    schedule 26.07.2009    source источник
comment
(Небольшое примечание: согласно RFC2607, в документации всегда используйте @example.com, @example.org или @example.net — не нужно, чтобы люди с адреса address.com получали ваш спам.)   -  person Arjan    schedule 27.07.2009
comment
Ааа! Я тоже это ЗНАЛ. ЛОЛ, исправлено.   -  person Jeff    schedule 27.07.2009


Ответы (8)


ПРИМЕЧАНИЕ: на момент написания это был единственный вариант. Однако позже был добавлен ?d=404, что сделало ответ Эндрю намного чище .


Хотя вы сказали, что знаете о параметре d, знаете ли вы, что он на самом деле возвращает перенаправление? заголовок, когда это применимо? Итак, следующий 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.

person Arjan    schedule 26.07.2009
comment
Это работает. Похоже, определяющим фактором является использование «?d=» по сравнению с использованием «d=» для граватара по умолчанию. - person Jeff; 27.07.2009
comment
Перед параметром first GET всегда должен стоять вопросительный знак; все последующие параметры разделяются амперсандом. - person Arjan; 27.07.2009
comment
Интерпретировать код состояния 302 как сбой очень подозрительно. Просто используйте 404 по умолчанию, и все готово. - person cweiske; 04.08.2012
comment
@cweiske, это было бы правдой, если бы Gravatar возвращал 404. Но нет. Итак, как можно действовать с ошибкой 404, которая не возвращается? - person Arjan; 04.08.2012
comment
Ах, я вижу, ?d= с некоторых пор также позволяет просто ?d=404. @ Джефф, ты можешь принять ответ Эндрю, чтобы я мог удалить этот? - person Arjan; 04.08.2012


Я предлагаю вам попробовать класс 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>
person pixeline    schedule 26.07.2009
comment
Я бы рекомендовал изменить класс, чтобы заменить устаревший (начиная с 5.3) вызов eregi и использовать preg_match с /i - person hobodave; 27.07.2009
comment
Ответ очень ценен, но мне нужна только функция для проверки действительного изображения граватара. Если действительное изображение не найдено, функция должна вернуть FALSE. Если я не упустил это из виду, я не видел для этого кода в приведенном выше классе. - person Jeff; 27.07.2009

добавьте параметр «по умолчанию» к URL-адресу изображения при проверке граватара, это обеспечит перенаправление 302, если изображение не будет найдено.

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

нулевое изображение может затем вернуть 404, если вы этого хотите :)

person Jason    schedule 27.07.2009
comment
не уверен, почему это изменено, у меня это отлично работает в производственной среде. - person Jason; 27.07.2009
comment
Я тоже не уверен, возможно, потому, что в исходном вопросе уже упоминается параметр по умолчанию. За карму и помощь, проголосовал. - person Jeff; 27.07.2009
comment
Или, как я разместил тот же самый ответ днем ​​ранее? В любом случае, ответ Эндрю устарел, поэтому я думаю, что и мой, и ваш теперь могут быть удалены! - person Arjan; 04.08.2012

Расширяя ответ Эндрю Эйлетта о d = 404, на самом деле можно составить запрос Gravatar с d=404 (или default=404), а затем просмотреть заголовки, если ключ [0] содержит значение 404 или 200< /сильный>.

$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 были немного другими.

person Community    schedule 09.07.2012

Имя файла ( Content-Disposition: inline; filename="5ed352b75af7175464e354f6651c6e9e.jpg" ) соответствует изображениям Gravatar "не найдено/недействительно"? Если это так, вы могли бы использовать это для выявления недопустимых изображений?

person Richy B.    schedule 26.07.2009
comment
Я бы хотел, чтобы он был последовательным, но для каждого адреса электронной почты он разный, независимо от того, является ли он действительным граватаром или нет. :( - person Jeff; 27.07.2009
comment
Одинаково ли содержание для недействительных адресов электронной почты, даже если имя файла отличается? Может быть, вы могли бы взять хэш MD5 известного недопустимого ответа и использовать его для сравнения... - person Ken Keenan; 27.07.2009
comment
Да, содержание одинаково для недействительных адресов электронной почты, хотя имя файла отличается. Проблема в том, что правильные ответы идентичны неправильным ответам. - person Jeff; 27.07.2009

Не уверен, как именно вы хотите использовать эту информацию, когда вы ее получите... но не могли бы вы:

Загрузите изображение на веб-страницу с прикрепленным обработчиком onload или onerror... если срабатывает onload, у вас есть совпадение, если срабатывает onerror, оно либо не существует (или есть проблемы с его загрузкой)

e.g.

<img
  src="http://www.gravatar.com/avatar/282eed17fcb9682bb2816697482b64ec?s=128&d=identicon&r=PG"
  onload="itWorked();"
  onerror="itFailed();"/>
person scunliffe    schedule 26.07.2009
comment
Я не думаю, что это сработает, потому что изображение никогда не подводит... Всегда ответ 200. - person Jeff; 27.07.2009

Действительно неэффективным решением может быть публикация 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('[email protected]'));
person Philippe Gerber    schedule 26.07.2009
comment
Я не думаю, что ребята из Gravatar будут в восторге от такого подхода. ;-) - person scunliffe; 27.07.2009
comment
Тогда они должны предоставить API... ;-) - person Philippe Gerber; 27.07.2009
comment
Re: API; Я полностью согласен. Недавно они заменили 302-е на недействительном граватаре на 200-е... вероятно, именно для этой цели. Почему бы им не разрешить веб-мастерам проверять недопустимое изображение? Без разницы. - person Jeff; 27.07.2009