SORU
27 Temmuz 2009, PAZARTESİ


HTML bağlantıları ile metin içinde URL değiştirin

Burada bir tasarım olsa: örneğin bir bağlantı gibi

http://example.com

button. Nasıl http:// link ve baskı olarak algılamak için PHP alabilirim

print "<a href='http://www.example.com'>http://www.example.com</a>";

Ancak, karmaşık bağlantılar için ihlal etti aptal kanıt değil daha önce böyle bir şey yaptığımı hatırlamıyorum.

Başka iyi bir fikir bir link gibi olurdu

http://example.com/test.php?val1=bla&val2blablabla bla bla.bl

aynen öyle Düzelt

print "<a href='http://example.com/test.php?val1=bla&val2=bla bla bla.bla'>";
print "http://example.com/test.php";
print "</a>";

Bu sadece bir sonra stackoverflow da muhtemelen bu kadar iyi kullanabilir..: D düşünülmektedir

Herhangi Bir Fikir

CEVAP
27 Temmuz 2009, PAZARTESİ


Bu şartları göz atalım. Kullanıcı tarafından sağlanan köprü URL ile görüntülemek istediğiniz düz metin var.

  1. "Http://" protokolü öneki isteğe bağlı olmalıdır.
  2. Etki alanları ve IP adresleri her ikisi de kabul edilmelidir.
  3. Üst düzey herhangi bir geçerli etki alanı, örneğin kabul edilmelidir .aero ve .--jxalpdlp Xi.
  4. Port numaralarını izin verilmelidir.
  5. Url normal cümle bağlamlarda izin verilmelidir. Örneğin, "stackoverflow.com." Ziyaret son dönem URL bir parçası değil.
  6. Muhtemelen "https://" gibi Url, ve belki de diğerleri de. izin vermek istiyor
  7. Görüntüleme kullanıcı HTML metin sağlandığında her zaman olduğu gibi, cross-site scripting (XSS) önlemek istiyoruz. Ayrıca, adresler ve işaretleri correctly escaped olarak & olmak isteyeceksiniz;.
  8. Muhtemelen IPv6 adresleri için desteğe ihtiyacınız yok.
  9. Edit: Açıklamalarda belirtildiği gibi, e-posta adresleri için destek bir artı kesinlikle.
  10. EditSadece düz metin giriş desteklenecek – giriş HTML etiketlerini onur olmamalıdır. (Bitbucket sürümü HTML giriş destekler.)

Edit: E-posta adresleri için destek, kimliği doğrulanmış URL, tırnak ve parantez içinde URL, HTML giriş ve güncellenmiş KARŞILIK bir liste ile en son sürümü için Bitbucket kontrol edin.

Lütfen rapor hataları ve geliştirme istekleri Bitbucket issue tracker kullanarak. Bu şekilde (ve yorum alanı karmaşası yok) takip etmek daha kolay oluyor.

Burada benim almak:

<?php
$text = <<<EOD
Here are some URLs:
stackoverflow.com/questions/1188129/pregreplace-to-detect-html-php
Here's the answer: http://www.google.com/search?rls=en&q=42&ie=utf-8&oe=utf-8&hl=en. What was the question?
A quick look at http://en.wikipedia.org/wiki/URI_scheme#Generic_syntax is helpful.
There is no place like 127.0.0.1! Except maybe http://news.bbc.co.uk/1/hi/england/surrey/8168892.stm?
Ports: 192.168.0.1:8080, https://example.net:1234/.
Beware of Greeks bringing internationalized top-level domains: xn--hxajbheg2az3al.xn--jxalpdlp.
And remember.Nobody is perfect.

<script>alert('Remember kids: Say no to XSS-attacks! Always HTML escape untrusted input!');</script>
EOD;

$rexProtocol = '(https?://)?';
$rexDomain   = '((?:[-a-zA-Z0-9]{1,63}\.) [-a-zA-Z0-9]{2,63}|(?:[0-9]{1,3}\.){3}[0-9]{1,3})';
$rexPort     = '(:[0-9]{1,5})?';
$rexPath     = '(/[!$-/0-9:;=@_\':;!a-zA-Z\x7f-\xff]*?)?';
$rexQuery    = '(\?[!$-/0-9:;=@_\':;!a-zA-Z\x7f-\xff] ?)?';
$rexFragment = '(#[!$-/0-9:;=@_\':;!a-zA-Z\x7f-\xff] ?)?';

// Solution 1:

function callback($match)
{
    // Prepend http:// if no protocol specified
    $completeUrl = $match[1] ? $match[0] : "http://{$match[0]}";

    return '<a href="' . $completeUrl . '">'
        . $match[2] . $match[3] . $match[4] . '</a>';
}

