Skip to content

3. Podstawy PHP

3.1. Pierwszy przykład

Poniżej znajduje się program przedstawiający podstawowe funkcje PHP.

3.1.1. Program (exemple_01)


<?php

// to jest komentarz
// zmienna użyta bez zadeklarowania
$nom = "dupont";

// wyświetlanie na ekranie
print "nom=$nom\n";

// tablica zawierająca elementy różnych typów
$tableau = array("un", "deux", 3, 4);

// liczba elementów
$n = count($tableau);

// pętla
for ($i = 0; $i < $n; $i++)
  print "tableau[$i]=$tableau[$i]\n";

// inicjalizacja dwóch zmiennych zawartością tablicy
list($chaine1, $chaine2) = array("chaine1", "chaine2");

// konkatenacja dwóch ciągów znaków
$chaine3 = $chaine1 . $chaine2;

// wyświetlenie wyniku
print "[$chaine1,$chaine2,$chaine3]\n";

// użycie funkcji
affiche($chaine1);

// typ zmiennej może być znany
afficheType($n);
afficheType($chaine1);
afficheType($tableau);

// typ zmiennej może ulec zmianie w trakcie wykonywania
$n = "a changé";
afficheType($n);

// funkcja może zwracać wynik
$res1 = f1(4);
print "res1=$res1\n";

// funkcja może zwracać tablicę wartości
list($res1, $res2, $res3) = f2();
print "(res1,res2,res3)=[$res1,$res2,$res3]\n";

// wartości te można by było pobrać do tablicy
$t = f2();
for ($i = 0; $i < count($t); $i++)
  print "t[$i]=$t[$i]\n";

// testy
for ($i = 0; $i < count($t); $i++)
// wyświetla tylko kanały
  if (getType($t[$i]) == "string")
    print "t[$i]=$t[$i]\n";

// inne testy
for ($i = 0; $i < count($t); $i++){
// wyświetla tylko liczby całkowite większe niż 10
  if (getType($t[$i]) == "integer" and $t[$i] > 10)
    print "t[$i]=$t[$i]\n";
}

// pętla while
$t = array(8, 5, 0, -2, 3, 4);
$i = 0;
$somme = 0;
while ($i < count($t) and $t[$i] > 0) {
  print "t[$i]=$t[$i]\n";
  $somme+=$t[$i];   //$somme=$somme+$t[$i]
  $i++;             //$i=$i+1
}
print "somme=$somme\n";

// koniec programu
exit;

//----------------------------------
function affiche($chaine) {
  // wyświetla $chaine
  print "chaine=$chaine\n";
}

//----------------------------------
function afficheType($variable) {
  // wyświetla typ $variable
  print "type[$variable]=" . getType($variable) . "\n";
}

//----------------------------------
function f1($param) {
  // dodaje 10 do $param
  return $param + 10;
}

//----------------------------------
function f2() {
  // zwraca 3 wartości
  return array("un", 0, 100);
}
?>

Wyniki:

nom=dupont
tableau[0]=un
tableau[1]=deux
tableau[2]=3
tableau[3]=4
[chaine1,chaine2,chaine1chaine2]
chaine=chaine1
type[4]=integer
type[chaine1]=string
type[Array]=array
type[a changé]=string
res1=14
(res1,res2,res3)=[un,0,100]
t[0]=un
t[1]=0
t[2]=100
t[0]=un
t[2]=100
t[0]=8
t[1]=5
somme=13

Uwagi

  • wiersz 5: w PHP nie zadeklarowano typów zmiennych. Mają one typ dynamiczny, który może się zmieniać w czasie
  • $nom reprezentuje zmienną o identyfikatorze nom
  • wiersz 8: aby wyświetlić dane na ekranie, można użyć instrukcji print lub instrukcji echo
  • wiersz 11: słowo kluczowe array pozwala zdefiniować tablicę. Zmienna $nom[$i] reprezentuje element $i tablicy $tableau.
  • wiersz 14: funkcja count($tableau) zwraca liczbę elementów tablicy $tableau
  • wiersz 18: ciągi znaków są ujęte w cudzysłowy „ lub apostrofy '. Wewnątrz cudzysłowów zmienne $variable są obliczane, ale nie w apostrofach.
  • wiersz 21: funkcja list pozwala zebrać zmienne na liście i przypisać im wartość za pomocą jednej operacji przypisania. Tutaj $chaine1 = „ciąg1”, a $chaine2 = „ciąg2”.
  • wiersz 24: operator . służy do łączenia ciągów znaków.
  • wiersz 88: słowo kluczowe function definiuje funkcję. Funkcja zwraca lub nie zwraca wartości za pomocą instrukcji return. Kod wywołujący może zignorować lub pobrać wyniki funkcji. Funkcję można zdefiniować w dowolnym miejscu kodu.
  • wiersz 90: predefiniowana funkcja getType($variable) zwraca ciąg znaków reprezentujący typ $variable. Typ ten może ulegać zmianom w czasie.
  • wiersz 79: predefiniowana funkcja exit zatrzymuje skrypt.

