Очередной рассказ о приобретенном опыте. Задача такая: пользователь при добавлении комментария может вставить ссылку, и будет идеально если ссылка на картинку сразу отобразиться картинка, на Youtube сразу роликом, а остальные просто ссылкой. Как сделать проигрывание роликов Youtube на форуме phpbb3 я писал, сейчас чуть усложним задачу и попробуем сделать отображение роликов на любом сайте.
Итак, нам нужно, чтбы украсить к примеру форум? Для начала получить все ссылки, что есть в тексте комментария, затем прогуляться по ним и посмотреть, если ссылка на youtube, то извлечь из нее id ролика и преобразовать это в код плеера. Если ссылка на картинку, то привести ее к виду <img src=»путь к картинке» />. С картинкой еще один момент, ссылка на нее необязательно заканчивается на .jpg или .png. Ссылка может быть без расширения, сделанная с помощью mod_rewrite. Проверять это будем заголовками.
Решение такое:
1) находим все ссылки с помощью вот такого регулярного выражения:
$reg_exUrl = "/(http|https|ftp|ftps)\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(\/\S*)?/";
2) Пробегаем по всем ссылкам и проверяем сначала не является ли она ссылкой Youtube, затем на картинку.
Является ли ссылка линком на ролик проверяем таким регулярным выражением:
$youtubePattern = '#(http://www.youtube.com)?/(v/([-|~_0-9A-Za-z]+)|watch\?v\=([-|~_0-9A-Za-z]+)&*(\/\S*)?)#i';
Явлется ли это ссылкой на картинку проверяем так:
get_headers('адрес ссылки'',1); if( array_key_exists('Content-Type', $aHeader) && substr( $aHeader['Content-Type'],0,6 ) == 'image/') { //то это картинка }
Вот собственно и все. Для ленивых полный текст функции в которой на вход подается текст и возвращается уже новый, с кодами картинок и роликов.
$reg_exUrl = "/(http|https|ftp|ftps)\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(\/\S*)?/"; if(preg_match_all($reg_exUrl, $text, $output)) { foreach($output[0] as $url){ $youtubePattern = '#(http://www.youtube.com)?/(v/([-|~_0-9A-Za-z]+)|watch\?v\=([-|~_0-9A-Za-z]+)&*(\/\S*)?)#i'; if(preg_match($youtubePattern, $url, $youtubemathes)){ $video_id = $youtubemathes[4]; $embed = '<br /><object width="480" height="390"><param name="movie" value="http://www.youtube.com/v/'.$video_id.'&hl=en&fs=1&"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/'.$video_id.'&hl=en&fs=1&" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="390"></embed></object>'; $text = str_replace($url, $embed, $text); } else { $aHeader = get_headers($url,1); if( array_key_exists('Content-Type', $aHeader) && substr( $aHeader['Content-Type'],0,6 ) == 'image/'){ $img = '<br /><a href="'.$url.'" rel="nofollow"><img src="'.$url.'" /></a>'; $text = str_replace($url, $img, $text); } else { $link = '<a href="'.$url.'" rel="nofollow">'.$url.'</a>'; $text = str_replace($url, $link, $text); } } } } return $text;
К сожалению, регулярные выражения в PHP работают ужас как медленно, и если объем для парсинга будет большой, это может заметно снизить производительность.
Ну и конечно анализировать коммент нужно один раз и уже в готовом виде заносить в базу.
Согласен, что один раз, но я храню в базе и оригинал и преобразованный, оригинал для редактирования, база конечно заметно вырастает, но возможность редактирования она важна.
что не мешает на регулярках строить всякие smarty-подобные шаблонизаторы. не такие они и медленные
Да, разумно.
Вы тут вообще не правы, все это нужно переносить на сторону клиента, а идея отличная, только вы забыли про музыкальные файлы, радиостанции. А так, конфета, мцаа.
Ой вэй, что на сторону клиента? на стороне клиента проверять ссылки? а музыкальный файлы все можно прикручивать и расширять я думаю 🙂
Я так понимаю, предлагается на стороне клиента посредством JavaScript обрабатывать этот текст и отправлять уже готовый результат на сервер.