Każda zmienna w PHP ma swój typ. W odróżnieniu do języków pokroju C++, w PHP typ danych nie musi być z góry określony, czyli ta sama zmienna może być raz „ciągiem znaków”, a raz „liczbą całkowitą”. Niestety takie dynamiczne typowanie to dość duży problem…
Zaczniemy od podstaw. W PHP do dyspozycji mamy następujące typy danych:
- bool – pozwala przechowywać tylko dwie wartości: „true” albo „false”
- int – przechowuje liczby całkowite, czyli „1”, „2”, „3”, „30”, ale nie może przechowywać tzw. ułamków
- float – używany jest do liczb zmiennoprzecinkowych, czyli na przykład „1.5”, „2.345”, „50.01”
- string – przechowuje ciąg znaków, czyli dowolny tekst np. „ładna jest dzisiaj pogoda”
- null – tzw. literał pusty, typ danych, który nie przechowuje niczego
- array – jest to tablica, która pozwala przechowywać przeróżne elementy dowolnego typu danych
- object – typ przechowujący obiekt jakiejś klasy
Dynamiczne typy danych
W poprzednim wpisie, gdy tworzyliśmy nasz kalkulator, używaliśmy funkcji readline
, która zapisywała wprowadzony tekst użytkownika do zmiennej:$element1 = readline('Podaj element 1: ');
Jak myślicie, jakiego typu danych będzie zmienna $element1
? Ktoś sprytniejszy może zajrzeć do dokumentacji i będzie widział, że będzie to „string” albo „false” (boolean). A jaki typ danych będzie zanim użyjemy readline
? Też „string”? A może „false”? A co jeśli Wam powiem, że będzie to „null”?
Niestety, jak sami widzicie, brak jasno zdefiniowanych typów danych to dość duży problem. Jak można pisać przewidywalny i dobrej jakości kod, skoro nawet nie wiemy jaki typ danych jest w zmiennej? Niestety, w PHP, póki co stosuje się różne tricki, np. type hinting, rzutowanie albo po prostu dodaje się komentarz w kodzie:
Te 3 powyższe metody zdecydowanie pomagają odnaleźć się w kodzie, gdyż od razu wiemy, jakiego typu danych możemy się spodziewać. Ale to nie wszystko. Ktoś spostrzegawczy mógłby zauważyć, że funkcja „sum” przyjmuje dwa argumenty, które powinny być „int”. My przekazujemy $element1, który jest „string” lub „false” oraz $element2, który jest „string”. Czyli żaden z tych argumentów nie ma typu „int”. Czy zatem powyższy kod jest niepoprawny?
Niekoniecznie. PHP domyślnie rzutuje typy danych, tak, by się zgadzały. Czyli jeśli mamy funkcje, która wymaga „int”, a my przekażemy „string”, to PHP automatycznie przekonwertuje „string” na „int”. Dodaje to dodatkowe nieścisłości, dlatego najlepszą praktyką jest dodawanie na początku kodu:declare(strict_types=1);
Po dodaniu tej „magicznej” formułki, IDE poinformowało o braku zgodności typów (gdyby nie IDE, błąd zobaczylibyśmy po uruchomieniu kodu). Najprościej będzie to rozwiązać po prostu rzutując wszystko do „int”:
Zagadka na koniec: Jaki typ danych będzie mieć zmienna $result?
Żeby poznać odpowiedź, dodajcie na końcu kodu var_dump($result)
. Funkcję var_dump()
możecie używać zawsze, kiedy chcecie poznać zawartość zmiennej. Pamiętajcie tylko, żeby używać jej tylko do debugowania, nigdy nie zostawiać jej w kodzie na dłużej!
Tablice
W odróżnieniu do większości języków programowania, tablice w PHP mogą przetrzymywać dane różnego typu. Poniżej przykład:
Nie jest to absolutnie dobra praktyka! W takiej tablicy ciężko się potem odnaleźć, jeśli chcemy z niej wyciągnąć dane. Najlepiej, żeby w tablicy znajdowały się tylko dane tego samego typu (lub chociaż o jasno określonej strukturze). Przykładem może być lista imion:
Z takiej zmiennej łatwo jest korzystać. Możemy np. użyć funkcji foreach
do wyświetlenia wszystkich imion:
Albo możemy je posortować alfabetycznie (robi to linia 10 na poniższym zrzucie ekranu):
Podsumowanie
Mogliście zauważyć, że PHP podchodzi do kwestii typów danych bardzo pobłażliwie, gdyż na dobrą sprawę można napisać działający kod, nie wiedząc nawet jakich typów danych użyliśmy (przykład: Kalkulator z poprzedniego wpisu). Mimo, że z pozoru jest to ułatwienie (zwłaszcza dla początkujących), to na dłuższą metę takie dynamiczne typowanie może doprowadzić do poważnych błędów w kodzie. Dlatego zachęcam Was do pilnowania typów danych, co najmniej w formie komentarza.