3.2. Zakres zmiennych

3.2.1. Program 1 (exemple_02)


<?php

// zakres zmiennych

function f1() {
  // używa się zmiennej globalnej $i
  $i = &$GLOBALS["i"];
  $i++;
  $j = 10;
  print "f1[i,j]=[$i,$j]\n";
}

function f2() {
  // używana jest zmienna globalna $i
  $i = &$GLOBALS["i"];
  $i++;
  $j = 20;
  print "f2[i,j]=[$i,$j]\n";
}

function f3() {
  // używa się zmiennej lokalnej $i
  $i = 4;
  $j = 30;
  print "f3[i,j]=[$i,$j]\n";
}

// testy
$i = 0;
$j = 0;  // te dwie zmienne są znane funkcji f poprzez tablicę $GLOBALS
f1();
f2();
f3();
print "test[i,j]=[$i,$j]\n";
?>

Wyniki:

1
2
3
4
f1[i,j]=[1,10]
f2[i,j]=[2,20]
f3[i,j]=[4,30]
test[i,j]=[2,0]

Komentarze

  • wiersze 29–30: definiują dwie zmienne $i i $j w programie głównym. Zmienne te nie są rozpoznawane wewnątrz funkcji. Tak więc w wierszu 9 zmienna $j z funkcji f1 jest zmienną lokalną funkcji f1 i różni się od zmiennej $j z programu głównego. Funkcja może uzyskać dostęp do zmiennej $variable z programu głównego za pośrednictwem tablicy zmiennych globalnych o nazwie $GLOBALS. W wierszu 7 zapis $GLOBALS["i"] oznacza zmienną globalną $i programu głównego. Jeśli napiszemy
$i=$GLOBALS["i"]

Zmienna lokalna $i otrzymuje wartość zmiennej globalnej $i. Mamy tu do czynienia z dwiema różnymi zmiennymi, a zmiana wartości zmiennej lokalnej $i nie wpłynie na wartość zmiennej globalnej $i. Zapis

$i=&Globals["i"]

oznacza, że zmienna lokalna $i ma ten sam adres pamięci co zmienna globalna $i. Manipulowanie zmienną lokalną $i jest zatem równoznaczne z manipulowaniem zmienną globalną $i.

3.2.2. Program 2 (exemple_03)


<?php

// zakres zmiennej jest globalny dla bloków kodu
$i = 0; {
  $i = 4;
  $i++;
}
print "i=$i\n";
?>

Wyniki:

i=5

Komentarze

W niektórych językach zmienna zdefiniowana w nawiasach klamrowych ma zasięg ograniczony do tych nawiasów: nie jest znana poza nimi. Powyższe wyniki pokazują, że w języku PHP tak nie jest. Zmienna $i zdefiniowana w linii 5 wewnątrz nawiasów klamrowych jest tą samą zmienną, co ta użyta w liniach 4 i 8 poza nimi.

3.3. Tablice

3.3.1. Klasyczne tablice jednowymiarowe (exemple_04)


<?php

// klasyczne tablice
// inicjalizacja
$tab1 = array(0, 1, 2, 3, 4, 5);

// przeglądanie – 1
print "tab1 a " . count($tab1) . " éléments\n";
for ($i = 0; $i < count($tab1); $i++)
  print "tab1[$i]=$tab1[$i]\n";

// przeglądanie – 2
print "tab1 a " . count($tab1) . " éléments\n";
reset($tab1);
while (list($clé, $valeur) = each($tab1))
  print "tab1[$clé]=$valeur\n";

// dodawanie elementów
$tab1[] = $i++;
$tab1[] = $i++;

// przeglądanie – 3
print "tab1 a " . count($tab1) . " éléments\n";
$i = 0;
foreach ($tab1 as $élément) {
  print "tab1[$i]=$élément\n";
  $i++;
}

// usunięcie ostatniego elementu
array_pop($tab1);

// przeglądanie – 4
print "tab1 a " . count($tab1) . " éléments\n";
for ($i = 0; $i < count($tab1); $i++)
  print "tab1[$i]=$tab1[$i]\n";

// usunięcie pierwszego elementu
array_shift($tab1);

// przeglądanie – 5
print "tab1 a " . count($tab1) . " éléments\n";
for ($i = 0; $i < count($tab1); $i++)
  print "tab1[$i]=$tab1[$i]\n";

// dodanie na końcu tablicy
array_push($tab1, -2);

// przeglądanie – 6
print "tab1 a " . count($tab1) . " éléments\n";
for ($i = 0; $i < count($tab1); $i++)
  print "tab1[$i]=$tab1[$i]\n";

// dodanie na początku tablicy
array_unshift($tab1, -1);

// przeglądanie – 7
print "tab1 a " . count($tab1) . " éléments\n";
for ($i = 0; $i < count($tab1); $i++)
  print "tab1[$i]=$tab1[$i]\n";
?>

Wyniki:

