Jak wydobyć rozszerzenie z nazwy pliku.

Podziel się z innymi!

    Jednym z ważniejszych zabiegów optymalizujących kod aplikacji jest używanie przy wykonywaniu poszczególnych operacji, funkcji do tego dedykowanych. Powszechną jest opinia o nadużywaniu np. wyrażeń regularnych, czy też pisaniu własnych funkcji, których odpowiedniki są już zaimplementowane w samym PHP.

    Wydobycie rozszerzenia z nazwy pliku nie jest operacją zbyt skomplikowaną i zasobożerną jednak da się ją wykonać na kilka różnych sposobów. Postanowiłem przeprowadzić mały test sprawdzający, które z przyjętych rozwiązań wykona owo zadanie najsprawniej.

    Na początek przedstawię kilka sposobów wyekstrahowania rozszerzenia z pełnej ścieżki do pliku.

    Na początek użycie funkcji pathinfo

    function get_ext_using_pathinfo($path) {
    	$parts = pathinfo($path);
    	return $parts['extension'];
    }

    Użycie funkcji pathinfo ze stałą PATHINFO_EXTENSION – dostępną od wersji PHP 5.2

    function get_ext_using_pathinfo_with_const($path) {
    	return pathinfo($path, PATHINFO_EXTENSION);
    }

    Użycie funkcji operujących na tekście substr i strrpos

    function get_ext_using_substr_and_strrpos($path) {
    	return substr($path, strrpos($path, ".") + 1);
    }

    Użycie wyrażeń regularnych a dokładnie funkcji preg_replace

    function get_ext_using_preg_replace($path) {
    	return preg_replace('/.*\.([a-zA-Z0-9]*)$/', '\\1', $path);
    }

    Użycie wyrażeń regularnych z tymże tym razem funkcji preg_match

    function get_ext_using_preg_match($path) {
    	preg_match('/.*\.([a-zA-Z0-9]*)$/', $path, $matches);
    	return $matches[1];
    }

    Wykonanie exploda i wydobycie ostatniego elementu tablicy funkcją array_pop

    function get_ext_using_explode($path) {
    	return array_pop(explode('.', $path));
    }

    Przez każdą z wyżej wymienionych funkcji – w pętli for – 10 tys. razy przepuściłem zmienną zawierającą przykładową ścieżkę do pliku.

    $path = '/home/user/workplace/project/images/file.sufix.ext';

    Operację tę wykonałem kilkukrotnie zapisując wyniki do pliku. Po uśrednieniu i zaokrągleniu wyników wyszło mi:

    substr i strrpos preg_replace preg_match pathinfo ze stałą PATHINFO_EXTENSION explode i array_pop pathinfo
    0.077 0.0822 0.0904 0.0952 0.1049 0.1310

    Jak wynika z powyższego zestawienia najlepiej spisały się funkcje operujące na stringach. Funkcje preg_replace i preg_match pozytywnie mnie zaskoczyły gdyż spodziewałem się, że zaprzęgnięcie do tak prostej pracy tak potężnej maszyny jaką są wyrażenia regularne będzie obarczone sporą stratą czasu. Z kolei bardzo zawiodłem się na wbudowanej funkcji pathinfo, którą dotąd najczęściej wykorzystywałem do wydobycia potrzebnych mi informacji ze ścieżki. Myślałem, że jest bardziej wydajna, a tu się okazało, że w wersji uniemożliwiającej użycie stałej PATHINFO_EXTENSION jest ona wolniejsza nawet od exploda. Nie skreślałbym tej funkcji w przypadku chęci uzyskania kompletu danych o ścieżce jednak dla atomowej operacji wydobycia rozszerzenia warto pomyśleć o innym sposobie. Z drugiej strony, różnice jak widać nie są znowu tak wielkie, więc dla tego prostego zadania w 99% przypadków użycia nie będzie miało znaczenia, którego z rozwiązań użyjemy i spokojnie możemy kierować się wygodą.

    Podziel się z innymi!

      2 Comments

      1. Nowaker

        Na oko, to Twoje rozwiązanie problemu z substr i strpos poda złą odpowiedź dla „/home/nowaker.net/plik” (poda „net/plik”). Zaś pathinfo, zdaje się, nie pomyli się. Zawsze lepiej używać specjalizowanych metod, niż wymyślać koło na nowo.

      2. Zbigniew Heintze Post author

        @Nowaker Masz rację, poza tym jak widać różnice w czasach wykonania są niewielkie więc można potraktować ten wpis jako ciekawostkę.

      Dodaj komentarz

      Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *