2016-10-01 77 views
1

我有这样的代码:https://gist.github.com/jasny/2000705 我该如何修改它只适用于以jpg,gif,bmp等结尾的链接?如何查找图像只有链接中的字符串,并链接它们

原始代码:

<?php 
    /** 
    * Turn all URLs in clickable links. 
    * 
    * @param string $value 
    * @param array $protocols http/https, ftp, mail, twitter 
    * @param array $attributes 
    * @param string $mode  normal or all 
    * @return string 
    */ 
    public function linkify($value, $protocols = array('http', 'mail'), array $attributes = array()) 
    { 
     // Link attributes 
     $attr = ''; 
     foreach ($attributes as $key => $val) { 
      $attr = ' ' . $key . '="' . htmlentities($val) . '"'; 
     } 

     $links = array(); 

     // Extract existing links and tags 
     $value = preg_replace_callback('~(<a .*?>.*?</a>|<.*?>)~i', function ($match) use (&$links) { return '<' . array_push($links, $match[1]) . '>'; }, $value); 

     // Extract text links for each protocol 
     foreach ((array)$protocols as $protocol) { 
      switch ($protocol) { 
       case 'http': 
       case 'https': $value = preg_replace_callback('~(?:(https?)://([^\s<]+)|(www\.[^\s<]+?\.[^\s<]+))(?<![\.,:])~i', function ($match) use ($protocol, &$links, $attr) { if ($match[1]) $protocol = $match[1]; $link = $match[2] ?: $match[3]; return '<' . array_push($links, "<a $attr href=\"$protocol://$link\">$link</a>") . '>'; }, $value); break; 
       case 'mail': $value = preg_replace_callback('~([^\s<][email protected][^\s<]+?\.[^\s<]+)(?<![\.,:])~', function ($match) use (&$links, $attr) { return '<' . array_push($links, "<a $attr href=\"mailto:{$match[1]}\">{$match[1]}</a>") . '>'; }, $value); break; 
       case 'twitter': $value = preg_replace_callback('~(?<!\w)[@#](\w++)~', function ($match) use (&$links, $attr) { return '<' . array_push($links, "<a $attr href=\"https://twitter.com/" . ($match[0][0] == '@' ? '' : 'search/%23') . $match[1] . "\">{$match[0]}</a>") . '>'; }, $value); break; 
       default:  $value = preg_replace_callback('~' . preg_quote($protocol, '~') . '://([^\s<]+?)(?<![\.,:])~i', function ($match) use ($protocol, &$links, $attr) { return '<' . array_push($links, "<a $attr href=\"$protocol://{$match[1]}\">{$match[1]}</a>") . '>'; }, $value); break; 
      } 
     } 

     // Insert all link 
     return preg_replace_callback('/<(\d+)>/', function ($match) use (&$links) { return $links[$match[1] - 1]; }, $value); 
    } 

回答

1

您可以添加另一种说法叫$allowed_types,它包含所有你想允许扩展。

然后你必须得到最后''后的子字符串。字符,并将其与您的允许扩展名列表进行比较。

这是基本的想法,我相信它可以改进很多。

/** 
* Turn all URLs in clickable links. 
* 
* @param string $value 
* @param array $protocols http/https, ftp, mail, twitter 
* @param array $attributes 
* @param string $mode  normal or all 
* @return string 
*/ 
function linkify($value, $allowed_types = array('jpg', 'png'), $protocols = array('http', 'mail'), array $attributes = array()) { 

    /** 
    * Get position of last dot in string 
    */ 
    $dot_pos = strrpos($value, '.'); 
    if(!$dot_pos) { 
     return FALSE; 
    } 

    /** 
    * Get substring after last dot 
    */ 
    $extension = substr($value, $dot_pos + 1); 

    if(!in_array($extension, $allowed_types)) { 
     /** 
     * Extension not in allowed types 
     */ 
     return FALSE; 
    } 


    // Link attributes 
    $attr = ''; 
    foreach ($attributes as $key => $val) { 
     $attr = ' ' . $key . '="' . htmlentities($val) . '"'; 
    } 

    $links = array(); 

    // Extract existing links and tags 
    $value = preg_replace_callback('~(<a .*?>.*?</a>|<.*?>)~i', function ($match) use (&$links) { 
     return '<' . array_push($links, $match[1]) . '>'; 
    }, $value); 

    // Extract text links for each protocol 
    foreach ((array) $protocols as $protocol) { 
     switch ($protocol) { 
      case 'http': 
      case 'https': $value = preg_replace_callback('~(?:(https?)://([^\s<]+)|(www\.[^\s<]+?\.[^\s<]+))(?<![\.,:])~i', function ($match) use ($protocol, &$links, $attr) { 
        if ($match[1]) 
         $protocol = $match[1]; 
        $link = $match[2] ? : $match[3]; 
        return '<' . array_push($links, "<a $attr href=\"$protocol://$link\">$link</a>") . '>'; 
       }, $value); 
       break; 
      case 'mail': $value = preg_replace_callback('~([^\s<][email protected][^\s<]+?\.[^\s<]+)(?<![\.,:])~', function ($match) use (&$links, $attr) { 
        return '<' . array_push($links, "<a $attr href=\"mailto:{$match[1]}\">{$match[1]}</a>") . '>'; 
       }, $value); 
       break; 
      case 'twitter': $value = preg_replace_callback('~(?<!\w)[@#](\w++)~', function ($match) use (&$links, $attr) { 
        return '<' . array_push($links, "<a $attr href=\"https://twitter.com/" . ($match[0][0] == '@' ? '' : 'search/%23') . $match[1] . "\">{$match[0]}</a>") . '>'; 
       }, $value); 
       break; 
      default: $value = preg_replace_callback('~' . preg_quote($protocol, '~') . '://([^\s<]+?)(?<![\.,:])~i', function ($match) use ($protocol, &$links, $attr) { 
        return '<' . array_push($links, "<a $attr href=\"$protocol://{$match[1]}\">{$match[1]}</a>") . '>'; 
       }, $value); 
       break; 
     } 
    } 

    // Insert all link 
    return preg_replace_callback('/<(\d+)>/', function ($match) use (&$links) { 
     return $links[$match[1] - 1]; 
    }, $value); 
} 
+0

伟大的想法,我可以做这个工作,感谢 –

+0

顺便说一句我才意识到,这可能仅仅上一个环节的工作,II曾在一个字符串的两个图像链接也只是赶上第二个,因为它是寻找最后一个字符串中的点。任何想法如何解决这个问题? –

+1

您将大链接分成基本链接,并通过相同的功能运行它。这种逻辑在上述功能之外会更好。 – Tool