2009-07-26 16 views
5

Soy bastante nuevo en PHP, así que si tiene alguna idea o sugerencia que me señale en la dirección correcta, le agradecería.Verificar gravatar válido (PHP)

Intentando hacer una función simple para comprobar si la dirección de correo electrónico de un usuario se traduce en una imagen de Gravatar válida, pero parece que gravatar.com ha cambiado sus encabezados.

Usando get_headers('[email protected]') devuelve un 200 en lugar de 302.

Aquí están las cabeceras de una imagen gravatar mal, ninguno de los cuales parecen ser capaces de ayudar, ya que son idénticos a una imagen gravatar válida:

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" 
} 

ps Soy consciente del parámetro '&d', pero no servirá para mi propósito. :)

EDIT:

Uso '?d' en lugar de '&d'. Debe ser un gravatar.com 'thang.

+5

(Solo una nota al margen: según RFC2607, en la documentación siempre use @ example.com, @ example.org o @ example.net - no es necesario que las personas en address.com obtengan su correo no deseado.) – Arjan

+0

Aaah! Yo también lo sabía. LOL, arreglado. – Jeff

Respuesta

4

NOTA: en el momento de la escritura, esta era la única opción. Sin embargo, se agregó un tiempo posterior ?d=404, lo que hace que Andrew's answer sea mucho más limpio.


Aunque se ha dicho que sabe sobre el d parameter, sabes que en realidad devuelve un encabezado de redirección en su caso?Por lo tanto, la siguiente yields 302 encontrados debido a que el avatar no existe:

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 

me parece que todo lo que tiene que hacer es añadir que d parámetro y comprobar el código de resultado HTTP a continuación.

+1

Esto funciona. Parece que el factor determinante es usar '? D =' versus usar '& d =' para el gravatar predeterminado. – Jeff

+2

El * primer * parámetro GET siempre debe ir precedido de un signo de interrogación; todos los parámetros subsiguientes se separan usando el símbolo comercial. – Arjan

+0

Interpretar un código de estado 302 como una falla es muy sospechoso. Solo usa el valor predeterminado 404, y estás listo. – cweiske

2

Te sugiero que pruebes el php gravatar class de Lucas Araújo.

/** 
* 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(); } 
} 

y así es como se lo utilizaría:

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

Recomiendo modificar la clase para reemplazar la llamada en desuso (desde 5.3) a eregi y usar preg_match con/i – hobodave

+0

La respuesta es muy apreciada, pero solo necesito una función para verificar si hay una imagen válida de Gravatar. Si no se encuentra una imagen válida, la función debe devolver FALSE. A menos que lo haya pasado por alto, no vi el código en la clase anterior para eso. – Jeff

0

es el nombre (Content-Disposition: inline; filename = "5ed352b75af7175464e354f6651c6e9e.jpg") consistente para "que no se encuentra/no válido" Gravatar imágenes? Si es así, ¿podría usar eso para identificar imágenes inválidas?

+0

Desearía que fuera consistente, pero es diferente para cada dirección de correo electrónico, ya sea que se trate de un gravatar válido o no. :( – Jeff

+0

¿El contenido es el mismo para las direcciones de correo electrónico no válidas incluso si el nombre del archivo no es? Tal vez podría tomar el hash MD5 de una respuesta conocida como "no válida" y usar eso para comparar ... –

+0

Sí, el contenido es el mismo para las direcciones de correo electrónico no válidas aunque el nombre del archivo no lo sea. El problema es que las respuestas válidas son idénticas a las respuestas no válidas. – Jeff

-1

Una solución muy unperformant podría ser para publicar email a http://en.gravatar.com/accounts/signup y comprobar si hay Sorry, that email address is already used! ...

edición

bien, utilizan alguna cookie para indicar si un error ha ocurrido o no ... ;-)

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]')); 
+2

No creo que la gente de Gravatar esté demasiado entusiasmada con este enfoque. ;-) – scunliffe

+0

Luego debería proporcionar una API ... ;-) –

+1

re: la API; Estoy de acuerdo de todo corazón. Recientemente cambiaron los 302 en un gravatar no válido a 200 ... probablemente para este propósito exacto. ¿Por qué no permitirían que los webmasters comprueben si hay una imagen no válida? No tiene sentido. – Jeff

-1
No

seguro exactamente cómo desea utilizar esta información una vez que lo consigue ... pero podría usted:

Cargue la imagen en una página web, con un controlador de onloadror o onload adjunto ... si la descarga se dispara, tiene una coincidencia, si el onerror se dispara o no existe (o hay problemas al cargarlo)

por ej.

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

No creo que funcione porque la imagen nunca falla ... Siempre una respuesta de 200. – Jeff

+0

Ah, bummer. Supongo que vale la pena leer la pregunta a fondo. – scunliffe

1

agregue el parámetro "predeterminado" a la url de la imagen cuando busque un gravatar, esto proporcionará una redirección 302 si no se encuentra la imagen.

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

la imagen nula podría entonces devolver un 404 si desea que :)

+0

no estoy seguro de por qué esto se modificó, tengo esto funcionando perfectamente en un entorno de producción. – Jason

+0

Tampoco estoy seguro, posiblemente porque la pregunta original ya menciona el parámetro predeterminado. Para el karma y la ayuda, votaron. – Jeff

+0

ah, lo perdí ... – Jason

6

Gravatar han añadido una opción para el parámetro 'd', lo que significa que if you pass in d=404, se obtiene una página 404 (en lugar de algunos 302 redirigen a una imagen predeterminada) si no hay imagen, en lugar de tener que usar heurística.

1

La extensión de la respuesta de Andrew Aylett acerca d = 404, en realidad, es posible componer una consulta con Gravatar d=404 (o default=404), a continuación, busque en las cabeceras si la clave contiene un valor [0] o .

$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 

pregunta original data de hace tres años. Tal vez en ese momento las cosas de los encabezados de Gravatar eran ligeramente diferentes.

Cuestiones relacionadas