Tablice w PHP

Adam Boduch

Tablice są jednym z wielu rodzajów kolekcji - elementem języka programowania, służącym do przechowywania wielu podobnych danych w jednym miejscu. Obecne w wielu językach, również w PHP, znacznie ułatwiają pracę.

Jak już wiesz z lektury poprzednich artykułów w tym dziale, zmienne stanowią pojemniki na dane - w zmiennych możesz zapisać dane, aby je później odczytać w dalszej części programu. Można powiedzieć, że tablice stanowią zbiór pojemników na dane.

Wyobraź sobie, że w swojej aplikacji musisz przechować imię, nazwisko oraz adres zamieszkania. Wiąże się to z deklaracją kilku zmiennych. Dzięki tablicom wszystkie te dane możesz przechować w jednym "pojemniku". Już jest to znaczne ułatwienie. A pomyśl sobie, co by było, jeżeli musiałbyś przechować w zmiennych kilkanaście adresów oraz nazwisk. Nie ma problemu! Dzięki tablicom wszystkie te dane mogą być zgromadzone w jednej liście.

Czym są tablice?

Tablica w PHP jest listą, na którą składają się elementy. Elementy z kolei przechowują wartości, które mogą być np. liczbami czy też łańcuchami danych, wartościami true/false, obiektami lub nawet innymi tablicami. Tak jak zmienna jest "pojemnikiem" na dane, tak w tablicy można trzymać wiele takich danych. Wszystko co można zawżeć w zmiennej, można też umieścić jako kolejny element w tablicy.

Przykłady dobrych zastosowań tablic

  1. Tłumaczenia kolorów
'red' => 'czerwony',
'green' => 'zielony',
'blue' => 'niebieski',
'yellow' => 'żółty',
'black' => 'czarny', 

Tablica o rozmiarze 5, mająca klucze 'red', 'green', 'blue', 'yellow' i 'black' oraz wartości 'czerwony', 'zielony', 'niebieski', 'żółty', 'czarny'.
2. Lista przyjaciół

0 => 'Jan Nowak',
1 => 'Tomasz Kowalski',
2 => 'Brad Pitt',
3 => 'Alicja Kowalska'

Tablica o rozmiarze 4, o kluczach będące kolejnymi liczbami całkowitymi (tz. 0, 1, 2 i 3) i wartościach 'Jan Nowak', 'Tomasz Kowalski', 'Brad Pitt', 'Alicja Kowalska'.
3. Licznik punków

'Jan Nowak' => 5,
'Brad Pitt' => 4,
'Alicja Kowalska' => 1

Ta tablica ma 3 elementy, i ma reprezentować liczbę punktów różnych ludzi. Kluczami są ich imiona, wartościami są ich punkty.

Tablice w PHP są trochę unikatowe względem innych języków; ponieważ w PHP tablice mogą mieć dowolne klucze. W innych językach programowania: Java, C#, C++, JavaScript, Python, Ruby i wiele innych, klucze w tablicach zawsze są kolejnymi liczbami całkowitymi: 0, 1, 2, 3, 4, 5, itd. Dodanie nowego elementu skutkuje ustawieniem nowego klucza na 6. Usunięcie elementu z listy przesuwa wszystkie klucze na nowo, tak, że klucze są znów kolejnymi liczbami całkowitymi. Więc jest element "X" zanjduje się pod kluczem 18, a inny element przed nim zostanie usunięy, element "X" będzie już dostepny pod kluczem 17; również kolejne elementy będą przesunięte, tak żeby klucze były kolejnymi liczbami całkowity. Innymi słowy klucz w większości języków programowania jest bardziej numerem porządkowym elementów w tablicy. Niestety, PHP jest tutaj wyjątkiem, klucze mogą być w dowolnej kolejności, nie muszą być wcale liczbami całkowitymi, mogą być ujemne, a nawet być innym typem: string! Z tego powodu tablicom w PHP jest bliżej do map/słowników z innych języków, niż tabliocm.

Żeby osiągnąć efekt tablicy z PHP, w innych językach istnieją do tego inne struktury - mają różne nazywy: mapa, słownik, dictionary, obiekt/object, lub inne.

Z tego powodu tablicom w PHP jest właściwie bliżej do map/słowników z innych języków, niż do tablic. Ale niestety noszą nazwę "tablica", więc tak właśnie o nich myślą programiści, więc "zwykłe" tablice w PHP (tzn z kluczami które są kolejnymi liczbami całkowitymi) noszą nazwy "tablica" lub "tablica sekwencyjna", a kiedy tablica ma klucze które są typu string, nazywane są przez programistów "tablicą asocjacyjną". Ale oczywiście taka nazwa jest jedynie umowna, ponieważ w PHP każda tablica jest asocjacyjna, nawet taka która ma klucze liczbowe.

Pamiętajmy że tablicom w PHP można ustalić dowolny klucz typu int oraz string w dowolnej kolejności, nawet ujemne liczby. To że klucze są kolejnymi liczbami 0, 1, 2, 3, etc. jest przypadkiem szczególnym.

Idea tablic

Większość programistów, spytana o ideę tablic, odpowie że są one po to żeby "grupować dane", lub trzymać "je w jednym miejscu". Nie jest to do końca prawda, dlatego że dużo lepszym miejscem na "grupowanie danych" jest albo obiekt w php (stdClass) albo klasa.

Tablice są raczej miejscem na nieznaną, mnogą ilość danych, albo sekwencyjną (lista/zbiór, np lista przyjaciół, historia transakcji, lista godzin, lista plików w folderze, etc.), która ma klucze rosnących liczb całkowitych; albo reprezentujące przypisania które są dynamiczne, np przypisania 'nazwa' => 'wartość', tłumaczenie "angielski => polski".

Do przechowywania takich wartości jak np czyjeś imie, nazwisko i wiek, lepsza byłaby klasa class Person { private $name; private $surname; private $age }.

Tworzenie tablic

W PHP można stworzyć tablicę na kilka sposobów:

  • Nawiasy kwadratowe: ['dog', 'cat', 'bird'] (niedostępne do PHP 5.6)
  • Tzw. short-array syntax: array('dog', 'cat', 'bird')
  • Rozszerzanie istniejącej tablicy
  • Użycie wbudowanych funkcji PHP, jak array_combine()

Sposoby ['dog', 'cat', 'bird'] oraz array('dog', 'cat', 'bird') są sobie w 100% równoważne. Nawiasy kwadratowe są jedynie troszkę krótsze, przez to są częściej używane. Zapis array() był używany w starszych wersjach PHP, jednak jest nadal dostępny.

Tworzenie tablicy już wypełnionej

Jednym ze sposobów tworzenia tablic jest użycie składni array() lub []:

<?php
$imiona = array('red' => 'czerwony', 'green' => 'zielony');

Dla czytelności, można je zapisać z wcięciami.

<?php
$kolory = [
  'red' => 'czerwony', 
  'green' => 'zielony',
  'blue' => 'niebieski',
  'black' => 'czarny'
];

W powyższym skrypcie zadeklarowałem tablicę o nazwie $kolory, która zawiera kilka elementów łańcuchowych.

W tym przykładzie wszystkie elementy tablicy są łańcuchami, lecz nic nie stoi na przeszkodzie, aby elementy były mieszane (tj. elementy mogą być dowolnego typu):

$rozneWartosci = ['Marcin', 0, 1.11, true, false, null, -5];

Zauważysz pewnie, że w powyższym przykładzie nie podaliśmy kluczy (jawnie). Ale PHP ustawił każdemu elementowi unikatowy klucz. W tablicach klucze zawsze muszą być unikatowe, żeby jeden konkrety klucz zawsze wskazywał na jakąś wartość. Jakie klucze więc PHP wybrał dla takiej tablicy, w której nie podaliśmy jawnie kluczy? PHP stworzył tablicę sekwencyjną, tzw wybrał klucze które są kolejnymi liczbami całkowitymi, zaczynając od zera.