tab1 a 6 éléments
tab1[0]=0
tab1[1]=1
tab1[2]=2
tab1[3]=3
tab1[4]=4
tab1[5]=5
tab1 a 6 éléments
tab1[0]=0
tab1[1]=1
tab1[2]=2
tab1[3]=3
tab1[4]=4
tab1[5]=5
tab1 a 8 éléments
tab1[0]=0
tab1[1]=1
tab1[2]=2
tab1[3]=3
tab1[4]=4
tab1[5]=5
tab1[6]=6
tab1[7]=7
tab1 a 7 éléments
tab1[0]=0
tab1[1]=1
tab1[2]=2
tab1[3]=3
tab1[4]=4
tab1[5]=5
tab1[6]=6
tab1 a 6 éléments
tab1[0]=1
tab1[1]=2
tab1[2]=3
tab1[3]=4
tab1[4]=5
tab1[5]=6
tab1 a 7 éléments
tab1[0]=1
tab1[1]=2
tab1[2]=3
tab1[3]=4
tab1[4]=5
tab1[5]=6
tab1[6]=-2
tab1 a 8 éléments
tab1[0]=-1
tab1[1]=1
tab1[2]=2
tab1[3]=3
tab1[4]=4
tab1[5]=5
tab1[6]=6
tab1[7]=-2

Komentarze

Powyższy program przedstawia operacje na tablicy wartości. W języku PHP istnieją dwa sposoby zapisu tablic:

$tableau=array("un",2,"trois")
$contraires=array("petit"=>"grand", "beau"=>"laid", "cher"=>"bon marché")

Tablica 1 nazywana jest tablicą, a tablica 2 – słownikiem, w którym elementy są zapisywane w postaci klucz => wartość. Notacja $contraires["beau"] oznacza wartość powiązaną z kluczem „piękny”. W tym przypadku jest to więc ciąg znaków „brzydki”. Tablica 1 jest jedynie odmianą słownika i mogłaby być zapisana w następujący sposób:

$tableau=array(0=>"un",1=>2,2=>"trois")

W ten sposób otrzymujemy $tableau[2] = „trois”. Ostatecznie mamy do czynienia wyłącznie ze słownikami. W przypadku klasycznej tablicy zawierającej n elementów klucze stanowią liczby całkowite z przedziału [0,n-1].

  • wiersz 15: funkcja each($tableau) pozwala na iterację po słowniku. Przy każdym wywołaniu zwraca parę (klucz, wartość) z tego słownika.
  • wiersz 14: funkcja reset($dictionnaire) ustawia funkcję each na pierwszą parę (klucz, wartość) w słowniku.
  • wiersz 15: pętla while zatrzymuje się, gdy funkcja each zwraca parę pustą na końcu słownika.
  • wiersz 19: zapis $tableau[]=wartość dodaje element valeur jako ostatni element tablicy $tableau.
  • wiersz 25: tablica jest przeglądana za pomocą foreach. Ten element składniowy umożliwia przeglądanie słownika, a więc tablicy, zgodnie z dwiema składniami:
foreach($dictionnaire as $clé=>$valeur)
foreach($tableau as $valeur)

Pierwsza składnia zwraca parę (clé,valeur) przy każdej iteracji, podczas gdy druga zwraca jedynie element valeur ze słownika.

  • wiersz 31: funkcja array_pop($tableau) usuwa ostatni element z $tableau
  • wiersz 39: funkcja array_shift($tableau) usuwa pierwszy element z $tableau
  • wiersz 47: funkcja array_push($tableau, wartość) dodaje valeur jako ostatni element do $tableau
  • wiersz 39: funkcja array_unshift($tableau, wartość) dodaje valeur jako pierwszy element do $tableau

3.3.2. Słownik (exemple_05)


<?php

// słowniki
$conjoints = array("Pierre" => "Gisèle", "Paul" => "Virginie", "Jacques" => "Lucette", "Jean" => "");

// przeglądanie – 1
print "Nombre d'éléments du dictionnaire : " . count($conjoints) . "\n";
reset($conjoints);
while (list($clé, $valeur) = each($conjoints))
  print "conjoints[$clé]=$valeur\n";

// sortowanie słownika według klucza
ksort($conjoints);

// przeglądanie – 2
reset($conjoints);
while (list($clé, $valeur) = each($conjoints))
  print "conjoints[$clé]=$valeur\n";

// lista kluczy słownika
$clés = array_keys($conjoints);
for ($i = 0; $i < count($clés); $i++)
  print "clés[$i]=$clés[$i]\n";

// lista wartości słownika
$valeurs = array_values($conjoints);
for ($i = 0; $i < count($valeurs); $i++)
  print "valeurs[$i]=$valeurs[$i]\n";

// wyszukiwanie klucza
existe($conjoints, "Jacques");
existe($conjoints, "Lucette");
existe($conjoints, "Jean");

// usunięcie pary klucz-wartość
unset($conjoints["Jean"]);
print "Nombre d'éléments du dictionnaire : " . count($conjoints) . "\n";
foreach ($conjoints as $clé => $valeur) {
  print "conjoints[$clé]=$valeur\n";
}

// koniec
exit;