print "<pre>";
print preg_replace_callback("&\\b$rexProtocol$rexDomain$rexPort$rexPath$rexQuery$rexFragment(?=[?.!,;:\"]?(\s|$))&",
    'callback', htmlspecialchars($text));
print "</pre>";
  • Düzgün kaçış < ve & karakterleri, işleme önce htmlspecialchars ile tüm metin atarım. Bu html kaçan URL sınırları misdetection neden olabileceği için idealdir.
  • "Ve hatırlayın.tarafından gösterildiği gibi Kimse mükemmel değildir." unutmayın ki. (satır Bir URL olarak kabul edilir kimse, kayıp alanı nedeniyle), daha geçerli bir üst düzey etki alanları kontrol olabilir.

EditAşağıdaki kodu yukarıdaki iki sorunu giderir, ama ya yeniden uygulamak preg_replace_callback preg_match kullanarak daha az olduğum için biraz daha ayrıntılı.

// Solution 2:

$validTlds = array_fill_keys(explode(" ", ".aero .asia .biz .cat .com .coop .edu .gov .info .int .jobs .mil .mobi .museum .name .net .org .pro .tel .travel .ac .ad .ae .af .ag .ai .al .am .an .ao .aq .ar .as .at .au .aw .ax .az .ba .bb .bd .be .bf .bg .bh .bi .bj .bm .bn .bo .br .bs .bt .bv .bw .by .bz .ca .cc .cd .cf .cg .ch .ci .ck .cl .cm .cn .co .cr .cu .cv .cx .cy .cz .de .dj .dk .dm .do .dz .ec .ee .eg .er .es .et .eu .fi .fj .fk .fm .fo .fr .ga .gb .gd .ge .gf .gg .gh .gi .gl .gm .gn .gp .gq .gr .gs .gt .gu .gw .gy .hk .hm .hn .hr .ht .hu .id .ie .il .im .in .io .iq .ir .is .it .je .jm .jo .jp .ke .kg .kh .ki .km .kn .kp .kr .kw .ky .kz .la .lb .lc .li .lk .lr .ls .lt .lu .lv .ly .ma .mc .md .me .mg .mh .mk .ml .mm .mn .mo .mp .mq .mr .ms .mt .mu .mv .mw .mx .my .mz .na .nc .ne .nf .ng .ni .nl .no .np .nr .nu .nz .om .pa .pe .pf .pg .ph .pk .pl .pm .pn .pr .ps .pt .pw .py .qa .re .ro .rs .ru .rw .sa .sb .sc .sd .se .sg .sh .si .sj .sk .sl .sm .sn .so .sr .st .su .sv .sy .sz .tc .td .tf .tg .th .tj .tk .tl .tm .tn .to .tp .tr .tt .tv .tw .tz .ua .ug .uk .us .uy .uz .va .vc .ve .vg .vi .vn .vu .wf .ws .ye .yt .yu .za .zm .zw .xn--0zwm56d .xn--11b5bs3a9aj6g .xn--80akhbyknj4f .xn--9t4b11yi5a .xn--deba0ad .xn--g6w251d .xn--hgbk6aj7f53bba .xn--hlcj6aya9esc7a .xn--jxalpdlp .xn--kgbechtv .xn--zckzah .arpa"), true);

$position = 0;
while (preg_match("{\\b$rexProtocol$rexDomain$rexPort$rexPath$rexQuery$rexFragment(?=[?.!,;:\"]?(\s|$))}", $text, &$match, PREG_OFFSET_CAPTURE, $position))
{
    list($url, $urlPosition) = $match[0];

    // Print the text leading up to the URL.
    print(htmlspecialchars(substr($text, $position, $urlPosition - $position)));

    $domain = $match[2][0];
    $port   = $match[3][0];
    $path   = $match[4][0];

    // Check if the TLD is valid - or that $domain is an IP address.
    $tld = strtolower(strrchr($domain, '.'));
    if (preg_match('{\.[0-9]{1,3}}', $tld) || isset($validTlds[$tld]))
    {
        // Prepend http:// if no protocol specified
        $completeUrl = $match[1][0] ? $url : "http://$url";

        // Print the hyperlink.
        printf('<a href="%s">%s</a>', htmlspecialchars($completeUrl), htmlspecialchars("$domain$port$path"));
    }
    else
    {
        // Not a valid URL.
        print(htmlspecialchars($url));
    }

    // Continue text parsing from after the URL.
    $position = $urlPosition   strlen($url);
}

// Print the remainder of the text.
print(htmlspecialchars(substr($text, $position)));

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Dom Esposito

    Dom Esposito

    26 Mayıs 2011
  • FILIPeeeK

    FILIPeeeK

    22 Mayıs 2006
  • HTC

    HTC

    12 Ocak 2006