Cum verifici dacă un șir de caractere este un URL valid
WordPress oferă o funcție utilă numită is_email()
care verifică dacă o adresă de email este validă. Există o funcție similară disponibilă pentru a verifica dacă un URL este valid?
Am încercat is_url()
dar asta a fost doar o presupunere optimistă din partea mea.
Folosește funcția nativă PHP Filtru Validator
if (filter_var($url, FILTER_VALIDATE_URL) === FALSE) {
die('URL-ul nu este valid');
}

Bună observație și mulțumesc @shanebp - nu știam că există acest filtru!

FILTER_VALIDATE_URL pare bun dar are câteva probleme serioase: https://d-mueller.de/blog/why-url-validation-with-filter_var-might-not-be-a-good-idea/

@tobltobs: Acelea nu sunt probleme, ci caracteristici. Autorul se plânge că URL-uri valide sunt raportate ca valide. E ca și cum te-ai plânge că PDO e stricat pentru că permite $pdo->query("SELECT pw FROM users WHERE id={$_GET['id']}")
.

Ai putea avea dreptate @dotancohen, că acelea sunt URL-uri valide din punct de vedere tehnic. Deci poate problema este într-adevăr în întrebarea noastră. Nu căutăm doar "URL-uri valide din punct de vedere tehnic", ci "URL-uri sigure". Adică, URL-uri care ajută la prevenirea atacurilor XSS sau altor probleme. Sugestia lui @orionrush evită o serie din aceste probleme, în timp ce FILTER_VALIDATE_URL
nu o face.

Am găsit funcția wp_http_validate_url
destul de utilă pentru a verifica dacă un șir de caractere este un URL valid sau nu în timp ce lucram la proiectul meu.
Consultați documentația oficială aici: https://developer.wordpress.org/reference/functions/wp_http_validate_url/
De exemplu:
$val = 'http://somevalidurl.com';
if ( wp_http_validate_url( $val ) ) {
// Este un URL valid;
} else {
// NU este un URL valid;
}
Funcția returnează URL-ul însuși dacă este valid, altfel returnează false.

Această funcție pare grozavă, dar cred că a făcut câteva greșeli în legătură cu datele introduse de utilizatori.
A considerat URL-ul localhost
ca fiind invalid;
dar a considerat http://example.com/"><script>alert("xss")</script>
ca fiind valid.

scuze, SO nu mă lasă să modific comentariul. Voiam să spun că consideră http://localhost
invalid.

@thespacecamel Poți folosi filtrul http_request_host_is_external
pentru a permite localhost:
`function allow_some_url( $external, $host, $url ) { return ( $host === 'localhost' ) ? true : $external;
} add_filter( 'http_request_host_is_external', 'allow_some_url', 10, 3 );
if ( wp_http_validate_url( 'http://localhost/wordpress/' ) ) { echo 'valid'; } else { echo 'invalid'; }`

Știu că acesta este un articol vechi, dar pentru oricine îl vizitează, merită luate în considerare și funcțiile WP esc_url()
și esc_url_raw()
, cea din urmă fiind sigură pentru intrările în baze de date etc., deoarece nu codifică entități. esc_url()
codifică entități și, prin urmare, este bună pentru afișare utilizatorilor.
În sursă puteți vedea că esc_url()
verifică o listă albă de protocoale și structuri permise și, astfel, evită unele dintre vulnerabilitățile FILTER_VALIDATE_URL
menționate de linkul postat de @tobltobs.

În opinia mea, este mai bine să folosești wp_http_validate_url.
Exemplul 1:
filter_var( '//website.com', FILTER_VALIDATE_URL )
Returnează false.
Exemplul 2:
wp_http_validate_url( '//website.com' )
Returnează URL-ul.
- Dacă nu știi dacă site-ul folosește protocolul https sau http, este mai bine să folosești '//'.
- wp_http_validate_url este îmbunătățit de dezvoltatorii WordPress (este mai specific).
- Poți îmbunătăți sau modifica wp_http_validate_url folosind hook-uri (filtre & acțiuni). Nu poți folosi hook-uri pentru filter_var.
Referință: https://developer.wordpress.org/reference/functions/wp_http_validate_url/
Referință: https://www.php.net/manual/en/function.filter-var.php

