Jak sprawdzić za pomocą PHP, czy adres URL oraz email są poprawne i rzeczywiście istnieją?

Jak sprawdzić za pomocą PHP, czy adres URL oraz email są poprawne i rzeczywiście istnieją?

PHP posiada wiele wbudowanych funkcji (file_exist, is_dir), dzięki którym jesteśmy w stanie sprawdzić, czy na przykład konkretny plik istnieje na dysku, ale jak możemy zdalnie sprawdzić, czy dany adres URL, email, czy link do obrazka są poprawne oraz rzeczywiście istnieją? Postaram się to Wam dzisiaj pokazać dzięki kilku kawałkom kodu, które posłużą do konkretnych zadań.

Czy ten obrazek rzeczywiście tam jest?

PHP5 daje nam możliwość sprawdzenia obrazka, który kryje się nam pod konkretnym linkiem. Dzięki takiej funkcji jak GetImageSize jesteśmy w stanie pobrać obrazek trzymany na zdalnym serwerze i dzięki bibliotece GD zainstalowanej na naszej maszynie.

$external_link = 'http://mrzepinski.pl/wp-content/uploads/2012/08/mrzepinski-resized.png';
if (@GetImageSize($external_link)) {
    echo "obrazek istnieje!";
} else {
    echo "nic tam nie ma :(";
}

Powyższy sposób jest jednak mało efektywny. Cały obrazek jest najpierw pobierany na nasz serwer i dopiero wtedy następuje rzeczywiste sprawdzenie rozmiaru obrazka. Stwarza to też pewne zagrożenie bezpieczeństwa, bo przecież dobrze znane są przypadki, że zły kod krył się właśnie pod postacią rozszerzenia pliku, które sugerowałoby zupełnie inne przeznaczenie niżeli próba odpalenia złośliwego kodu i przejęcie kontroli nad funkcjonowaniem naszego systemu lub narobieniem w nim szkód.

Całość możemy jednak wykonać nieco inaczej. Jeżeli nie boimy się używać biblioteki cURL, to nasz kod może wyglądać następująco:

function checkRemoteFile($url) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    // nie pobieraj kontentu na serwer
    curl_setopt($ch, CURLOPT_NOBODY, 1);
    curl_setopt($ch, CURLOPT_FAILONERROR, 1);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    if (curl_exec($ch) !== false) {
        return true;
    } else {
        return false;
    }
}

Jeżeli są jednak tacy, którzy boją się używać cURL’a albo zwyczajnie nie mogą, to istnieje jeszcze funkcja file_get_contents, która pozwala nam na pobranie wystarczającej ilości danych z zewnętrznego serwera, by stwierdzić, że link jest poprawny i prowadzi do konkretnego pliku. Wystarczy, że pobierzemy w ten sposób 1 bajt informacji, tak jak w przykładzie poniżej.

function url_exists($url) {
    if (@file_get_contents($url, 0, null, 0, 1)) {
        return 1;
    } else { 
        return 0;
    }
}

Sprawdzamy adres URL

Taką funkcjonalność możemy uzyskać na wiele sposobów, ale nie wszystkie dobre są w każdej sytuacji. Poniżej kilka przykładów.

function url_exists($url) {
    if (strstr($url, "http://")) 
        $url = "http://".$url;
    $fp = @fsockopen($url, 80);

    return !($fp === false);
}

Powyższa metoda jest zdecydowanie szybsza niż funkcja fopen, ale tylko dla adresów z https:// lub nazw domenowych, ponieważ sprawdzając już adres http://example.com?p=231 możemy napotkać na małe problemy wydajnościowe.

Poniższy sposób jest bardziej kompleksowy, ponieważ sprawdza on tylko odpowiedź serwera, a dokładniej przesłane nagłówki.

function url_exists($url) {
     if ((strpos($url, "http")) === false) 
         $url =  "http://".$url;

     return is_array(@get_headers($url));
}

Całość jednak działa tylko dla URL z http:// oraz z PHP5 i nowszym. Możemy ją jednak nieco rozbudować, tak by i starsza wersja PHP nie była dla nas problemem.

function is_valid_url($url) {
    $url = @parse_url($url);
    if (!$url) {
        return false;
    }

    $url = array_map('trim', $url);
    $url['port'] = (!isset($url['port'])) ? 80 : (int)$url['port'];
    $path = (isset($url['path'])) ? $url['path'] : '';
    if ($path == '') {
        $path = '/';
    }

    $path .= (isset($url['query'])) ? "?$url[query] " : '';
    if (isset($url['host']) AND $url['host'] != gethostbyname($url['host'])) {
        if (PHP_VERSION >= 5) {
            $headers = get_headers("$url[scheme]://$url[host]:$url[port]$path ");
        } else {
            $fp = fsockopen($url['host'], $url['port'], $errno, $errstr, 30);
            if (!$fp) {
                return false;
            }
            fputs($fp, "HEAD $path HTTP/1.1rnHost: $url[host]rnrn");
            $headers = fread($fp, 4096);
            fclose($fp);
        }
        $headers = (is_array($headers)) ? implode("n", $headers) : $headers;
        return (bool)preg_match('#^HTTP/.*s+[(200|301|302)]+s#i', $headers);
    }
    return false;
}

Czego się nie robi, by zachować wsteczną kompatybilność :)

Pozostał nam jeszcze jeden sposób

function image_exist($url) {
    return (@fclose(@fopen( $url,  "r ")));
}

, ale wymaga on by zmienna allow_url_fopen była ustawiona na true w naszym pliku konfiguracyjnym PHP (php.ini).

Sprawdzamy adres em@il