function existe($conjoints, $mari) {
  // sprawdza, czy klucz $mari istnieje w słowniku $conjoints
  if (isset($conjoints[$mari]))
    print "La clé [$mari] existe associée à la valeur [$conjoints[$mari]]\n";
  else
    print "La clé [$mari] n'existe pas\n";
}

?>

Wyniki:

Nombre d'éléments du dictionnaire : 4
conjoints[Pierre]=Gisèle
conjoints[Paul]=Virginie
conjoints[Jacques]=Lucette
conjoints[Jean]=
conjoints[Jacques]=Lucette
conjoints[Jean]=
conjoints[Paul]=Virginie
conjoints[Pierre]=Gisèle
clés[0]=Jacques
clés[1]=Jean
clés[2]=Paul
clés[3]=Pierre
valeurs[0]=Lucette
valeurs[1]=
valeurs[2]=Virginie
valeurs[3]=Gisèle
La clé [Jacques] existe associée à la valeur [Lucette]
La clé [Lucette] n'existe pas
La clé [Jean] existe associée à la valeur []
Nombre d'éléments du dictionnaire : 3
conjoints[Jacques]=Lucette
conjoints[Paul]=Virginie
conjoints[Pierre]=Gisèle

Komentarze

Powyższy kod stosuje do słownika to, co omówiono wcześniej w przypadku zwykłej tablicy. Omówimy tylko nowe elementy:

  • wiersz 13: funkcja ksort (sortowanie według klucza) pozwala posortować słownik według naturalnej kolejności kluczy.
  • wiersz 21: funkcja array_keys($dictionnaire) zwraca listę kluczy słownika w postaci tablicy
  • wiersz 26: funkcja array_values($dictionnaire) zwraca listę wartości słownika w postaci tablicy
  • wiersz 47: funkcja isset($variable) zwraca wartość true, jeśli zmienna $variable została zdefiniowana, w przeciwnym razie zwraca wartość false.
  • wiersz 36: funkcja unset($variable) usuwa zmienną $variable.

3.3.3. Tablice wielowymiarowe (exemple_06)


<?php

// klasyczne tabele wielowymiarowe
// inicjalizacja
$multi = array(array(0, 1, 2), array(10, 11, 12, 13), array(20, 21, 22, 23, 24));
// przeglądanie
for ($i1 = 0; $i1 < count($multi); $i1++)
  for ($i2 = 0; $i2 < count($multi[$i1]); $i2++)
    print "multi[$i1][$i2]=" . $multi[$i1][$i2] . "\n";
// słowniki wielowymiarowe
// inicjalizacja
$multi = array("zéro" => array(0, 1, 2), "un" => array(10, 11, 12, 13), "deux" => array(20, 21, 22, 23, 24));
// przeglądanie
foreach ($multi as $clé => $valeur)
  for ($i2 = 0; $i2 < count($valeur); $i2++)
    print "multi[$clé][$i2]=" . $multi[$clé][$i2] . "\n";
?>

Wyniki:

multi[0][0]=0
multi[0][1]=1
multi[0][2]=2
multi[1][0]=10
multi[1][1]=11
multi[1][2]=12
multi[1][3]=13
multi[2][0]=20
multi[2][1]=21
multi[2][2]=22
multi[2][3]=23
multi[2][4]=24
multi[zéro][0]=0
multi[zéro][1]=1
multi[zéro][2]=2
multi[un][0]=10
multi[un][1]=11
multi[un][2]=12
multi[un][3]=13
multi[deux][0]=20
multi[deux][1]=21
multi[deux][2]=22
multi[deux][3]=23
multi[deux][4]=24

Uwagi

  • wiersz 5: elementy tablicy $multi są same w sobie tablicami
  • wiersz 12: tablica $multi staje się słownikiem (clé,valeur), w którym każda pozycja valeur jest tablicą

3.3.4. Powiązania między ciągami znaków a tablicami (exemple_07)


<?php

// przekształcanie ciągu znaków w tablicę
$chaine = "1:2:3:4";
$tab = explode(":", $chaine);

// przeglądanie tablicy
print "tab a " . count($tab) . " éléments\n";
for ($i = 0; $i < count($tab); $i++)
  print "tab[$i]=$tab[$i]\n";

// tablica do ciągu znaków
$chaine2 = implode(":", $tab);
print "chaine2=$chaine2\n";

// dodajmy puste pole
$chaine.=":";
print "chaîne=$chaine\n";
$tab = explode(":", $chaine);

// przeglądanie tablicy
print "tab a " . count($tab) . " éléments\n";
for ($i = 0; $i < count($tab); $i++)
  print "tab[$i]=$tab[$i]\n"; // mamy teraz 5 elementów, z których ostatni jest pusty
  
// dodajmy ponownie puste pole
$chaine.=":";
print "chaîne=$chaine\n";
$tab = explode(":", $chaine);

// przeglądanie tablicy
print "tab a " . count($tab) . " éléments\n";
for ($i = 0; $i < count($tab); $i++)
  print "tab[$i]=$tab[$i]\n"; // mamy teraz 6 elementów, z których dwa ostatnie są puste