Te dwie tablice są sobie równoważne:

<?php
$tablica1 = ['Marcin', 0, 1.11, true, false, null, -5];
$tablica2 = [
  0 => 'Marcin', 
  1 => 0, 
  2 => 1.11, 
  3 => true, 
  4 => false, 
  5 => null, 
  6 => -5
];

Mimo, że klucze w jednej są zadeklarowane niejawniea w drugiej jawnie, obie są nazywane tablicami sekwencyjnymi (ponieważ ich klucze są koljenymi liczbami całkowitymi, począwszy od zera).

W PHP 8.1 jest dostępna funkcja array_is_list(), która sprawdza czy tablica jest sekwencyjna.

Ponieważ, z reguły tablice sekwencyjne są używane częściej niż takie z arbitralnymi kluczami, dla wygody nie musimy deklarować kluczy jawnie w PHP. Domyślnie klucze będą kolejnymi liczbami całkowitymi.

Rozszeżanie istniejącej tablicy

Innym sposobem inicjacji tablicy jest stworzenie pustej tablicy, i dodanie do niej nowych elementów.

<?
$animals = []; // pusta tablica
$animals['dog'] = 'pies'; // dodanie pierwszego elementu
$animals['cat'] = 'kot'; // kolejnego
$animals['bird'] = 'ptak'; // i kolejnego

By stworzyć tablicę sekwencyjną, wystarczy podać kolejne liczby całkowite jako klucze.

<?
$imiona1 = [];
$imiona1[0] = 'Marcin';
$imiona1[1] = 'Daniel';
$imiona1[2] = 'Magda';
$imiona1[3] = 'Paulina';

Dla wygody, ponieważ tablice sekwencyjne są tak często używane, podobnie jak nie trzeba jawnie podawać kluczy przy używaniu array() oraz [], nie trzeba jawnie podawać kluczy również podczas rozszerzenia tablicy. PHP wtedy wybierze, podobnie jak w poprzednich przypadkach, klucz który jest kolejną liczbą całkowitą.

<?
$imiona2 = [];
$imiona2[] = 'Marcin';  // zostanie wybrany klucz 0
$imiona2[] = 'Daniel';  // tutaj klucz 1
$imiona2[] = 'Magda'; // tutaj klucz 2
$imiona2[] = 'Paulina'; // czy zgadniesz jaki klucz będzie tutaj?

Tablice $imiona1 oraz $imiona2 są sobie równoważne.

Indeksy tablicy nie muszą być numerowane od zera, nie muszą być także kolejnymi liczbami. Kolejny przykład tworzy pięcioelementową tablicę o kluczach: 100, 101, 200, 105:

<?php
$imiona[100] = 'Marcin';
$imiona[101] = 'Daniel';
$imiona[200] = 'Magda';
$imiona[105] = 'Paulina';
$imiona[] = 'Aneta';

W ostatniej linii tego skryptu, przypisałem do tablicy element bez podawania klucza. Wtedy PHP użyło następnego numeru po najwyższym indeksie, w tym wypadku 201.

Określanie klucza w konstrukcji array()

Używając składni array() stworzyliśmy tablicę z elementami, które były przypisane do kluczy, które były kolejnymi liczbami całkowitymi. Aby jawnie nadać klucz elementom, należy zastosować operator =>, który jest poprawny tylko wewnętrz array() lub [] i nigdzie indziej.

$imiona = array('Marcin', 100 => 'Daniel', 200 => 'Magda', 'Paulina');

Takie utworzenie tablicy spowodowało, że mamy tablicę cztero-elementową, w której pod kluczem 0 znajduje się wartość 'Marcin', pod kluczem 100 wartość 'Daniel', pod kluczem 200 wartość 'Magda', a pod kluczem 201 wartość 'Paulina'.

Jak wspomniałem wcześniej, klucze tablicy mogą być wartościami tekstowymi:

$lang = array('pl' => 'polski', 'de' => 'niemiecki');
$lang = ['pl' => 'polski', 'de' => 'niemiecki'];

Inny sposób:

$lang = [];
$lang['pl'] = 'polski';
$lang['de'] = 'niemiecki';

Odwołanie do tablic

Pomimo iż tablice tworzy się podobnie jak zmienne, nie można się do nich odwołać w taki sam sposób. Nie możemy np po prostu spróbować jej wyświetlić (próba wypisania tablicy przy pomocy instrukcji echo spowoduje po prostu wyświetlenie napisu "Array").

<?
$imiona = Array('Marcin', 100 => 'Daniel', 200 => 'Magda', 'Paulina');
echo $imiona; // "Array"

Jeżeli z jakiegoś powodu chcesz po prostu zobaczyć jakie wartości są w tablicy, skorzystaj z print_r() lub var_dump().

<?
$imiona = Array('Marcin', 100 => 'Daniel', 200 => 'Magda', 'Paulina');
print_r($imiona);

Zobaczysz wtedy coś takiego:

Array
(
    [0] => Marcin
    [100] => Daniel
    [200] => Magda
    [201] => Paulina
)

Dzięki temu możesz w prosty sposób przeglądać strukturę tablicy, wraz z kluczami oraz wartościami. Jednak pamiętaj że print_r() oraz var_dump() to funkcje które raczej nadają się jedynie do zastosowań developerskich i debugowania, tzn szukania błędów w programie. Nie powinny być stosowane w "normalnym" działaniu aplikacji.

Chcąc wyświetlić pojedynczą zawartość elementu, możesz użyć instrukcji echo odwołując się do elementu tablicy przy pomocy nawiasów kwadratowych:

$imiona = Array('Marcin', 100 => 'Daniel', 200 => 'Magda', 'Paulina');
echo $imiona[0]; // wyświetli "Marcin"
echo $imiona[200]; // wyświetli "Magda"

$imiona[201] = 'Katarzyna'; // zmiana wartości
echo $imiona[201]; // wyświetli "Katarzyna"

Jeżeli spróbujesz się odwołać do elementu nieistniejącego (np. poprzez klucz 2) PHP rzuci ostrzeżenie: Undefined offset: 2, i zamiast tego zostanie zwróca wartość null

<?php
$tablica = [];
$wartosc = $tablica['nie istnieje'];
$wartosc // null

Zależnie od ustawień servera i instalacji PHP, takie odniesienie się do nieistniejącego elementu tablicy może albo zastopować działanie aplikacji, kończąc się błędem, albo zwrócić wartośc null.

Tablice asocjacyjne

"Tablice asocjacyjne" to umowna nazwa na tablice w PHP, których klucze nie są kolejnymi liczbami całkowitymi zaczynającymi się od 0. Np tablica z kluczami 1, 2, 3 również jest asocjacyjna. Także tablica z kluczami 1, 2, 0 jest asocjacyjna. Tylko tablica której klucze zaczynają się od 0, i są kolejnymi liczbami całkowitymi, tylko wtedy tablica nazywana jest sekwencyjną.

<?
$dane = [];
$dane['imię'] = 'Jan';
$dane['nazwisko'] = 'Kowalski';
$dane['ulica'] = 'Kowalowska';
  
print_r($dane);

echo $dane['imię']; // "Jan"

Jak widzisz na powyższym przykładzie, klucze tablicy stanowią łańcuchy tekstowe. Odwołanie do tak skonstruowanej tablicy, polega na podaniu odpowiedniego klucza.

Tablice wielowymiarowe

Do tej pory korzystaliśmy z tablic jednowymiarowych. PHP umożliwia także deklaracje tzw. tablic wielowymiarowych. Polega to na tworzeniu kolejnych węzłów elementu dając przy tym wrażenie drzewa elementów. "Tablica wielowymiarowa" to umowna nazwa na tablicę, która zawiera w sobie inne tablice.

  • Talibca która zawiera wartości nazywana jest tablicą jednowymiarową.
  • Tablica, która zawiera tablice, która zawiera wartości nazywana jest tablicą dwuwymiarową.
  • Tablica, która zawiera tablice, która zawiera tablice, która zawiera wartości, nazywana jest tablicą trójwymiarową
  • i tak dalej