Nadszedł czas na sposoby sprawdzenia poprawności i zweryfikowanie adresu email. Tutaj także mamy kilka ścieżek do wyboru.

Jak się okazuje, proces weryfikacji adresu email w dużej mierze zależy także od ustawień konkretnego serwera SMTP. Mamy jednak możliwość sprawdzenia istnienia konkretnej domeny, by zaoszczędzić sobie trochę czasu i od razu eliminować takie nieprawdziwe adresy. Jesteśmy w stanie to osiągnąć poprzez wykorzystanie funkcji PHP, jaką jest checkdnsrr, która – jak wskazuje nam na to jej nazwa – sprawdza rekordy DNS dla danego URL / hosta. Przykład poniżej.

function email_exist($email) {
    list($userid, $domain) = split("@", $email);

    return checkdnsrr($domain, "MX"));
}

Wszystko byłoby dobrze, ale oczywiście pojawia się kolejny problem. Windows do dzisiaj nie wspiera tej funkcji i aby móc z niej skorzystać, musimy ją sobie stworzyć sami, sic!

if (!function_exists('checkdnsrr'))
function checkdnsrr($hostName, $recType = '') {
   if (!empty($hostName)) {
       if ($recType == '') $recType = "MX";
           exec("nslookup -type=$recType $hostName", $result);

       foreach ($result as $line) {
           if (eregi("^$hostName", $line))
                return true;
       }

       return false;
   }

   return false;
}

Kiedy mamy już gotową obsługę dwóch platform (Linux i Windows), przejdźmy teraz do rzeczy właściwej, a mianowicie, sprawdźmy czy dany email jest poprawny oraz zweryfikujmy jego istnienie.

function isValidEmail($email) {
        $emailError = false;
        $email = htmlspecialchars(stripslashes(strip_tags(trim($email))));
        if ($email == " ") { 
            $emailError = true; 
        } elseif (!eregi( "^([a-zA-Z0-9._-])+@([a-zA-Z0-9._-])+.([a-zA-Z0-9._-])([a-zA-Z0-9._-])+ ", $email)) { 
            $emailError = true; 
        } else {
            list($email, $domain) = split("@", $email, 2);
            if (!checkdnsrr($domain, "MX")) { 
                emailError = true; 
            } else {
                $array = array($email, $domain);
                $email = implode("@", $array);
            }
        }
        return !emailError;
}

I to byłoby na tyle. Znacie jeszcze jakieś sposoby na realizację powyżej przedstawionych funkcjonalności? Jeżeli tak, to oczywiście piszcie w komentarzach. Podyskutujemy :)

Roundup #2 – Circle Hover, AuthManager, HTML5 File Upload, CSSComb, HubSearch, canvas-charts, Motown

Roundup #2Circle Hover

Serwis Codrops jak zawsze dostarcza nam ciekawych artykułów. Tym razem jest to tutorial o tym, jak stworzyć ciekawe efekty :hover w formie kółek z wykorzystaniem animacji CSS oraz przejść 3D w CSS3.


AuthManager - Open Source User Authentication & Management

AuthManager

Jest to bilbioteka Open Source dla PHP. W oparciu o bazę MySQL pozwala ona na autentykację oraz zarządzanie użytkownikami, wykorzystując przy tym możliwości jakie daje nam integracja z serwisami społecznościowymi, takimi jak Facebook. Jest to narzędzie bardzo podobne do innej biblioteki dla PHP, jaką jest HybridAuth.

  • Protect your content with just few lines of code.
  • Login via Facebook Connect.
  • Spam protection using reCAPTCHA.
  • Google Analytics integration.
  • User access logs.
  • Email Templates.
  • Translation ready. Can be translated in any language.

Create a HTML5 Drag & Drop File Uploader with jQuery

HTML5 File Upload

Kolejny tutorial. Serwis InsertHTML opublikował poradnik, który pokazuje nam jak za pomocą HTML5, jQuery i kilku linijek w PHP możemy zbudować upload plików wykorzystujący technikę Drag & Drop oraz Local Storage z HTML5.


Greatest tool for sorting CSS properties in specific order

CSSComb

Jestem pewien, że każda osoba, która związana jest z pisaniem styli w CSS doceni to narzędzie. W Internecie jest wiele podobnych, darmowych serwisów, które są w stanie uporządkować nieco nasz arkusz styli. Żaden jednak nie potrafi zrobić tego w określonym porządku i wedle określonych zasad, które sami jesteśmy stanie stworzyć. To podejście stara się zmienić serwis CSSComb, który pozwala na sortowanie i robienie porządku w naszym ‘styles.css’ wedle określonej kolejności, którą definiujemy w prosty sposób przed samym użyciem narzędzia.


HubSearch is a GitHub search interface built with Bootstrap, Underscore, jQuery

HubSearch

Jest to niezależny interfejs dla GitHuba zbudowany przy użyciu między innymi Backbone, Underscore i jQuery. Pozwala na przeszukiwanie repozytoriów pod kątem konkretnego języka i słów kluczowych.


canvas-charts

Biblioteka JavaScript, która – wykorzystując HTML5 Canvas API – pozwala na budowanie wykresów. Typy tworzonych grafów to nic innego jak dodatkowe pluginy, które możemy dołączyć do interfejsu renderowania w naszym kodzie.


Motown

Kolejna biblioteka, dająca tym razem możliwość tworzenia interfejsów opartych o Metro, które pojawi się nam jesienią razem z najnowszym Windows 8. Całość zbudowana została przy użyciu  HTML, CSS i JavaScript.


[1], [2], [3], [4], [5]