?>

Wyniki:

tab a 4 éléments
tab[0]=1
tab[1]=2
tab[2]=3
tab[3]=4
chaine2=1:2:3:4
chaîne=1:2:3:4:
tab a 5 éléments
tab[0]=1
tab[1]=2
tab[2]=3
tab[3]=4
tab[4]=
chaîne=1:2:3:4::
tab a 6 éléments
tab[0]=1
tab[1]=2
tab[2]=3
tab[3]=4
tab[4]=
tab[5]=

Komentarze

  • wiersz 5: funkcja explode($séparateur,$chaine) pozwala pobrać pola z $chaine, oddzielone przez $séparateur. W ten sposób funkcja explode(":",$chaine) pozwala pobrać w postaci tablicy elementy z $chaine, które są oddzielone ciągiem znaków „:”.
  • Funkcja implode($séparateur, $tableau) wykonuje operację odwrotną do funkcji explode. Zwraca ciąg znaków utworzony z elementów $tableau oddzielonych przez $séparateur.

3.4. Ciągi znaków

3.4.1. Notacja (exemple_08)


<?php

// zapis ciągów znaków
$chaine1 = "un";
$chaine2 = 'un';
print "[$chaine1,$chaine2]\n";
?>

Wyniki:

[un,un]

3.4.2. Porównanie (exemple_09)


<?php

// testy porównywania ciągów znaków
compare("abcd", "abcd");
compare("", "");
compare("1", "");
exit;

function compare($chaine1, $chaine2) {
  // porównuje ciąg1 i ciąg2
  if ($chaine1 == $chaine2)
    print "[$chaine1] est égal à [$chaine2]\n";
  else
    print "[$chaine1] est différent de [$chaine2]\n";
}

?>

Wyniki:

1
2
3
[abcd] est égal à [abcd]
[] est égal à []
[1] est différent de []

3.5. Wyrażenia regularne (exemple_10)


<?php

// wyrażenia regularne w PHP
// pobieranie poszczególnych pól z ciągu znaków

// wzór: ciąg cyfr otoczony dowolnymi znakami
// chcemy pobrać tylko ciąg cyfr
$modèle = "/(\d+)/";
// porównujemy ciąg znaków z wzorcem
compare($modèle, "xyz1234abcd");
compare($modèle, "12 34");
compare($modèle, "abcd");

// wzór: ciąg cyfr otoczony dowolnymi znakami
// chcemy uzyskać ciąg cyfr wraz z polami poprzedzającymi i następującymi po nim
$modèle = "/^(.*?)(\d+)(.*?)$/";
// porównujemy ciąg znaków z wzorcem
compare($modèle, "xyz1234abcd");
compare($modèle, "12 34");
compare($modèle, "abcd");

// wzorzec – data w formacie dd/mm/rr
$modèle = "/^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$/";
compare($modèle, "10/05/97");
compare($modèle, "  04/04/01  ");
compare($modèle, "5/1/01");

// wzorzec – liczba dziesiętna
$modèle = "/^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*/";
compare($modèle, "187.8");
compare($modèle, "-0.6");
compare($modèle, "4");
compare($modèle, ".6");
compare($modèle, "4.");
compare($modèle, " + 4");

// koniec
exit;

// --------------------------------------------------------------------------
function compare($modèle, $chaîne) {
  // porównuje ciąg znaków $chaîne z wzorcem $modèle
  // porównuje się ciąg znaków z wzorcem
  $correspond = preg_match($modèle, $chaîne, $champs);
  // wyświetlanie wyników
  print "\nRésultats($modèle,$chaîne)\n";
  if ($correspond) {
    for ($i = 0; $i < count($champs); $i++)
      print "champs[$i]=$champs[$i]\n";
  } else
    print "La chaîne [$chaîne] ne correspond pas au modèle [$modèle]\n";
}
?>

Wyniki:

Résultats(/(\d+)/,xyz1234abcd)
champs[0]=1234
champs[1]=1234

Résultats(/(\d+)/,12 34)
champs[0]=12
champs[1]=12

Résultats(/(\d+)/,abcd)
La chaîne [abcd] ne correspond pas au modèle [/(\d+)/]

Résultats(/^(.*?)(\d+)(.*?)$/,xyz1234abcd)
champs[0]=xyz1234abcd
champs[1]=xyz
champs[2]=1234
champs[3]=abcd

Résultats(/^(.*?)(\d+)(.*?)$/,12 34)
champs[0]=12 34
champs[1]=
champs[2]=12
champs[3]= 34

Résultats(/^(.*?)(\d+)(.*?)$/,abcd)
La chaîne [abcd] ne correspond pas au modèle [/^(.*?)(\d+)(.*?)$/]

Résultats(/^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$/,10/05/97)
champs[0]=10/05/97
champs[1]=10
champs[2]=05
champs[3]=97

Résultats(/^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$/,  04/04/01  )
champs[0]=  04/04/01  
champs[1]=04
champs[2]=04
champs[3]=01