"Tablice wielowymiarowe" jest tylko wygodnym uproszczeniem, tak na prawdę tablice to również zmienne które mają w sobie inne zmienne. A skoro tak, to tablice mogą przechowywać takie zmienne, ktore również są tablicami. Proste :)

<?php
$osoba1 = [];
$osoba1['imię'] = 'Jan';
$osoba1['nazwisko'] = 'Kowalski';
$osoba1['ulica'] = 'Kowalowska';

$osoba2 = [];
$osoba2['imię'] = 'Maciej';
$osoba2['nazwisko'] = 'Nowak';
$osoba2['ulica'] = 'Nowakowska';

$dwuwymiarowa = [];
$dwuwymiarowa[0] = $osoba1;
$dwuwymiarowa[1] = $osoba2;

print_r($dane);

Jak widzimy, tablice $osoba1 oraz $osoba2 są tablicami jednowymiarowymi. Jednak tablica $dwuwymiarowa mogłaby być nazwana dwuwymiarową, ponieważ jest tablicą która zawiera inne tablice.

Innym sposobem zapisu tablicy, może być zmiana kolejności przypisań wartości, przez co kod może być odrobinę mniej czytelny. Zachowanie jednak będzie takie samo.

$dwuwymiarowa = [];
$dwuwymiarowa[0] = [];
$dwuwymiarowa[1] = [];

$osoba1 = [];
$osoba1['imię'] = 'Jan';
$osoba1['nazwisko'] = 'Kowalski';
$osoba1['ulica'] = 'Kowalowska';
$dwuwymiarowa[0] = $osoba1;

$osoba2 = [];
$osoba2['imię'] = 'Maciej';
$osoba2['nazwisko'] = 'Nowak';
$osoba2['ulica'] = 'Nowakowska';
$dwuwymiarowa[1] = $osoba2;

print_r($dane);

a posługując się kolejnym trkiciem, możemy zainicjalizować tablicę bezpośrednio przypisując wartości do tablicy dwuwymiarowej. Jest to jednak bardziej zaawansowana technika i może wymagać więcej umiejętności - nie musisz umieć tworzyć tablic dwuwymiarowych od razu.

$dwuwymiarowa = [];

$dwuwymiarowa[0] = [];
$dwuwymiarowa[0]['imię'] = 'Jan';
$dwuwymiarowa[0]['nazwisko'] = 'Kowalski';
$dwuwymiarowa[0]['ulica'] = 'Kowalowska';

$dwuwymiarowa[1] = [];
$dwuwymiarowa[1]['imię'] = 'Maciej';
$dwuwymiarowa[1]['nazwisko'] = 'Nowak';
$dwuwymiarowa[1]['ulica'] = 'Nowakowska';

print_r($dane);

W powyższym przykładzie dwa główne "węzły" to elementy opatrzone indeksami 0 oraz 1. Każdy z tych elementów posiada kolejne o nazwach "imię", "nazwisko" oraz "ulica". Działanie takiego programu spowoduje wyświetlenie następującej struktury:

Array
(
    [0] => Array
        (
            [imię] => Jan
            [nazwisko] => Kowalski
            [ulica] => Kowalowska
        )

    [1] => Array
        (
            [imię] => Maciej
            [nazwisko] => Nowak
            [ulica] => Nowakowska
        )

)

Oczywiście oba klucze w tej tablicy mogą być łańcuchami (typu string):

<?
$kraje = [
    'Europa' => ['Polska', 'Anglia', 'Litwa', 'Francja'],
    'Afryka' => ['Tunezja', 'Egipt', 'RPA', 'Etiopia'],
    'Azja' => ['Chiny', 'Mongolia', 'Japonia', 'Kazachstan']
];

print_r($kraje);

Wydaje mi się że poprzednia konstrukcja jest jednak bardziej przejrzysta niż ta z użyciem słowa Array(). Tak napisany skrypt da następujące wyniki:

Array
(
    [Europa] => Array
        (
            [0] => Polska
            [1] => Anglia
            [2] => Litwa
            [3] => Francja
        )

    [Afryka] => Array
        (
            [0] => Tunezja
            [1] => Egipt
            [2] => RPA
            [3] => Etiopia
        )

    [Azja] => Array
        (
            [0] => Chiny
            [1] => Mongolia
            [2] => Japonia
            [3] => Kazachstan
        )

)

Pętla foreach

O pętli foreach wspominałem już w poprzednim rozdziale. Napisałem tam także, że pętla foreach używana jest jedynie w połączeniu z tablicami (lub bardziej zaawansowanymi bytami jak Traversable, Iterable lub Generator). Składnia tej pętli jest następująca:

foreach (tablica as wartość)
{
   instrukcje;
}

Pętla foreach przechodzi po każdym z elementów tablicy i pozwala nam go odczytać przy każdym kroku. Oto skrypt z poprzedniego przykładu rozbudowany o pętlę foreach:

<?php
$kontynenty = [
      'Europa' => ['Polska', 'Anglia', 'Litwa', 'Francja'],
      'Afryka' => ['Tunezja', 'Egipt', 'RPA', 'Etiopia'],
      'Azja' => ['Chiny', 'Mongolia', 'Japonia', 'Kazachstan']
];
  
foreach ($kontynenty as $kraje) {
      echo "$kraje[0]\n"; // pierwszy kraj
}

Za każdą iteracją pętli do zmiennej $kraje przypisywana jest kolejna zagnieżdżona tablica. Odwołując się do klucza 0 wyświetlamy pierwszy element z zagnieżdżonej tablicy:

Polska
Tunezja
Chiny

Działanie pętli foreach tak na prawdę iteruje jednocześnie po kluczach jak i wartościach, jednak z uwagi że tablice sekwencyjne są częsciej używane, iterowanie po kluczu można pominąć. Pełna składnia foreach tak na prawdę występuje z operatorem =>.

foreach ($kontynenty as $kontynent => $kraje)

W powyższym przykładzie, do zmiennej $kontynent zostanie przypisany klucz, natomiast do zmiennej $kraj wartość pod kluczem. Przykład poniżej generuje tabele HTML z nazwami państw z danego kontynentu.

<html>
<head>
<title>Kontynenty i państwa</title>
</head>
<body>

<table border="1" cellspacing="2">
 <tr>
   <td width="100%" colspan="5" align="center">Kraje i kontynenty</td>
 </tr>
 <?
  $kontynenty = Array(
      'Europa' => array('Polska', 'Anglia', 'Litwa', 'Francja'),
      'Afryka' => array('Tunezja', 'Egipt', 'RPA', 'Etiopia'),
      'Azja' => array('Chiny', 'Mongolia', 'Japonia', 'Kazachstan')
  );
  
  foreach ($kontynenty as $kontynent => $kraje)
  {
      echo '<tr><td width="20%"><b>' . $kontynent . '</b></td>';
      
      foreach ($kraje as $kraj)
      {
          echo '<td width="20%">' . $kraj . '</td>';
      }
      
      echo '</tr>';
  }
?>
</table>
</body>
</html>

W powyższym przykładzie musiałem użyć dwóch pętli, z której jedna jest zagnieżdżona w drugiej. Wszystko przez to, że w tym przykładzie mamy do czynienia z tablicą wielowymiarową. Druga pętla for generuje kolejne komórki z nazwami państw z danego kontynentu. Nazwa kontynentu wpisywana jest w pierwszą komórkę danego wiersza.

Instrukcje empty(), isset() i funkcja count()

Dwie instrukcje: empty() oraz isset() służą do sprawdzania czy zmienna jest pusta oraz czy dana zmienna istnieje (została zadeklarowana). Polecenia te służą także do sprawdzania czy istnieje dany element tablicy.

