URLs und E-Mail-Adressen als Hyperlink verlinken

edit | delete

Autor: Varsamis Karamanidis (Macky), Ralf v.d.Mark

eingetragen: Dienstag, 12. Oktober 2021 um 14:27 Uhr (41/2021 Kalenderwoche)

geändert: Dienstag, 25. November 2025 um 14:53 Uhr (48/2025 Kalenderwoche)

Keywords: URLs E-Mail-Adresse Hyperlink verlinken HTML

Kategorien: PHP,

Text:

URLs und E-Mail-Adressen als HTML-Hyperlink verlinken!


Wenn Sie nur auf PHP-8-Systemen arbeiten, dann können Sie die Funktionsaufrufe "" in "" umschreiben.

Quellcode:  

/**
 * URLs und E-Mail-Adressen als Hyperlink zu verlinken
 *
 * PHP version 8
 *
 * Ursprünglich programmiert am Freitag, 14. Juli 2006
 * Angepasst mit Macky am Donnerstag, 12. Oktober 2021
 * Angepasst mit Macky am Dienstag, 25. November 2025
 *
 * @copyright  2025, BLE
 * @version    25.11.2025
 *
 * @param string $zudurchsuchenderText Zu durchsuchender Text
 * @param int    $urlKuerzenAnzahl     (222)
 * @param string $urlZusatzHtmlTags    ('target="_blank" class="url"')
 * @param string $emailZusatzHtmlTags  ('title="E-Mail-Adresse" class="email"')
 * @param string|null $vorUndHinterLink (null)
 * @param bool   $NurHostAusUrlAnzeign (false)
 * @param string $anhangBeiKuerzung    (...)
 *
 * @return string (fertig verlinkter Text)
 */
function link_aktivieren(
    string $zudurchsuchenderText,
    int $urlKuerzenAnzahl = 222,
    string $urlZusatzHtmlTags = 'target="_blank" class="url"',
    string $emailZusatzHtmlTags = 'title="E-Mail-Adresse" class="email"',
    ?string $vorUndHinterLink = null,
    bool $NurHostAusUrlAnzeign = false,
    string $anhangBeiKuerzung = '...'
): string {
    if (trim($zudurchsuchenderText) === '') {
        return $zudurchsuchenderText;
    }

    $vorUndHinterLink = $vorUndHinterLink ?? '';

    // 1. URLs verlinken (http/https/www)
    // Regex sucht nach URLs, ignoriert aber solche, die sich bereits in HTML-Attributen befinden
    // (Lookbehind: muss am Anfang, nach Leerzeichen oder nach '>' starten)
    $urlPattern = '/(?<=^|[\s>])(' .
        '(?:https?:\/\/' .         // Protokoll
        '|www\.)' .                 // ODER www.
        '(?:[a-z0-9\-]+\.)+[a-z]{2,}' . // Domain
        '(?::[0-9]+)?' .            // Optionaler Port
        '(?:\/[^ \s"<]*)?' .        // Optionaler Pfad
        ')(?=$|[\s"<])/iu';         // Lookahead

    $zudurchsuchenderText = preg_replace_callback($urlPattern, function ($matches) use (
        $urlKuerzenAnzahl,
        $urlZusatzHtmlTags,
        $vorUndHinterLink,
        $NurHostAusUrlAnzeign,
        $anhangBeiKuerzung
    ) {
        $url = $matches[1];
        $displayText = $url;

        // Protokoll für href sicherstellen
        $href = $url;
        if (str_starts_with(strtolower($url), 'www.')) {
            $href = 'http://' . $url;
        }

        // Soll nur der Host angezeigt werden?
        if ($NurHostAusUrlAnzeign) {
            $tempUrl = str_starts_with(strtolower($url), 'http') ? $url : 'http://' . $url;
            $parsed = parse_url($tempUrl);
            if (isset($parsed['host'])) {
                $displayText = $parsed['host'];
            }
        }

        // Text kürzen falls zu lang
        if ($urlKuerzenAnzahl > 0 && mb_strlen($displayText) > $urlKuerzenAnzahl) {
            $cutLen = $urlKuerzenAnzahl - mb_strlen($anhangBeiKuerzung);
            if ($cutLen > 0) {
                $displayText = mb_substr($displayText, 0, $cutLen) . $anhangBeiKuerzung;
            }
        }

        return $vorUndHinterLink . sprintf(
                '<a href="%s" %s>%s</a>',
                htmlspecialchars($href),
                $urlZusatzHtmlTags,
                htmlspecialchars($displayText)
            ) . $vorUndHinterLink;
    }, $zudurchsuchenderText);

    // 2. E-Mail-Adressen verlinken
    $emailPattern = '/(?<=^|[\s>])([a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,})(?=$|[\s"<])/iu';

    $zudurchsuchenderText = preg_replace_callback($emailPattern, function ($matches) use (
        $emailZusatzHtmlTags,
        $vorUndHinterLink
    ) {
        $email = $matches[1];
        return $vorUndHinterLink . sprintf(
                '<a href="mailto:%s" %s>%s</a>',
                htmlspecialchars($email),
                $emailZusatzHtmlTags,
                htmlspecialchars($email)
            ) . $vorUndHinterLink;
    }, $zudurchsuchenderText);

    return $zudurchsuchenderText;
}

// --- Beispielaufruf und Test ---

$text = <<<TEXT
Hier ist eine normale URL: https://example.com/pfad?query=1
Und hier eine ohne Protokoll: www.google.de
Hier ist eine E-Mail: kontakt@test.com
Aber hier ist bereits ein Link: <a href="https://bereits-verlinkt.de">Klick mich</a>
Und hier eine URL in einem Attribut (sollte nicht geändert werden): <img src="http://bild.de/image.jpg">
TEXT;

echo link_aktivieren($text,
    222,
    'target="_blank" class="url"',
    'title="E-Mail-Adresse in Ihrem Client" class="email"',
    null,
    false,
    '...');