Résultats(/^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$/,5/1/01)
La chaîne [5/1/01] ne correspond pas au modèle [/^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$/]

Résultats(/^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*/,187.8)
champs[0]=187.8
champs[1]=
champs[2]=187.8

Résultats(/^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*/,-0.6)
champs[0]=-0.6
champs[1]=-
champs[2]=0.6

Résultats(/^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*/,4)
champs[0]=4
champs[1]=
champs[2]=4

Résultats(/^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*/,.6)
champs[0]=.6
champs[1]=
champs[2]=.6

Résultats(/^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*/,4.)
champs[0]=4.
champs[1]=
champs[2]=4.

Résultats(/^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*/, + 4)
champs[0]= + 4
champs[1]=+
champs[2]=4

Komentarze

  • wiersze 3–4: w tym miejscu wykorzystujemy wyrażenia regularne do wyodrębnienia różnych pól z ciągu znaków. Wyrażenia regularne pozwalają obejść ograniczenia funkcji implode. Zasadą działania jest porównanie ciągu znaków z innym ciągiem o nazwie modèle za pomocą funkcji preg_match:

$correspond = preg_match($modèle, $chaîne, $champs);

Funkcja preg_match zwraca wartość logiczną, jeśli ciąg modèle występuje w ciągu chaîne. Jeśli tak, to $champs[0] reprezentuje podciąg odpowiadający szablonowi. Ponadto, jeśli model zawiera podmodele w nawiasach, $champs[1] jest fragmentem $chaîne odpowiadającym pierwszemu podmodelowi, $champs[2] to fragment ciągu $chaîne odpowiadający drugiemu podwzorowi itd.

Rozważmy pierwszy przykład. Wzorzec jest zdefiniowany w wierszu 8: oznacza on ciąg jednej lub więcej (+) cyfr (\d) umieszczonych w dowolnym miejscu ciągu znaków. Ponadto wzorzec definiuje podwzorzec ujęty w nawiasy.

  • Wiersz 10: wzorzec /(\d+)/ (sekwencja jednej lub więcej cyfr w dowolnym miejscu ciągu) jest porównywany z ciągiem „xyz1234abcd”. Widzimy, że podciąg 1234 odpowiada wzorcowi. W związku z tym $champs[0] będzie równe „1234”. Ponadto wzorzec zawiera podwzorce w nawiasach. Otrzymamy więc, że $champs[1] = „1234”.
  • wiersz 11: wzorzec /(\d+)/ jest porównywany z ciągiem znaków „12 34”. Widać, że podciągi 12 i 34 pasują do wzorca. Porównanie kończy się przy pierwszym podciągu pasującym do wzorca. Otrzymamy zatem: $champs[0]=12 oraz $champs[1]=12.
  • wiersz 12: wzorzec /(\d+)/ jest porównywany z ciągiem „abcd”. Nie znaleziono żadnego dopasowania.

Wyjaśnijmy wzorce użyte w dalszej części kodu:


$modèle = "/^(.*?)(\d+)(.*?)$/";

