Информация о сайте по ссылке (upgrade стены как вконтакте)

Здаров-здаров, сегодня я бы хотел поговорить с вами о трудностях воспитания маленькой обезьянки 8| Чо, повелись? =) На самом деле речь пойдет о том, как проапгрейдить мою уникальную авторскую разработку стену как вконтакте. В частности, я расскажу о таком бонусе, как когда вставляешь ссылку, оно заодно автоматом картиночку прифигачит и описание ко всей этой сковороде.

Итак, поехали!

Первым делом нам понадобится функция, которая будет получать содержимое страниц, на которые будут ссылаться спамеры на нашей стене. Для этих целей воспользуемся библиотекой cURL (обычно на хостингах есть, а если у вас нет, попросите хостера включить; если у вас локальный виртуальный сервер, например Денвер, то посмотрите "как установить curl на denwer" в гугле). Всё довольно просто: инициализируем библотэку (сказанул а-ля Гомер Симпсон =)) функцией curl_init(), задаем параметры функцией curl_setopt(), получим кое-какую информацию с помощью curl_getinfo() и закроем всю эту байду функцией curl_close().

Что касается curl_setopt(), я не хочу излишне все разжевывать, вы можете тупо скопировать, не вникая, и просто пользоваться, а можете и вникнуть, тогда вам полезнее будет это сделать самим, покопавшись в инете. Скажу лишь, что для нас самая важная CURLOPT_URL - ею мы задаем адрес страницы, содержимое которой получаем.

Итак, вот функция:

function get_html_file($url) 
{
   $ch = curl_init();
   curl_setopt($ch, CURLOPT_URL, $url);
   curl_setopt($ch, CURLOPT_HEADER, 0);
   curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
   curl_setopt($ch, CURLOPT_USERAGENT, 'Opera/9.80 (Windows NT 6.0) Presto/2.12.388 Version/12.14'); // тут можно написать что угодно, не только мой вариант
   curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
 
   $html = curl_exec($ch);
   $info = curl_getinfo($ch);
 
   curl_close($ch);
 
   if ( !empty($info['content_type']) )
      return '<meta http-equiv="content-type" content="'.$info['content_type'].'">' . $html;
   else
      return $html;
}

Ну... Вот. Чо еще?.. Ну в общем, это самая хорошая функция, что есть 8| С..ка, дебил, бляяяя...
Шутка, едем дальше =)

Надеюсь, что вам не нужно объяснять, что такое DOM. Если нужно, милости просим за помощью к гуглу (блин, я на него столько ссылаюсь, что пора бы им уже приплачивать мне вовсю). То же и с XPath (ну серьезно, там не нужно сильно въезжать, чисто 10 минут разобраться). Нууу на крайняяяк, если у вас совсем уж проблемы с пониманием, пишите в комментах, попробую объяснить на пальцах.

Итак, следующая функция (по адресу страницы берет и возвращает массив с адресом картинки, заголовком страницы и описанием):

function get_data($url) 
{
   $data = array();
 
   $dom = new DOMDocument; // создаем объект DOM
   $dom->preserveWhiteSpace = false;
 
   $file = get_html_file($url); // получаем код страницы
 
   @$dom->LoadHTML($file);
   $dom->normalizeDocument();
   $xpath = new DOMXPath($dom); // создаем объект DOMXPath
 
   $query = "//html/head/meta[@property='og:image']/attribute::content | //img/attribute::src";
   /*
   Здесь мы формируем xpath запрос исходя из того, что хотим получить:
   нам нужно либо содержимое атрибута content тэга meta с атрибутом og:image (такая фигня используется  например для кнопки like фэйсбука), либо, если такового не найдется, адрес любой первой картинки
   */
   $content = $xpath->query($query); // выполняем xpath запрос
   $data['image'] = $content->item(0)->nodeValue; // item(0) - это первый результат; с тем же успехом мы могли бы использовать и item(2)->nodeValue, и item(10), и вообще цикл foreach, если понадобится
   if ( strpos($data['image'], 'http://') === false )
   {
      // src у img может быть как http://androoha.com/picture.jpg, так и /picture.jpg, далее мы предусматриваем эти моменты
      $urlparts = parse_url($url);
      if ( substr($data['image'], 0, 2) == '//' ) {
          // ничего не делаем
      }
      else if ( strpos($data['image'], '/') === 0 )
         $data['image'] = $urlparts['scheme'].'://'.$urlparts['host'].$data['image'];
      else
         $data['image'] = $urlparts['scheme'].'://'.$urlparts['host'].'/'.$data['image'];
 
      // но я не учел случаи, когда они могут быть просто picture.jpg или вообще ../picture.jpg, так что вы вольны доработать этот скрипт
   }
 
   // потом нам нужен заголовок: это вероятно или <meta property="og:site_name" content="My cool site">, или <title>My awesome site</title>
   $query = "//html/head/meta[@property='og:site_name']/attribute::content | //title";
   $content = $xpath->query($query);
   $data['title'] = $content->item(0)->nodeValue;
 
   // ну и описание пригодится
   $query = "//meta[@name='description']/attribute::content";
   $content = $xpath->query($query);
   $data['description'] = $content->item(0)->nodeValue;
 
   return $data;
}

Вот и все, осталось лишь проверять весь входящий трафик на наличие ссылок и перед занесением его в БД корректировать, к примеру, как в контакте, добавить к тексту сообщения снизу картинку и рядом заголовок страницы и описание, или же сделать что-то попроще типа такого:

if ( preg_match_all("#http://[^ \,!\n\r]+#", $message, $matches) ) // регулярное выражение примитивное, лучше доработайте %)
{
   foreach ( $matches[0] as $value )
   {
      $data = get_data($value); // получаем нужные данные
 
      // и заменяем ссылку
      $message = str_replace($value, '<a href="'.$value.'" target="_blank">'.$data['title'].'</a>', $message);
   }
}

По традиции, демо вот, скачать пример можно вот.

 Жду с нетерпением
ваших комментариев!
 

Подписаться на RSS

Вы можете нажать "подписаться", чтобы следить за моими новостями!
Так вы всегда будете в курсе появления новостей на сайте =)
О том, что такое RSS можно прочитать здесь.

Подписаться

Подписаться на Twitter

Я специально зарегистрировался в Твиттере, чтобы вы могли следить за обновлениями на сайте =)

Подписаться

Envato marketplace А эти люди занимаются прокатом карнавальных костюмов и масок в Минске. К слову, я им делал сайт.