遇到两个需求,需要将内容的的url自动加入a链接,可以直接点击,另外一个是需要将内容中的url替换成短链接,其实就是实现类似新浪微博那样。

比如内容为:我是徐鹏,我的博客网址为:devops.jiunile.com

将以上内容替换为:我是徐鹏,我的博客网址为:<a href="devops.jiunile.com" target="_blank">xp.cn/6A3ihJ0</a>


实现方式如下:

define('SHORTURL', 'xp.cn');

//调用方法
$processContent = formatContent('我是徐鹏,我的博客网址为:devops.jiunile.com');
$autoLinkContent = autolink($processContent);
echo $autoLinkContent;

function formatContent($content)
{
    $URL_VALID_PRECEEDING_CHARS = "(?:[^/\"':!=]|^|\\:)";
    $URL_VALID_DOMAIN = "(?:[\\.-]|[^\\p{P}\\s])+\\.[a-z]{2,}(?::[0-9]+)?";
    $URL_VALID_URL_PATH_CHARS = "[\x80-\xff_a-z0-9!\\*'\\(\\);:&=\\+\\$/%#\\[\\]\\-_\\.,~@]";
    $URL_VALID_URL_PATH_ENDING_CHARS = "[\x80-\xff_a-z0-9\\)=#/]";
    $URL_VALID_URL_QUERY_CHARS = "[\x80-\xff_a-z0-9!\\*'\\(\\);:&=\\+\\$/%#\\[\\]\\-_\\.,~]";
    $URL_VALID_URL_QUERY_ENDING_CHARS = "[\x80-\xff_a-z0-9_&=#]";
    $VALID_URL_PATTERN_STRING = '$(' .
        "(" . $URL_VALID_PRECEEDING_CHARS . ")" .
        "(" .
        "(https?://|www\\.)" .
        "(" . $URL_VALID_DOMAIN . ")" .
        "(/" . $URL_VALID_URL_PATH_CHARS . "*" .
        $URL_VALID_URL_PATH_ENDING_CHARS . "?)?" .
        "(\\?" . $URL_VALID_URL_QUERY_CHARS . "*" .
        $URL_VALID_URL_QUERY_ENDING_CHARS . ")?" .
        ")" .
        ')$i';

    return preg_replace_callback($VALID_URL_PATTERN_STRING, 'replaceUrls',$content);
}

function replaceUrls($matches)
{
    $replacement  = $matches[2];
    if (substr($matches[3], -1, 1) == "[")
    {
        $matches[3] = substr($matches[3], 0, -1);
        $append = "[";
    }
    else
    {
        $append = "";
    }

    if( !empty($matches[3]) )
    {
        $original = (substr($matches[3], 0, 7) == 'http://' || substr($matches[3], 0, 8) == 'https://') ? $matches[3] : 'http://'.$matches[3];
        $short = shortUrl($original);
		//下面根据$short 去检查数据库里是否存在shortUrl 如果不存在,需要插入对应的记录。
		......

        $replacement .= SHORTURL . '/' . $short;
    }

    $replacement .= $append;
    return $replacement;
}

function shortUrl($url)
{
    $base32 = array (
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
        'a', 'A', 'b', 'B', 'c', 'C', 'd', 'D', 'e', 'E', 'f', 'F', 'g', 'G', 'h', 'H',
        'i', 'I', 'j', 'J', 'k', 'K', 'l', 'L', 'm', 'M', 'n', 'N', 'o', 'O', 'p', 'P',
        'q', 'Q', 'r', 'R', 's', 'S', 't', 'T', 'u', 'U', 'v', 'V', 'w', 'W', 'x', 'X',
        'y', 'Y', 'z', 'Z'
    );

    $hex = md5($url);
    $hexLen = strlen($hex);

    $subHex = substr ($hex, 0, 8);
    $int = 0x3FFFFFFF & (1 * ('0x'.$subHex));
    $out = '';

    for ($j = 0; $j < 7; $j++) {
        $val = 0x0000001F & $int;
        $out .= $base32[$val];
        $int = $int >> 5;
    }

    return $out;
}

function autolink($tweet)
{
	$VALID_URL_PATTERN_STRING = '$('.SHORTURL.'/[a-zA-Z0-9]{7})$i';
	return preg_replace_callback($VALID_URL_PATTERN_STRING, 'replacementURLs',$tweet);
}
	
function replacementURLs($matches)
{
    $arr = explode('/',$matches[0]);
	//根据$arr[0](shortUrl) 去查找对应数据库里的正式url地址
	// $url 从数据库里取出
    $replacement = '<a href="' . $url . '" target="_blank">' . $matches[0] . '</a>';
    return $replacement;
}