początek ciągu (^), następnie 0 lub więcej (*) dowolnych znaków (.), następnie 1 lub więcej (+) cyfr, a następnie ponownie 0 lub więcej (*) dowolnych znaków (.). Wzorzec (.*) oznacza 0 lub więcej dowolnych znaków. Taki wzorzec będzie pasował do dowolnego ciągu znaków. W związku z tym wzorzec /^(.*)(\d+)(.*)$/ nigdy nie zostanie znaleziony, ponieważ pierwszy podwzorzec (.*) pochłonie cały ciąg znaków. Wzór (.*?)(\d+) oznacza natomiast 0 lub więcej dowolnych znaków aż do następnego podwzoru (?), w tym przypadku \d+. Zatem cyfry nie są już pochłaniane przez wzór (.*). Powyższy wzór odpowiada zatem ciągowi [début de chaîne (^), une suite de caractères quelconques (.*?), une suite d'un ou plusieurs chiffres (\d+), une suite de caractères quelconques (.*?), la fin de la chaîne ($)].


$modèle = "/^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$/";

odpowiada [début de chaîne (^), 2 chiffres (\d\d), le caractère / (\/), 2 chiffres, /, 2 chiffres, une suite de 0 ou plusieurs espaces (\s*), la fin de chaîne ($)]


$modèle = "/^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*/";

[début de chaîne (^), 0 ou plusieurs espaces (\s*), un signe + ou - [+|-] présent 0 ou 1 fois (?), une suite de 0 ou plusieurs espaces (\s*), 1 ou plusieurs chiffres suivis d'un point décimal suivi de zéro ou plusieurs chiffres (\d+\.\d*) ou (|) un point décimal (\.) suivi d'un ou plusieurs chiffres (\d+) ou (|) un ou plusieurs chiffres (\d+), une suite de 0 ou plusieurs espaces (\s*)].

3.6. Sposób przekazywania parametrów funkcji (exemple_11)


<?php

// sposób przekazywania parametrów

function f(&$i, $j) {
  // $i zostanie uzyskany przez odwołanie
  // $j zostanie uzyskany przez wartość
  $i++;
  $j++;
  print "f[i,j]=[$i,$j]\n";
}

// ----------------------------------------testy
$i = 0;
$j = 0;
// $i i $j przekazane jako wartości
f($i, $j);
print "test[i,j]=[$i,$j]\n";
?>

Wyniki:

f[i,j]=[1,1]
test[i,j]=[1,0]

Komentarze

Powyższy kod przedstawia dwa sposoby przekazywania parametrów do funkcji. Rozważmy następujący przykład:

1
2
3
4
5
6
7
function f(&$a,$b){

}

// program główny
$i=10; $j=20;
f($i,$j);
  • wiersz 1: definiuje parametry formalne $a i $b funkcji f. Funkcja ta przetwarza te dwa parametry formalne i zwraca wynik.
  • wiersz 7: wywołanie funkcji f z dwoma parametrami rzeczywistymi $i i $j. Powiązania między parametrami formalnymi ($a, $b) a parametrami rzeczywistymi ($i, $j) są zdefiniowane w wierszu 7
  • &$a: znak & oznacza, że parametr formalny $a przyjmie jako wartość adres parametru rzeczywistego $i. Innymi słowy, $a i $i to dwa odwołania do tej samej lokalizacji w pamięci. Manipulowanie parametrem formalnym $a jest równoznaczne z manipulowaniem parametrem rzeczywistym $i. Pokazuje to wykonanie kodu. Ten sposób przekazywania nadaje się do parametrów wyjściowych oraz dużych zbiorów danych, takich jak tablice i słowniki. Ten sposób przekazywania nazywa się przekazywaniem przez odwołanie.
  • $b: parametr formalny $b przyjmie wartość parametru rzeczywistego $j. Jest to przekazywanie przez wartość. Parametry formalne i rzeczywiste to dwie różne zmienne. Manipulowanie parametrem formalnym $b nie ma żadnego wpływu na parametr rzeczywisty $j. Pokazuje to wykonanie kodu. Ten tryb przekazywania nadaje się do parametrów wejściowych.
  • Weźmy na przykład funkcję échange, która przyjmuje dwa parametry formalne: $a i $b. Funkcja ta zamienia wartości tych dwóch parametrów. Zatem podczas wywołania typu „zamiana” ($i,$j) kod wywołujący oczekuje, że wartości obu parametrów rzeczywistych zostaną zamienione. Są to zatem parametry wyjściowe (ulegają one modyfikacji). Napiszemy zatem:
function échange(&$a,&$b){....}

3.7. Wyniki zwracane przez funkcję (exemple_12)


<?php

// wyniki zwracane przez funkcję
// funkcja może zwracać wiele wartości w tablicy
list($res1, $res2, $res3) = f1(10);
print "[$res1,$res2,$res3]\n";
$res = f1(10);
for ($i = 0; $i < count($res); $i++)
  print "res[$i]=$res[$i]\n";

// funkcja może zwracać pseudoobiekt
$res = f2(10);
print "[$res->res1,$res->res2,$res->res3]\n";

// koniec
exit;

// funkcja f1
function f1($valeur) {
  // zwraca tablicę ($valeur+1,$aleur+2,$baleur+3)
  return array($valeur + 1, $valeur + 2, $valeur + 3);
}

// funkcja f2
function f2($valeur) {
  // zwraca pseudoobiekt ($valeur+1,$aleur+2,$baleur+3)
  $res->res1 = $valeur + 1;
  ;
  $res->res2 = $valeur + 2;
  $res->res3 = $valeur + 3;
  // zwraca obiekt
  return $res;
}

?>

Wyniki

1
2
3
4
5
[11,12,13]
res[0]=11
res[1]=12
res[2]=13
[11,12,13]

Komentarze

  • Poprzedni program pokazuje, że funkcja PHP może zwracać zbiór wyników, a nie tylko jeden, w postaci tablicy lub obiektu. Pojęcie obiektu zostanie wyjaśnione nieco dalej
  • wiersze 19–22: funkcja f1 zwraca wiele wartości w postaci tablicy
  • wiersze 25–33: funkcja f2 zwraca wiele wartości w postaci obiektu

3.8. Pliki tekstowe (exemple_13)


<?php

// sekwencyjne przetwarzanie pliku tekstowego
// plik ten stanowi zbiór wierszy o postaci login:pwd:uid:gid:infos:dir:shell
// każdy wiersz jest umieszczany w słowniku w postaci login => uid:gid:infos:dir:shell

// ustalamy nazwę pliku
$INFOS = "infos.txt";

// otwieramy go w trybie tworzenia
if (!$fic = fopen($INFOS, "w")) {
  print "Erreur d'ouverture du fichier $INFOS en écriture\n";
  exit;
}

// generuje się dowolną treść
for ($i = 0; $i < 100; $i++)
  fputs($fic, "login$i:pwd$i:uid$i:gid$i:infos$i:dir$i:shell$i\n");
// zamykamy plik
fclose($fic);

// wykorzystujemy to – funkcja fgets zachowuje znacznik końca linii
// dzięki temu podczas odczytu pustej linii nie pobierany jest pusty ciąg znaków
// otwiera się go w trybie tworzenia
if (!$fic = fopen($INFOS, "r")) {
  print "Erreur d'ouverture du fichier $INFOS en lecture\n";
  exit;
}
while ($ligne = fgets($fic, 1000)) {
  // usuwa się znak końca linii, jeśli istnieje
  $ligne = cutNewLineChar($ligne);
  // umieszczamy wiersz w tablicy
  $infos = explode(":", $ligne);
  // pobieramy login
  $login = array_shift($infos);
  // pomija się hasło
  array_shift($infos);
  // tworzy się wpis w słowniku
  $dico[$login] = $infos;
}
// zamykamy go
fclose($fic);

// wykorzystanie słownika
afficheInfos($dico, "login10");
afficheInfos($dico, "X");

// koniec
exit;

// --------------------------------------------------------------------------
function afficheInfos($dico, $clé) {
  // wyświetla wartość powiązaną z kluczem w słowniku $dico, jeśli istnieje
  if (isset($dico[$clé])) {
    // wartość istnieje – czy jest to tablica?
    $valeur = $dico[$clé];
    if (is_array($valeur)) {
      print "[$clé," . join(":", $valeur) . "]\n";
    } else {
      // $valeur nie jest tablicą
      print "[$clé,$valeur]\n";
    }
  } else {
    // $clé nie jest kluczem słownika $dico
    print "la clé [$clé] n'existe pas\n";
  }
}

// --------------------------------------------------------------------------
function cutNewLinechar($ligne) {
  // usuwamy znacznik końca linii z $ligne, jeśli istnieje
  $L = strlen($ligne);  // długość wiersza
  while (substr($ligne, $L - 1, 1) == "\n" or substr($ligne, $L - 1, 1) == "\r") {
    $ligne = substr($ligne, 0, $L - 1);
    $L--;
  }
  // koniec
  return($ligne);
}

?>

Plik infos.txt:

login0:pwd0:uid0:gid0:infos0:dir0:shell0
login1:pwd1:uid1:gid1:infos1:dir1:shell1
login2:pwd2:uid2:gid2:infos2:dir2:shell2
...
login98:pwd98:uid98:gid98:infos98:dir98:shell98
login99:pwd99:uid99:gid99:infos99:dir99:shell99

Wyniki:

[login10,uid10:gid10:infos10:dir10:shell10]
la clé [X] n'existe pas

Komentarze

  • wiersz 11: fopen(nom_fichier, „w”) otwiera plik nom_fichier w trybie zapisu (w=write). Jeśli plik nie istnieje, zostanie utworzony. Jeśli istnieje, zostanie wyczyszczony. Jeśli utworzenie pliku nie powiedzie się, fopen zwraca wartość false. W instrukcji if (!$fic = fopen($INFOS, "w")) {…} występują dwie kolejne operacje: 1) $fic = fopen(..) 2) if( ! $fic) {...}
  • wiersz 18: fputs($fic, $chaîne) zapisuje chaîne do pliku $fic.
  • wiersz 20: fclose($fic) zamyka plik $fic.
  • wiersz 25: fopen(nom_fichier, „r”) otwiera plik nom_fichier w trybie odczytu (r=read). Jeśli otwarcie się nie powiedzie (plik nie istnieje), fopen zwraca wartość false.
  • wiersz 29: fgets($fic,1000) odczytuje następny wiersz z pliku, ograniczając długość do 1000 znaków. W pętli while ($ligne = fgets($fic, 1000)) {…} występują dwie kolejne operacje: 1) $ligne = fgets(...) 2) while ( ! $ligne). Po odczytaniu ostatniego znaku z pliku funkcja fgets zwraca pusty ciąg znaków, a pętla while zostaje zatrzymana.
  • wiersz 31: funkcja fgets odczytuje wiersz tekstu wraz ze znakiem końca wiersza. Funkcja cutNewLineChar w wierszach 70–79 usuwa ewentualny znak końca wiersza.
  • wiersz 72: funkcja strlen($chaîne) zwraca liczbę znaków w $chaîne.
  • wiersz 73: funkcja substr($ligne, $position, $taille) zwraca $taille znaków z ciągu $ligne, począwszy od znaku o numerze $position, przy czym pierwszy znak ma numer 0. Na komputerach z systemem Windows znakiem końca linii jest „\r\n”. Na komputerach z systemem Unix jest to ciąg znaków „\n”.
  • wiersz 35: funkcja array_shift($tableau) usuwa pierwszy element z $tableau i zwraca go jako wynik.
  • wiersz 37: wykorzystywana jest funkcja array_shift($tableau), ale jej wynik jest pomijany
  • wiersz 57: funkcja is_array($variable) zwraca true, jeśli $variable jest tablicą, w przeciwnym razie zwraca false.
  • wiersz 58: funkcja join działa tak samo jak funkcja implode, którą już poznaliśmy