Sunt de acord, wp_http_validate_url()
este un validator mai bun, permițând atât adrese IP, cât și forțând o validare suplimentară pentru URL-uri localhost cu filtru http_request_host_is_external
care implicit returnează false ca măsură de siguranță suplimentară

Să discutăm opțiunile noastre pentru validarea URL-urilor în WordPress, începând cu cele evidente.
filter_var()
cu filtrulFILTER_VALIDATE_URL
în PHP nu funcționează pentru nume de domenii internaționale care conțin caractere non-ASCII, cum ar fihttp://스타벅스코리아.com
. De asemenea, prezintă și alte probleme, așa cum a discutat David Müller, cum ar fi acceptareahttp://example.com/"><script>alert("xss")</script>
ca URL valid, chiar dacă este clar malefic.wp_http_validate_url()
în WordPress poate face o treabă mai bună, deși a fost concepută special pentru utilizarea în API-ul HTTP și nu pentru validarea generală a URL-urilor. Dar tot nu rezolvă cele două probleme specifice discutate mai devreme.preg_match()
în PHP poate funcționa sau nu. Scrierea expresiilor regulate care să anticipeze fiecare scenariu posibil nu este întotdeauna cea mai ideală soluție, iar obținerea unui rezultat universal corect poate fi uneori imposibilă.esc_url_raw()
în WordPress nu este destinat validării URL-urilor, dar pare să facă o treabă mai bună decât celelalte. Va funcționa pentru caractere non-ASCII, precum și pentru rezolvarea celorlalte probleme discutate anterior. Această funcție va practic sanitiza orice șir de caractere pentru a fi salvat în baza de date WordPress ca un URL, eliminând sau modificând orice caractere care sunt fie invalide, fie malefice. Prin urmare, dacă versiunea sanitizată nu este aceeași cu cea nesanitizată, se poate spune cu încredere că URL-ul nu este valid și, cel mai important, nu este sigur.
Iată cum poate fi făcută verificarea URL-ului cu funcția esc_url_raw()
, profitând și de funcția strtolower()
pentru a face verificarea insensibilă la majuscule/minuscule.
function validateUrl($url) {
if ( strtolower(esc_url_raw($url)) === strtolower($url) ) {
return $url;
} else {
return false;
}
}

Pentru a verifica dacă un URL introdus de utilizator este valid și sigur pentru stocare și afișare ulterioară, sugerez:
esc_url_raw($url) === $url
esc_url_raw()
, așa cum a menționat @orionrush mai sus, sanitizează URL-ul prin eliminarea oricăror elemente invalide sau malicioase. Deci, dacă șirul de caractere nu conține nimic invalid sau rău intenționat, atunci este în regulă.
Exemplu:
if( esc_url_raw($url) === $url ) {
// URL-ul este valid. Folosește-l...
} else {
// URL-ul este invalid sau malicios. Nu-l utiliza...
}
Am scris un articol mai detaliat pe această temă aici: https://cmljnelson.wordpress.com/2018/08/31/url-validation-in-wordpress/

is_email()
, de fapt nu verifică dacă o adresă de email este validă, ci doar dacă respectă specificațiile standard. Adresa de email pe care o ofer cu plăcere pe multe site-uri care arată un interes inutil pentru adresa mea de email este a@b.com - aceasta respectă specificațiile, dar este puțin probabil să fie folosită de cineva.
Cel mai bun mod de a verifica URL-urile este prin trimiterea unei cereri ping. Puteți încerca să verificați conformitatea, dar teoretic există foarte puține limitări în ceea ce poate fi un URL codat.
