Por el texto de tu pregunta no me queda claro si deseas que la URL se pueda hacer clic al estar como texto dentro de un campo textarea. Este caso no podrías, ya que en un textarea solo se puede escribir y ver texto plano.
Pero lo que imagino que quieres es que, al cargar una cadena de texto que has escrito en un textarea y volcarla como contenido de una página, en HTML, que cualquier URL se vea como si fuera un enlace, cambiando tal URL en texto a una etiqueta <a> de enlace con su href.
Eso se puede hacer simplemente transformando la cadena que has cargado con el textarea. Haciendo un reemplazo de la cadena, en búsqueda de todas las URL, para colocar la etiqueta <a href="URL_ENCONTRADA"> completa.
En Internet encontramos varias soluciones a este tema. Puedes consultar esta de Stack Overflow, aunque me parece todavía más completa esta función publicada por un usuario en GitHub.
Por si retiran más adelante ese código de GitHub, copio y pego la solución aquí.
Los parámetros son:
- $value: la cadena original
- $protocols: los protocolos que tiene que buscar, en un array, por ejemplo ('http', 'mail'). Por el código que tiene la función, si colocas http te vale tanto para http como https.
- $attributes: un array asociativo, con el nombre del atributo y el valor del atributo que se desea poner al enlace
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<]+?@[^\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);
}