Instrukcja empty() sprawdza czy zmienna jest pusta. Zwróci true jeżeli zmienna w ogóle nie istnieje lub posiada wartość 0, "", null, [] lub false. W każdym z tych przypadków zmienna $var jest pusta, funkcja empty() zwróci true. Jakakolwiek inna wartość spowoduje, iż empty() zwróci false.

Instrukcja isset() zwraca true jeżeli zmienna podana w parametrze istnieje. Nieważne jest, czy posiada wartość 0, "" czy false - w takich przypadkach isset() zwróci true. Oto zmodyfikowana wersja poprzedniego przykładu. isset() zwróci jednak false, jeśli zmienna posiada wartość null.

Tablice zewnętrzne

Gdy chcemy wyświetlić zawartość jakiejś strony, która generowana jest przy pomocy skryptu PHP, serwer na żądanie przekazuje wykonywanie strony do PHP. Mechanizm języka PHP wykorzystuje informacje zawarte w żądaniu w celu określenia który plik należy uruchomić, jak i również wykorzystuje te informacje w celu ustawienia wartości kilku zmiennych.
Lepiej będzie, gdy taką sytuację zobrazuje przykładem. Załóżmy, że posiadasz stronę WWW, która wyświetla formularz służący do wpisania adresu e-mail. Chcemy, aby po naciśnięciu przycisku "Wyślij zawartość" formularza została przekazana do skryptu, który taki adres e-mail zapisałby w bazie danych. W takim przypadku przeglądarka wysyła żądanie do serwera, ten z kolei uruchamia skrypt PHP. W żądaniu przekazuje kilka informacji jak np. adres e-mail, który użytkownik wpisał w formularzu.

Wymiana danych

Przeglądając strony WWW, klikasz na odnośniki, które prowadzą do plików umieszczonych na serwerze. Niekiedy jednak korzystanie z serwisu wymaga wypełnienia formularza, którego zawartość wędruje najczęściej do odpowiedniego skryptu PHP, ASP lub CGI. Odwiedzasz także strony tworzone dynamicznie (tzn. również przy użyciu języków skryptowych), a do adresu dołączane są jakieś parametry. Te dwa przykłady wysyłania informacji nazywane są metodami GET i POST.

Metoda POST

Załóżmy, ze przeglądasz stronę internetową. Na tej stronie znajduje się formularz, po którego wypełnieniu i naciśnięciu przycisku Wyślij informacje wędrują do autora strony. Najczęściej za taki proces odpowiada skrypt wykonywany po stronie serwera.

Przeglądarka przesyła dane z formularza w ciele żądania HTTP do serwera obsługującego żądanie. Zależnie od formatu, ich wygląd może się różnić, jednak domyślnym jest application/x-www-form-urlencoded, a takie ciało wygląda w taki sposób.

nazwa_pola=wartosc_pola&nazwa_pola2=wartosc_pola2

Poszczególne parametry URL są oddzielone od siebie znakiem &. Natomiast nazwa danego pola jest oddzielona od wartości znakiem =. W ten sposób połączone dane wędrują wraz z nagłówkiem do skryptu, który już je odpowiednio interpretuje. Istotą metody POST jest właśnie to, że dane są przekazywane w ciele HTTP.

Metoda GET

Metoda GET różni się odrobinę od metody POST. Tzn. dane, które są przekazywane są zbudowane tak samo jak przy użyciu formatu application/x-www-form-urlencoded (który jest wybierany domyślnie) poszczególne pola są oddzielone znakiem &. Zasadniczą jednak różnicą jest to, że te dane są dołączane do adresu strony, czyli wygląda to mniej więcej tak:

http://www.4programmers.net/skrypt.php?pole1=wartosc1&pole2=wartosc2

Metodą GET dane można przekazywać niewielkie ilości danych. Nie zaleca się przekazywania tą metodą np. zawartości dużych pół edycyjnych itp.

Zmienne systemowe

PHP udostępnia nam kilka zmiennych systemowych, które są przekazywane przez serwer. Są to zmienne super-globalne, tzn takie które są dostępne z każdego miejsca, nawet bez użycia global.

<?php
print_r($_SERVER);

Tablica środowiskowa $_ENV

Tablica $_ENV zawiera informacje odnośnie zmiennych środowiskowych, maszyny na jakiej proces PHP jest uruchamiany. Dzięki elementom znajdującym się w tablicy możemy poznać ścieżkę katalogu systemowego, czy np. architekturę procesora. Użycie instrukcji print_r() na tablicy $_ENV zwraca następujące rezultaty:

Array
(
    [ALLUSERSPROFILE] => C:\Documents and Settings\All Users
    [CommonProgramFiles] => C:\Program Files\Common Files
    [COMPUTERNAME] => BODUCH
    [ComSpec] => C:\WINDOWS\system32\cmd.exe
    [NUMBER_OF_PROCESSORS] => 1
    [OS] => Windows_NT
    [Path] => C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\Program Files\Network Associates\PGPNT
    [PATHEXT] => .COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH
    [PROCESSOR_ARCHITECTURE] => x86
    [PROCESSOR_IDENTIFIER] => x86 Family 6 Model 3 Stepping 1, AuthenticAMD
    [PROCESSOR_LEVEL] => 6
    [PROCESSOR_REVISION] => 0301
    [ProgramFiles] => C:\Program Files
    [SystemDrive] => C:
    [SystemRoot] => C:\WINDOWS
    [TEMP] => C:\WINDOWS\TEMP
    [TMP] => C:\WINDOWS\TEMP
    [USERPROFILE] => C:\Documents and Settings\LocalService
    [windir] => C:\WINDOWS
)

Należy zaznaczyć, że pomimo tego, iż tablica $_ENV jest tablicą superglobalną, to zasada korzystania jest taka sama jak w przypadku zwykłych tablic:

echo "Ścieżka do katalogu systemowego: " . $_ENV['SystemRoot'];

Tablica $_SERVER

Tablica $_SERVER zawiera informacje dotyczące nagłówka HTTP oraz innych informacji zależny od aktualnego uruchomienia skryptu. Z informacji zawartych w tej tablicy możemy się dowiedzieć, np. o ścieżce do skryptu PHP.

Array
(
    [COMSPEC] => C:\WINDOWS\system32\cmd.exe
    [DOCUMENT_ROOT] => c:/usr/coyote/coyote-0-9-1/
    [HTTP_ACCEPT] => */*
    [HTTP_ACCEPT_ENCODING] => gzip, deflate
    [HTTP_ACCEPT_LANGUAGE] => pl
    [HTTP_CONNECTION] => Keep-Alive
    [HTTP_HOST] => 127.0.0.1
    [HTTP_USER_AGENT] => Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322)
    [PATH] => C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\Program Files\Network Associates\PGPNT
    [REMOTE_ADDR] => 127.0.0.1
    [REMOTE_PORT] => 1131
    [SCRIPT_FILENAME] => c:/usr/coyote/coyote-0-9-1/php/test.php
    [SERVER_ADDR] => 127.0.0.1
    [SERVER_ADMIN] => [email protected]
    [SERVER_NAME] => 127.0.0.1
    [SERVER_PORT] => 80
    [SERVER_SIGNATURE] => 
Apache/1.3.27 Server at 127.0.0.1 Port 80
    [SERVER_SOFTWARE] => Apache/1.3.27 (Win32) PHP/5.0.0RC3
    [SystemRoot] => C:\WINDOWS
    [WINDIR] => C:\WINDOWS
    [GATEWAY_INTERFACE] => CGI/1.1
    [SERVER_PROTOCOL] => HTTP/1.1
    [REQUEST_METHOD] => GET
    [QUERY_STRING] => 
    [REQUEST_URI] => /php/test.php
    [SCRIPT_NAME] => /php/test.php
    [PATH_TRANSLATED] => c:/usr/coyote/coyote-0-9-1/php/test.php
    [PHP_SELF] => /php/test.php
)

Tablica $_GET

Elementy tablicy $_GET pochodzą z query parameters HTTP GET przekazanego do skryptu. Przykładowo, jeżeli kontrolka tekstowa, w formularzu HTML nosi nazwę "username" to w tablicy, wartość z tej kontrolki zostanie zapisana do elementu $_GET['username']. Napiszmy przykładowy skrypt, który umożliwia wpisanie w formularzu nazwy użytkownika oraz hasła. Jeżeli użytkownik poda prawidłowe informacje, dostęp do dalszej części skryptu zostanie odblokowany. Kod źródłowy takiego skryptu znajduje się na listingu ponizej:

<html>
<head>
<title>Logowanie</title>
</head>
<body>

<?

  if ( $_GET['username'] )
  {
      if ( $_GET['username'] == 'root' && $_GET['password'] == 'root' )
      {
          echo 'Weryfikacja przeprowadzona - dostęp odblokowany!<br>';
      }
      else
      {
          echo 'Brak dostępu!<br>';
      }
      exit;
  }
  else
  {

?>
 <form action="p4.2.php" method="GET">
  <table border="1">
    <tr><td width="100%" colspan="2" align="center">Logowanie</td></tr>
    <tr>
      <td width="30%">Nawa użytkownika</td>
      <td width="70%"><input type="text" name="username"></td>
    </tr>
    <tr>
      <td width="30%">Hasło</td>
      <td width="70%"><input type="password" name="password"></td>
    </tr>
    <tr>
      <td width="30%"> </td>
      <td width="70%"><input type="submit" value="Zaloguj"></td>
    </tr>
  </table>
 </form>
<?
   }
?>
</body>
</html>

Pierwsza instrukcja (instrukcja warunkowa) sprawdza czy w tablicy $_GET istnieje cokolwiek pod kluczem "username". Jeżeli tak, wykonywany jest blok instrukcji mający na celu sprawdzenie czy hasło oraz nazwa użytkownika jest poprawna. Jeżeli tak, wyświetlamy odpowiedni napis. Instrukcja exit() zawarta w tym programie kończy działanie skryptu dalsze polecenia nie będą wykonywane.

Jeżeli tablica $_GET nie zawiera elementu "username" (lub jest on "pusty", jak false, 0, "") wyświetlany jest kod HTML z formularzem służącym do wprowadzenia nazwy użytkownika oraz hasła. Zwróć uwagę na następującą linię kodu HTML:

<form action="p4.2.php" method="GET"> 

Znacznik <form> ma na celu utworzenie formularza. Parametr action określa ścieżkę programu, do którego skierowane zostanie żądanie. Parametr method określa metodę żądania, w tym wypadku HTTP GET. Dzięki temu parametry z formularza zostaną przekazane w adresie.

http://127.0.0.1/p4.2.php?username=root&password=root

Tablica $_POST

Działanie tablicy $_POST jest praktycznie takie same jak działanie tablicy $_GET. Różnica polega na tym, że elementy w tablicy $_POST pochodzą z wywołania HTTP POST.

Zmodyfikuj program z listingu tak aby żądanie było przekazywane w nagłówku HTTP POST. Pierwsze, co musisz zrobić, to doprowadzić znacznik <form> do takiej postaci:

<form action="p4.3.php" method="POST">

Drugim etapem będzie zastąpienie tablicy $_GET przez tablicę $_POST

<html>
<head>
<title>Logowanie</title>
</head>
<body>

<?
  if ( $_POST['username'] )
  {
      if ( $_POST['username'] == 'root' && $_POST['password'] == 'root' )
      {
          echo 'Weryfikacja przeprowadzona - dostęp odblokowany!<br>';
      }
      else
      {
          echo 'Brak dostępu!<br>';
      }
      exit;
  }
  else
  {

?>
 <form action="p4.3.php" method="POST">
  <table border="1">
    <tr><td width="100%" colspan="2" align="center">Logowanie</td></tr>
    <tr>
      <td width="30%">Nawa użytkownika</td>
      <td width="70%"><input type="text" name="username"></td>
    </tr>
    <tr>
      <td width="30%">Hasło</td>
      <td width="70%"><input type="password" name="password"></td>
    </tr>
    <tr>
      <td width="30%"> </td>
      <td width="70%"><input type="submit" value="Zaloguj"></td>
    </tr>
  </table>
 </form>
<?
   }
?>
</body>
</html>

Tablica $_FILES

Tablica $_FILES przechowuje informacje pochodzące z przesłania żadnia HTTP o próbie wysłania pliku. Żądnie takie można łatwo wykonać dzięki kontrolce HTML file, która umożliwia wysyłanie plików do serwera. My możemy obsłużyć takie wywołanie w dowolny sposób: zignorować, wysłać dalej, zapisać taki plik na serwerze zewnętrznym lub nawet tym samym na którym działa proces php. Teraz zajmijmy się jedynie wyświetlaniem informacji o pliku. Takie informacje zawarte są w tablicy wielowymiarowej - $_FILES. Listing ponizej zawiera kod źródłowy skryptu, który wyświetla informacje na temat pliku wysyłanego na serwer.

<html>
<head>
<title>Wysyłanie plików na serwer</title>
</head>

<body>
 <form action="p4.4.php" method="POST" enctype="multipart/form-data">
  <input type="file" name="userfile"><br>
  <input type="submit" value="Wyślij">
 </form>
<?
  if ( $_FILES['userfile'] )
  {
     echo '<blockquote>';

     echo 'Nazwa pliku: <b>' . $_FILES['userfile']['name'] . '</b><br>';
     echo 'Typ MIME: <b>' . $_FILES['userfile']['type'] . '</b><br>';
     echo 'Nazwa tymczasowa: <b>' . $_FILES['userfile']['tmp_name'] . '</b><br>';
     echo 'Rozmiar: <b>' . $_FILES['userfile']['size'] . '</b><br>';
     echo 'Błąd: <b>' . $_FILES['userfile']['error'] . '</b><br>';

     echo '</blockquote>';
  }
?>
</body>
</html>

Zawartość pliku przesyłana jest do serwera przy pomocy metody HTTP POST. Poniższy znacznik HTML umożliwia wyświetlenie pola edycyjnego zawierającego przycisk Przeglądaj, służący do wybrania pliku:

<input type="file" name="userfile">

Informacje o wysyłanym pliku zawarte będą w tablicy $_FILES['userfile'].

Tablica $_FILES['userfile'] zawiera zagnieżdżoną tablicę, która zawiera informacje o pliku. Znaczenie poszczególnych kluczy prezentuje tabela ponizej:

Znaczenie kluczy tablicy $_FILES['userfile']

$_FILES['userfile']['name']     // Oryginalna nazwa wysyłanego pliku
$_FILES['userfile']['type']     // Typ MIME wysyłanego pliku
$_FILES['userfile']['size']     // Rozmiar wysyłanego pliku (w bajtach)
$_FILES['userfile']['tmp_name'] // Tymczasowa nazwa pliku, który został wysłany na serwer
$_FILES['userfile']['error']    // Numer błędu (0 oznacza prawidłowe wysłanie)

Każdy dokument przetwarzany przez przeglądarkę (grafika, skrypty) posiada tzw. typ MIME (ang. Multipuropse Internet Mail Extensions) opisujący rodzaj dokumentu. Typ MIME przesyłany jest w nagłówku HTTP i może przybrać np. taką postać: text/html.

Wartość elementu $_FILES['userfile']['error'] może przybrać wartości takie jak w tabeli ponizej:

Stała Wartość liczbowa Opis
UPLOAD_ERR_OK 0 Żadnych błędów, wysyłanie powiodło się.
UPLOAD_ERR_INI_SIZE 1 Rozmiar pliku przekracza wartość z ustawienia upload_max_filesize z pliku php.ini.
UPLOAD_ERR_FORM_SIZE 2 Rozmiar pliku przekracza wartość określaną w formularzu HTML poprzez parametr MAX_FILE_SIZE.
UPLOAD_ERR_PARTIAL 3 Plik został przesłany jedynie w części.
UPLOAD_ERR_NO_FILE 4 Plik nie został wysłany.

W tabeli wspomniałem o parametrze MAX_FILE_SIZE. Parametr ten może zostać użyty w formularzu HTML do dodatkowego określenia maksymalnego rozmiaru pliku:

<input type="hidden" name="MAX_FILE_SIZE" value="5000">

Maksymalny rozmiar podawany jest w bajtach.

Pamiętaj o tym, że aby wysyłanie działało prawidłowo, w formularzu, w parametrze znacznika <form> należy określić typ danych:

enctype="multipart/form-data"

Tablica $_COOKIE

Tablica $_COOKIE służy do przechowywania tzw. ciastek (ang. cookies). Ciastko nagłówek wysyłany w tę i z powrotem pomiędzy klientem, a serwerem. Przeglądarka otrzymując żądanie od serwera z reguły zapamiętuje ciastko (jeżeli przeglądarka ma włączoną odpowiednią opcję) i wykonując kolejne żadanie, odsyła ciastko z powrotem, a my jesteśmy w stanie jakkolwiek rozróżnić klienta który wysyła do nas rządania, które (poza ciasteczkami) równie dobrze mogą być od od tego samego lub różnych użytkowników. Bez ciasteczek (i innych form weryfikacji), 1000 żądań z jednego klienta nie różni się niczym od pojedynczego żądania wysłanego przez 1000 użytkowników.

Funkcje związane z tablicami

PHP udostępnia dość pokaźny zbiór funkcji związanych z obsługą tablic. Dzięki tym funkcjom, możemy w prosty sposób posortować tablicę, operować na kluczach, wartościach, pozostawić tylko unikalne elementy, przeprowadzić transformację, zamienić ją na inne typy, łączyć ją z innymi tablicami, odejmować tablice od siebie, podzielić ją na mniejsze części oraz dokonywać wielu innych operacji. Przyjrzyjmy się pokrótce najważniejszym funkcjom służącym do operowania na tablicach.

is_array()

Dzięki funkcji is_array() możemy w prosty sposób upewnić się czy dana zmienna jest tablicą (w takim wypadku funkcja zwróci true).

<?
  $array = Array('a', 'b');

  if ( is_array($array) ) 
  { 
      echo 'Zmienna tablicowa!';
  } 
?>

Warto wspomnieć, iż istnieją podobne funkcje sprawdzające wartość danego typu, takie jak: is_int(), is_bool(), is_float(), is_string(), is_float().

array_chunk()

array array_chunk ( array wejście, int rozmiar [, bool zachowaj_klucze])

Funkcja array_chunk() umożliwia podział tablicy na kilka części, określonych w parametrze rozmiar. Ostatni, opcjonalny parametr zachowaj_klucze umożliwia zachowanie oryginalnych kluczy z tablicy wejściowej (w przypadku true). Spójrz na poniższy przykład:

<?
    $array = Array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j');

    print_r(array_chunk($array, 4, true));
    
    print_r(array_chunk($array, 4));
?>

Takie działanie spowoduje wyświetlenie następującej wartości:

Array
(
    [0] => Array
        (
            [0] => a
            [1] => b
            [2] => c
            [3] => d
        )

    [1] => Array
        (
            [4] => e
            [5] => f
            [6] => g
            [7] => h
        )

    [2] => Array
        (
            [8] => i
            [9] => j
        )

)
Array
(
    [0] => Array
        (
            [0] => a
            [1] => b
            [2] => c
            [3] => d
        )

    [1] => Array
        (
            [0] => e
            [1] => f
            [2] => g
            [3] => h
        )

    [2] => Array
        (
            [0] => i
            [1] => j
        )

)

array_diff()

array array_diff ( array tabela1, array tabela2 [, array ...])

Funkcja zwraca różnice pomiędzy tablicami podanymi w parametrach. Rezultatem działania tej funkcji jest tablica, która zawiera wartości tablicy tabela1, których brak w tabela2:

<?
    $a1 = Array('a', 'b', 'c', 'd');
    $a2 = Array('e', 'b', 'c', 'd');
    
    print_r(array_diff($a1, $a2)); // zwróci Array ( [0] => a )

array_filter()

array array_filter ( array wejście [, callback funkcja_zwrotna])

Funkcja filtruje elementy tablicy przy pomocy funkcji zwrotnej. Oznacza to, że program wykonuje iteracje dla każdego elementu z tablicy wejście i przekazuje go do funkcji określonej w parametrze funkcja_zwrotna. Oto przykład przefiltrowania parametrów i pozostawienie tylko liczb:

<?
    function Alfa($value)
    {
        return is_numeric($value);
    }
    
    $array = Array(1, 'test', 344, 455, 'PHP');
    print_r(array_filter($array, "Alfa"));
/* 
  Array ( [0] => 1 [2] => 344 [3] => 455 )
*/
?>

array_key_exists()

bool array_key_exists ( mixed igła, array stóg_siana)

Funkcja array_key_exists() umożliwia sprawdzenie, czy element o danym kluczu lub indeksie istnieje w tablicy:

<?
    $array = Array('a' => 'abc', 'b' => 'bcd');
    
    if ( array_key_exists('a', $array) )
    {
        echo 'Element istnieje w tablicy!';
    }

Pierwszym parametrem funkcji musi być nazwą klucza lub numerem indeksu; drugi parametr musi być nazwą tablicy.

array_keys()

array array_keys ( array wejście [, mixed szukana_wartość])

Czasem może zdarzyć się sytuacja, w której będziemy musieli pobrać nazwy kluczy z danej tablicy. W takim wypadku można użyć funkcji array_keys() która pobiera nazwy kluczy i zwraca jako rezultat działania funkcji:

<?
    $array = Array('a' => 'abc', 'b' => 'bcd');
    
    print_r(array_keys($array));
/* rezultat: Array ( [0] => a [1] => b ) */
?>

Drugi, opcjonalny parametr umożliwia zwrócenie tylko tych kluczy, których wartością jest szukana_wartość.

array_slice()

array array_slice ( array tablica, int przesunięcie [, int długość])

Do tej pory zajmowaliśmy się jedynie tworzeniem tablic,
przypisywaniem wartości do danych elementów. Funkcja array_slice() umożliwia wycinanie elementów z tablicy. Parametr długość oznacza ilość elementów do wycięcia, natomiast parametr przesunięcie oznacza numer elementu od którego funkcja rozpocznie wycinanie. Jeżeli dwa ostatnie parametry są ujemne, wycinanie elementów rozpocznie się od końca. Oto parę przykładów:

<?
    $array = Array('rower', 'skakanka', 'komputer', 'lalka', 'długopis');
    
    print_r(array_slice($array, 2));
    print_r(array_slice($array, 1, 2));
    print_r(array_slice($array, 0, 2));
    print_r(array_slice($array, -2));
    print_r(array_slice($array, 1, -1));
?>

Oto rezultat działania takiego programu:

Array
(
    [0] => komputer
    [1] => lalka
    [2] => długopis
)
Array
(
    [0] => skakanka
    [1] => komputer
)
Array
(
    [0] => rower
    [1] => skakanka
)
Array
(
    [0] => lalka
    [1] => długopis
)
Array
(
    [0] => skakanka
    [1] => komputer
    [2] => lalka
)

implode()

string implode ( string glue, array pieces)

Bardzo przydatna funkcja implode(), służy do złączania elementów tablicy w jeden ciąg (łańcuch). Pierwszy parametr ? glue, określa łańcuch, który zostanie wstawiony pomiędzy każdy element tablicy. Oto przykład:

<?
    $array = Array('cytryna', 'pomarańcz', 'jabłko', 'pomidor');
    
    echo implode(', ', $array);
?>

Rezultatem takiego działania będzie wyświetlenie następującego łańcucha w oknie przeglądarki: cytryna, pomarańcz, jabłko, pomidor.
Aliasem do funkcji implode() jest join() (obie wykonują dokładnie tę samą czynność) i ta nazwa jest równie często wykorzystywana ze względu na przyzwyczajenia programistów do Perla (w języku Perl funkcja join() realizowała takie samo zadanie, co funkcja implode() w PHP).

explode()

array explode ( string separator, string string [, int limit])

Funkcja explode() wykonuje czynność dokładnie odwrotną, co join(). Tworzy ona tablicę na podstawie łańcucha string. Pierwszy parametr musi określać separator na podstawie którego łańcuch zostanie rozdzielony:

<pre>
<?
    $string = 'cytryna, pomarańcz, jabłko, pomidor';
    
    print_r(explode(', ', $string));
?>
</pre>

Dzięki ostatniemu, opcjonalnemu parametrowi możesz określić ile elementów tablicy zostanie utworzonych poprzez rozdzielnie. Np. takie wywołanie funkcji:

print_r(explode(', ', $string, 2));

Spowoduje rozdzielenie łańcucha na dwa następujące elementy:

Array
(
    [0] => cytryna
    [1] => pomarańcz, jabłko, pomidor
)

PHP udostępnia jeszcze jedną, bardzo podobną funkcję o nazwie split(). Działa ona podobnie, ale nie jest identyczna, co explode(). Umożliwia ona rozdzielenie parametrów na podstawie wyrażenia regularnego..

Sortowanie

PHP jest na tyle wygodnym językiem, że ma wbudowane funkcje sortowania tablic. Normalnie konieczna by była implementacja algorytmów sortowania. Programując w PHP, sprawa jest bardzo ułatwiona ? mamy do dyspozycji wiele funkcji sortowania, które wykorzystują rozmaite algorytmy. Dzięki temu nie będzie problemu z posortowaniem nawet wymyślnej tablicy.

sort()

void sort ( array tablica [, int flagi])

Najprostszą funkcją sortującą elementy w tablicy jest sort(). Sortuje ona elementy, od najmniejszego do największego. Należy zaznaczyć, że funkcja ta nie zwraca rezultatu w postaci posortowanej już tablicy. Użycie jest następujące:

<pre>
<?
    $array = Array('rower', 'skakanka', 'komputer', 'lalka', 'długopis');
    sort($array);
    print_r($array);
?>
</pre>

Takie sortowanie spowoduje umiejscowienie elementów w następującej kolejności:

Array
(
    [0] => długopis
    [1] => komputer
    [2] => lalka
    [3] => rower
    [4] => skakanka
)

Funkcja sort() posiada drugi, opcjonalny parametr nakazujący porównanie elementów jako liczby (SORT_NUMERIC) lub łańcuchy (SORT_STRING).

arsort()

void arsort ( array tablica [, int flagi])

Kolejna z funkcji sortujących arsort(), służy do sortowania tablicy, ale w odwrotnej kolejności niż sort() (tj. od najwyższej do najmniejszej). Funkcja przydaje się przede wszystkim do sortowania tablic asocjacyjnych, gdyż zachowuje położenie kluczy:

<pre>
<?
    $array = Array('a' => 'rower', 'b' => 'skakanka', 'c' => 'komputer', 'd' => 'lalka', 'e' => 'długopis');
    arsort($array);
    print_r($array);
?>
</pre>

Oto rezultat:

Array
(
    [b] => skakanka
    [a] => rower
    [d] => lalka
    [c] => komputer
    [e] => długopis
)

Funkcja także, podobnie jak funkcja sort() posiada drugi, opcjonalny parametr mówiący o trybie sortowania elementów.

asort()

void asort ( array tablica [, int flagi])

Funkcja asort() jest bardzo podobna do arsort() również zachowuje skojarzenia kluczy, lecz sortuje w porządku od najmniejszego do największego elementu.

ksort

int ksort ( array tablica [, int flagi])

Do tej pory omawiałem funkcje sortowania związane z sortowaniem według wartości. Funkcja ksort() sortuje według klucza, w porządku od najmniejszego do największego elementu:

<?
    $array = Array('a' => 'rower', 'b' => 'skakanka', 'c' => 'komputer', 'd' => 'lalka', 'e' => 'długopis');
    ksort($array);
    print_r($array);
?>

Oto rezultat:

Array
(
    [a] => rower
    [b] => skakanka
    [c] => komputer
    [d] => lalka
    [e] => długopis
)

krsort()

int krsort ( array tablica [, int flagi])

Funkcja sortuje według klucza, lecz w porządku odwrotnym. Posługując się poprzednim przykładem, funkcja zwróci następujące rezultaty:

Array
(
    [e] => długopis
    [d] => lalka
    [c] => komputer
    [b] => skakanka
    [a] => rower
)

natsort()

void natsort ( array tablica)

Funkcja natsort() sortuje łańcuchy alfanumeryczne stanowi implementację algorytmu porządkowania naturalnego. Różnicę pomiędzy funkcją sort(), a natsort() można zauważyć na poniższym przykładzie:

<?
    $array = Array('rysunek1.gif', 'rysunek11.gif', 'rysunek2.gif', 'rysunek12.gif');
    
    sort($array);
    print_r($array);
    natsort($array);
    print_r($array);
?>

W tym przypadku tablica $array zostanie posortowana w dwojaki sposób:

Array
(
    [0] => rysunek1.gif
    [1] => rysunek11.gif
    [2] => rysunek12.gif
    [3] => rysunek2.gif
)
Array
(
    [0] => rysunek1.gif
    [3] => rysunek2.gif
    [1] => rysunek11.gif
    [2] => rysunek12.gif
)

W PHP możesz skorzystać także z funkcji natcasesort() która różni się od natsort() tym, iż ignoruje wielkość znaków.

usort()

void usort ( array tablica, callback funkcja_por)

Do realizowania bardziej skomplikowanych zadań związanych z sortowaniem, służy funkcja usort(). Aby z niej skorzystać należy zadeklarować własną funkcję, do której przekazywane są pod dwa elementy z tablicy (jest to tak zwana funkcja zwrotna). Rezultat zwrócony przez funkcję decyduje o przestawieniu elementów w tablicy. Jeżeli funkcja zwrotna zwróci 0, to oznacza, że dwa elementy są równe. Wartość mniejsza lub większa od zera oznacza, że element jest mniejszy lub większy od drugiego elementu.

Ponizszy listing prezentuje przykładowy program umożliwiający sortowanie liczb podanych przez użytkownika. W skrypcie istnieje dodatkowo możliwość wybrania trybu sortowania (od najmniejszego do największego lub od największego do najmniejszego).

<html>
<head>
<title>Sortowanie liczb</title>
</heead>

<body>
<?
    if ( $_POST['array'] )
    {
  /* utworzenie tablicy z łańcucha liczb oddzielonych spacją */
        $array = explode(' ', $_POST['array']);

        function compare($value1, $value2)
        {
            if ( $value1 === $value2 )
            {
                return 0;
            }
            else
            {
                return ( $value1 > $value2 ? $_POST['order'] : ( $_POST['order'] * -1 ) );
            }
        }

        usort($array, 'compare');

        echo 'Posortowana tablica:<br>';
        
        foreach ( $array as $value )
        {
            echo "$value<br>";
        }
    }
    else
    {
?>
<p>Sortuj elementy wpisane w formularzu:</p>
 <form action="p4.5.php" method="POST">
   <b>Liczby oddziel spacjami</b>:<br>
   <textarea name="array" rows="10" cols="40"></textarea>
   <br>Tryb sortowania: <select name="order"><option value="1">Rosnąco</option><option value="-1">Malejąco</option></select>
   <br><input type="Submit" value="Sortuj">
  </form>
<? } ?>
</body>
</html>

Oczywiście taki sam efekt da się osiągnąć stosując podstawowe, prostsze funkcje sortowania. Funkcja usort() służy do nieco bardziej skomplikowanego sortowania. W powyższym listingu użytkownik może podać liczby do posortowania, w kontrolce <textarea>. Liczby muszą być oddzielone spacją.

Tryb sortowania przekazywany jest w nagłówku HTTP POST, w kontrolce typu <select> o nazwie order. Jeżeli użytkownik wybierze tryb rosnący, wartością elementu $_POST['order'] będzie 1. W przeciwnym wypadku, element będzie posiadał wartość ?1. Na podstawie tej wartości, w funkcji compare() decydujemy o położeniu elementów.

PHP udostępnia jeszcze dwie funkcje, podobne do usort(). Są to funkcje o nazwach uasort() oraz uksort(). Pierwsza z nich, korzystając z funkcji zwrotnej sortuje tablicę asocjacyjną, zachowując przy tym skojarzenia kluczy. Druga z funkcji uksort(), korzystając z funkcji zwrotnej sortuje według nazw kluczy.

count()

int count ( mixed zmienna)

Funkcja count() jest używana do zliczania ilości elementów w tablicy. Funkcja przydaje się często w przypadkach gdy musimy dokonać iteracji na wszystkich elementach tablicy. Jeżeli zmienna podana w parametrze nie jest tablicą funkcja zwróci cyfrę 1. Jeżeli w parametrze podano zmienną, która nie została zainicjowana funkcja zwróci 0.
Aliasem do funkcji count() jest sizeof().

key()

mixed key ( array tablica)

Funkcja key() zwraca nazwę bieżącego klucza z tablicy podanej w parametrze:

<?
    $array[20] = 'Piotr';
    $array[30] = 'Grzesiek';
    
    echo key($array); // zwróci 20
?>

Funkcja jest przeważnie używana w połączeniu z tablicami asocjacyjnymi. W tym wypadku funkcja zwróci klucz, pierwszego elementu tablicy.

Tak na prawdę key() zwraca klucz, na który wskazuje wewnętrzny wskaźnik tablicy, którym można manipulować funkcjami prev(), reset() lub innymi.

<?
    $array['User'] = 'Użytkownik';
    $array['Profile'] = 'Profil';
    $array['Next'] = 'Następny';
    $array['Prev'] = 'Poprzedni';
    
    echo key($array). '<br>';  // zwróci User
    
    next($array);
    
    echo key($array) . '<br>'; // zwróci Profile
    
    end($array);
    
    echo key($array) . '<br>';  // zwróci Prev
    
    prev($array);
    
    echo key($array) . '<br>';  // zwróci Next
?>

Nie trudno domyśleć się znaczenia poszczególnych funkcji. Odpowiadają one za przesunięcie wewnętrznego wskaźnika tablicy na element następny (next()), poprzedni (prev()), końcowy (end()), pierwszy (reset()). Wszystkie z tych funkcji po zmianie położenia wskaźnika wewnętrznego zwracają obecną wartość elementu:

echo (  prev($array) ); // wyświetli 'Następny'

Jeżeli zmiana położenia wskaźnika nie powiedzie się (bo np. nie ma już więcej elementów w tablicy) ? funkcja zwróci false.

W każdej chwili możesz pobrać wartość aktualnego parametru tablicy, przy pomocy funkcji current().

Destrukcja tablicy

Spokojnie, słowo "destrukcja" może być drastycznie, ale nie chodzi o niszczenie tablicy, nie ma ku temu potrzeby - w słowie "destrukcja" chodzi o odwrotnośc struktury. odwrotna-struktura, de-strukcja.

Tworzenie tablic, odbywa się przez "wkładanie" zmiennych do tablicy. Destrukcja tablic to "wyciąganie" zmiennych z tablic.

$name = 'Jack';
$age = 5;
$male = true;

$array = [$name, $age, $male]; // tworzenie

a następnie:

[$imie, $wiek, $plec] = $array; // destrukcja

$imie; // 'Jack'
$wiek; // 5
$plec; // true

Wcześniej, przed PHP 7.0, zamiast [..] = $array, należało użyć słowa kluczowego list() do destrukcji (podobnie jak array() do tworzenia).

list($imie, $wiek, $plec) = array('Mark', 14, true); // Przed PHP 7.1
[$imie, $wiek, $plec] = ['Mark', 14, true]; // standardowy zapis

Destrukcji można również używać bezpośrednio w argumentach funkcji lub w foreach.

PHP

12 komentarzy

Zredagowałem artykuł, dodałem linki do dokumentacji PHP, poprawiłem formatowanie linków i tabel, dopisałem dodatkowe informacje, poprawiłem kilka niedociągnięć odnośnie języka, dodałem informacje nt. nowszych funkcji języka, i usunąłem odniesienia do PHP 4.

foreach ($parentArray as $array) {
    echo $array[0];
}

Chyba nie znalazłam odpowiedzi na moje pytanie w artykule. Jak odwołać się gdy array wygląda powiedzmy nastepujaco:

[0] => Array
        (
            [0] => 2017:05:05 13:48:17
            [1] => 87.239.222.197
        )

    [1] => Array
        (
            [0] => 2017:05:05 13:48:19
            [1] => 87.239.222.197
        )

W jaki sposób odwołać się tylko do elementów o indeksie [0] ze wszystkich elementów? Mam na myśli te wiersze z datą.

A ja też sie przyczepie do rozdziału "Instrukcje empty i isset"a dokładniej:

Instrukcja isset zwraca true jeżeli zmienna podana w parametrze istnieje. Nieważne jest, czy posiada wartość 0, '' czy false ? w takich przypadkach isset zwróci true.
Jeżeli dana wartośc w tablicy ma wartość null to niestety ale isset zwróci false, piszeo tym nawet w manualu, dlatego istnienie jakiegoś klucza sprawdzac należy korzystając z array_key_exists!

A kiedy chciałbym rozdzielić tablice, aby móc dane stopy VAT mieć osobno:

$a = array("VAT" => array(22,7,0,22,22,7,22,3), "NETTO" => array(10,10,100,120,1,20,10,20));

i szukam jak to zrobić, ale nie mogę tego nigdzie znaleźć - manuala przeleciałem php.net i nici :( Czyli chcialbym, zeby wyjsciowa tablica wygladala tak:

Array (0 => ARRAY(100)) (7 => ARRAY(10,20)) (22 => ARRAY(10,120,1,10)))

Jak to zrobic ? Ktos moze pomoc ??

lukasz_sz84 dnia 16-09-2006 00:55
ciekawy artykuł, ale mam pytanko jak w tablicach wielowymiarowych wyświetlić konkretne pole, np Polska. Próbuję echo $kraje['Europa[0]'] i nic. Jak sobie z tym poradzić??

Spróbuj echo $kraje['Europa'][0];

Pozdrawiam

Nie czytałem całego artykułu, ale wystarczyło, że zajrzałem i odrazu znalazłem rozwiązanie problemu :)

Nie wiedziałem, że o tablicach można tyle napisać.
Jak będę mieć czas to poczytam. Wygląda ciekawie.

ciekawy artykuł, ale mam pytanko jak w tablicach wielowymiarowych wyświetlić konkretne pole, np Polska. Próbuję echo $kraje['Europa[0]'] i nic. Jak sobie z tym poradzić??

Art bardzo dobry, uważam że duzo można się z niego dowiedzieć.

Osobiście znam tablice ale z punktu widzenia praktycznego, ale nie wiedziałem np. że tablica asocjacyjna to taka której kluczami są łańcuchy tekstowe (tzn. że tak ona się nazywa).

Praktykę znam ale teorii nie, także dzięki za art!

Dopisane:
Długi, ale JAKI PRZEJRZYSTY I CZYTELNY !!

no, całkiem ładnie, i ekstremalnie długo

brawo ja chcem więcej !! może wkońcu się przełamie i naucze się php :D