Skip to content

3. Основи роботи з PHP

3.1. Перший приклад

Нижче наведено програму, що демонструє основні можливості PHP.

3.1.1. Програма (exemple_01)


<?php

// це коментар
// змінна, що використовується без оголошення
$nom = "dupont";

// виведення на екран
print "nom=$nom\n";

// масив з елементами різних типів
$tableau = array("un", "deux", 3, 4);

// кількість елементів
$n = count($tableau);

// цикл
for ($i = 0; $i < $n; $i++)
  print "tableau[$i]=$tableau[$i]\n";

// ініціалізація 2 змінних вмістом масиву
list($chaine1, $chaine2) = array("chaine1", "chaine2");

// об'єднання двох рядків
$chaine3 = $chaine1 . $chaine2;

// виведення результату
print "[$chaine1,$chaine2,$chaine3]\n";

// використання функції
affiche($chaine1);

// тип змінної може бути відомим
afficheType($n);
afficheType($chaine1);
afficheType($tableau);

// тип змінної може змінюватися під час виконання
$n = "a changé";
afficheType($n);

// функція може повертати результат
$res1 = f1(4);
print "res1=$res1\n";

// функція може повертати масив значень
list($res1, $res2, $res3) = f2();
print "(res1,res2,res3)=[$res1,$res2,$res3]\n";

// ці значення можна було б зберегти в масиві
$t = f2();
for ($i = 0; $i < count($t); $i++)
  print "t[$i]=$t[$i]\n";

// тести
for ($i = 0; $i < count($t); $i++)
// відображає лише канали
  if (getType($t[$i]) == "string")
    print "t[$i]=$t[$i]\n";

// інші тести
for ($i = 0; $i < count($t); $i++){
// виводить лише цілі числа >10
  if (getType($t[$i]) == "integer" and $t[$i] > 10)
    print "t[$i]=$t[$i]\n";
}

// цикл 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";

// кінець програми
exit;

//----------------------------------
function affiche($chaine) {
  // виводить $chaine
  print "chaine=$chaine\n";
}

//----------------------------------
function afficheType($variable) {
  // відображає тип $variable
  print "type[$variable]=" . getType($variable) . "\n";
}

//----------------------------------
function f1($param) {
  // додає 10 до $param
  return $param + 10;
}

//----------------------------------
function f2() {
  // повертає 3 значення
  return array("un", 0, 100);
}
?>

Результати:

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

Коментарі

  • рядок 5: у PHP тип змінних не оголошується. Вони мають динамічний тип, який може змінюватися з часом
  • $nom представляє змінну з ідентифікатором nom
  • рядок 8: для виведення на екран можна використовувати інструкцію print або інструкцію echo
  • рядок 11: ключове слово array дозволяє визначити масив. Змінна $nom[$i] представляє елемент $i масиву $tableau.
  • рядок 14: функція count($tableau) повертає кількість елементів масиву $tableau
  • рядок 18: символьні рядки беруться в лапки " або апострофи '. Усередині лапок змінні $variable обчислюються, а всередині апострофів — ні.
  • рядок 21: функція list дозволяє об’єднати змінні в список і присвоїти їм значення за допомогою однієї операції присвоєння. Тут $chaine1="рядок1" і $chaine2="рядок2".
  • рядок 24: оператор . — це оператор конкатенації рядків.
  • рядок 88: ключове слово function визначає функцію. Функція може повертати або не повертати значення за допомогою оператора return. Код, що викликає функцію, може ігнорувати або отримувати результати функції. Функцію можна визначити в будь-якому місці коду.
  • рядок 90: попередньо визначена функція getType($variable) повертає рядок символів, що представляє тип $variable. Цей тип може змінюватися з часом.
  • рядок 79: попередньо визначена функція exit зупиняє виконання скрипта.

3.2. Область дії змінних

3.2.1. Програма 1 (exemple_02)


<?php

// область дії змінних

function f1() {
  // використовується глобальна змінна $i
  $i = &$GLOBALS["i"];
  $i++;
  $j = 10;
  print "f1[i,j]=[$i,$j]\n";
}

function f2() {
  // використовується глобальна змінна $i
  $i = &$GLOBALS["i"];
  $i++;
  $j = 20;
  print "f2[i,j]=[$i,$j]\n";
}

function f3() {
  // використовується локальна змінна $i
  $i = 4;
  $j = 30;
  print "f3[i,j]=[$i,$j]\n";
}

// тести
$i = 0;
$j = 0;  // ці дві змінні відомі функції f через масив $GLOBALS
f1();
f2();
f3();
print "test[i,j]=[$i,$j]\n";
?>

Результати:

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

Коментарі

  • рядки 29–30: визначають 2 змінні $i та $j головної програми. Ці змінні не визнані всередині функцій. Так, у рядку 9 змінна $j функції f1 є локальною змінною функції f1 і відрізняється від змінної $j головної програми. Функція може отримати доступ до змінної $variable головної програми через масив глобальних змінних під назвою $GLOBALS. У рядку 7 запис $GLOBALS["i"] позначає глобальну змінну $i головної програми. Якщо ми напишемо
$i=$GLOBALS["i"]

локальній змінній $i присвоюється значення глобальної змінної $i. Тут маємо дві різні змінні, і зміна значення локальної змінної $i не вплине на значення глобальної змінної $i. Запис

$i=&Globals["i"]

означає, що локальна змінна $i має ту саму адресу в пам’яті, що й глобальна змінна $i. Отже, маніпулювання локальною змінною $i рівнозначне маніпулюванню глобальною змінною $i.

3.2.2. Програма 2 (exemple_03)


<?php

// область дії змінної є глобальною для блоків коду
$i = 0; {
  $i = 4;
  $i++;
}
print "i=$i\n";
?>

Результати:

i=5

Коментарі

У деяких мовах змінна, визначена в фігурних дужках, має область дії, обмежену цими дужками: вона не є відомою поза ними. Наведені вище результати показують, що в PHP це не так. Змінна $i, визначена в рядку 5 всередині фігурних дужок, є тією самою, що й та, яка використовується в рядках 4 та 8 поза ними.

3.3. Масиви

3.3.1. Класичні одновимірні масиви (exemple_04)


<?php

// класичні масиви
// ініціалізація
$tab1 = array(0, 1, 2, 3, 4, 5);

// обхід — 1
print "tab1 a " . count($tab1) . " éléments\n";
for ($i = 0; $i < count($tab1); $i++)
  print "tab1[$i]=$tab1[$i]\n";

// обхід — 2
print "tab1 a " . count($tab1) . " éléments\n";
reset($tab1);
while (list($clé, $valeur) = each($tab1))
  print "tab1[$clé]=$valeur\n";

// додавання елементів
$tab1[] = $i++;
$tab1[] = $i++;

// перегляд — 3
print "tab1 a " . count($tab1) . " éléments\n";
$i = 0;
foreach ($tab1 as $élément) {
  print "tab1[$i]=$élément\n";
  $i++;
}

// видалення останнього елемента
array_pop($tab1);

// перегляд — 4
print "tab1 a " . count($tab1) . " éléments\n";
for ($i = 0; $i < count($tab1); $i++)
  print "tab1[$i]=$tab1[$i]\n";

// видалення першого елемента
array_shift($tab1);

// проходження — 5
print "tab1 a " . count($tab1) . " éléments\n";
for ($i = 0; $i < count($tab1); $i++)
  print "tab1[$i]=$tab1[$i]\n";

// додавання в кінець масиву
array_push($tab1, -2);

// проходження — 6
print "tab1 a " . count($tab1) . " éléments\n";
for ($i = 0; $i < count($tab1); $i++)
  print "tab1[$i]=$tab1[$i]\n";

// додавання на початок масиву
array_unshift($tab1, -1);

// перегляд — 7
print "tab1 a " . count($tab1) . " éléments\n";
for ($i = 0; $i < count($tab1); $i++)
  print "tab1[$i]=$tab1[$i]\n";
?>

Результати:

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

Коментарі

Наведена вище програма демонструє операції з масивом значень. У PHP існують дві нотації для масивів:

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

Масив 1 називається масивом, а масив 2 — словником, де елементи позначаються у форматі «ключ => значення». Запис $contraires["beau"] позначає значення, пов’язане з ключем «красивий». У даному випадку це рядок «потворний». Масив 1 є лише варіантом словника і може бути записаний так:

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

Таким чином, маємо $tableau[2] = «trois». Зрештою, існують лише словники. У випадку класичного масиву, що містить n елементів, ключами є цілі числа з інтервалу [0,n-1].

  • рядок 15: функція each($tableau) дозволяє обходити словник. При кожному виклику вона повертає пару (ключ, значення) з нього.
  • рядок 14: функція reset($dictionnaire) встановлює функцію each на першу пару (ключ, значення) словника.
  • рядок 15: цикл while зупиняється, коли функція each повертає порожню пару в кінці словника.
  • рядок 19: запис $tableau[]=значення додає елемент valeur як останній елемент масиву $tableau.
  • рядок 25: масив обходиться за допомогою foreach. Цей синтаксичний елемент дозволяє обходити словник, а отже й масив, за двома синтаксичними схемами:
foreach($dictionnaire as $clé=>$valeur)
foreach($tableau as $valeur)

Перший синтаксис повертає пару (clé,valeur) при кожній ітерації, тоді як другий синтаксис повертає лише елемент valeur зі словника.

  • рядок 31: функція array_pop($tableau) видаляє останній елемент з $tableau
  • рядок 39: функція array_shift($tableau) видаляє перший елемент із $tableau
  • рядок 47: функція array_push($tableau, значення) додає valeur як останній елемент $tableau
  • рядок 39: функція array_unshift($tableau, значення) додає valeur як перший елемент $tableau

3.3.2. Словник (exemple_05)


<?php

// словники
$conjoints = array("Pierre" => "Gisèle", "Paul" => "Virginie", "Jacques" => "Lucette", "Jean" => "");

// пробіг — 1
print "Nombre d'éléments du dictionnaire : " . count($conjoints) . "\n";
reset($conjoints);
while (list($clé, $valeur) = each($conjoints))
  print "conjoints[$clé]=$valeur\n";

// сортування словника за ключем
ksort($conjoints);

// пробіг — 2
reset($conjoints);
while (list($clé, $valeur) = each($conjoints))
  print "conjoints[$clé]=$valeur\n";

// список ключів словника
$clés = array_keys($conjoints);
for ($i = 0; $i < count($clés); $i++)
  print "clés[$i]=$clés[$i]\n";

// список значень словника
$valeurs = array_values($conjoints);
for ($i = 0; $i < count($valeurs); $i++)
  print "valeurs[$i]=$valeurs[$i]\n";

// пошук ключа
existe($conjoints, "Jacques");
existe($conjoints, "Lucette");
existe($conjoints, "Jean");

// видалення пари «ключ-значення»
unset($conjoints["Jean"]);
print "Nombre d'éléments du dictionnaire : " . count($conjoints) . "\n";
foreach ($conjoints as $clé => $valeur) {
  print "conjoints[$clé]=$valeur\n";
}

// кінець
exit;

function existe($conjoints, $mari) {
  // перевіряє, чи існує ключ $mari у словнику $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";
}

?>

Результати:

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

Коментарі

Попередній код застосовує до словника те, що ми розглядали раніше для простого масиву. Ми коментуємо лише нові моменти:

  • рядок 13: функція ksort (key sort) дозволяє впорядкувати словник за природним порядком ключів.
  • рядок 21: функція array_keys($dictionnaire) повертає список ключів словника у вигляді масиву
  • рядок 26: функція array_values($dictionnaire) повертає список значень словника у вигляді масиву
  • рядок 47: функція isset($variable) повертає true, якщо змінна $variable була визначена, і false в іншому випадку.
  • рядок 36: функція unset($variable) видаляє змінну $variable.

3.3.3. Багатовимірні масиви (exemple_06)


<?php

// класичні багатовимірні масиви
// ініціалізація
$multi = array(array(0, 1, 2), array(10, 11, 12, 13), array(20, 21, 22, 23, 24));
// обхід
for ($i1 = 0; $i1 < count($multi); $i1++)
  for ($i2 = 0; $i2 < count($multi[$i1]); $i2++)
    print "multi[$i1][$i2]=" . $multi[$i1][$i2] . "\n";
// багатовимірні словники
// ініціалізація
$multi = array("zéro" => array(0, 1, 2), "un" => array(10, 11, 12, 13), "deux" => array(20, 21, 22, 23, 24));
// обхід
foreach ($multi as $clé => $valeur)
  for ($i2 = 0; $i2 < count($valeur); $i2++)
    print "multi[$clé][$i2]=" . $multi[$clé][$i2] . "\n";
?>

Результати:

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

Коментарі

  • рядок 5: елементи масиву $multi самі є масивами
  • рядок 12: масив $multi перетворюється на словник (clé,valeur), де кожен valeur є масивом

3.3.4. Зв’язки між рядками та масивами (exemple_07)


<?php

// перетворення рядка в масив
$chaine = "1:2:3:4";
$tab = explode(":", $chaine);

// обхід масиву
print "tab a " . count($tab) . " éléments\n";
for ($i = 0; $i < count($tab); $i++)
  print "tab[$i]=$tab[$i]\n";

// масив у рядок
$chaine2 = implode(":", $tab);
print "chaine2=$chaine2\n";

// додамо порожнє поле
$chaine.=":";
print "chaîne=$chaine\n";
$tab = explode(":", $chaine);

// обхід масиву
print "tab a " . count($tab) . " éléments\n";
for ($i = 0; $i < count($tab); $i++)
  print "tab[$i]=$tab[$i]\n"; // тепер у нас є 5 елементів, останній з яких порожній
  
// додамо ще одне порожнє поле
$chaine.=":";
print "chaîne=$chaine\n";
$tab = explode(":", $chaine);

// пробігаємо масив
print "tab a " . count($tab) . " éléments\n";
for ($i = 0; $i < count($tab); $i++)
  print "tab[$i]=$tab[$i]\n"; // тепер маємо 6 елементів, останні два з яких порожні
?>

Результати:

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]=

Коментарі

  • рядок 5: функція explode($séparateur,$chaine) дозволяє витягти поля з $chaine, розділені $séparateur. Так, функція explode(":",$chaine) дозволяє отримати у вигляді масиву елементи $chaine, розділені символом ":".
  • Функція implode($séparateur, $tableau) виконує операцію, протилежну до функції explode. Вона повертає рядок, утворений елементами $tableau, розділеними $séparateur.

3.4. Символьні рядки

3.4.1. Запис (exemple_08)


<?php

// позначення рядків
$chaine1 = "un";
$chaine2 = 'un';
print "[$chaine1,$chaine2]\n";
?>

Результати:

[un,un]

3.4.2. Порівняння (exemple_09)


<?php

// тести на порівняння рядків
compare("abcd", "abcd");
compare("", "");
compare("1", "");
exit;

function compare($chaine1, $chaine2) {
  // порівняння рядка1 та рядка2
  if ($chaine1 == $chaine2)
    print "[$chaine1] est égal à [$chaine2]\n";
  else
    print "[$chaine1] est différent de [$chaine2]\n";
}

?>

Результати:

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

3.5. Регулярні вирази (exemple_10)


<?php

// регулярні вирази в PHP
// витяг різних полів із рядка

// шаблон: послідовність цифр, оточена довільними символами
// потрібно витягти лише послідовність цифр
$modèle = "/(\d+)/";
// порівнюємо рядок із шаблоном
compare($modèle, "xyz1234abcd");
compare($modèle, "12 34");
compare($modèle, "abcd");

// шаблон: послідовність цифр, оточена довільними символами
// потрібна послідовність цифр, а також поля, що йдуть перед нею та після неї
$modèle = "/^(.*?)(\d+)(.*?)$/";
// порівнюємо рядок із шаблоном
compare($modèle, "xyz1234abcd");
compare($modèle, "12 34");
compare($modèle, "abcd");

// шаблон — дата у форматі дд/мм/рр
$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");

// шаблон — десяткове число
$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");

// кінець
exit;

// --------------------------------------------------------------------------
function compare($modèle, $chaîne) {
  // порівнює рядок $chaîne із шаблоном $modèle
  // рядок порівнюється з шаблоном
  $correspond = preg_match($modèle, $chaîne, $champs);
  // виведення результатів
  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";
}
?>

Результати:

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

Коментарі

  • рядки 3–4: тут ми використовуємо регулярні вирази для вилучення різних полів із символьного рядка. Регулярні вирази дозволяють обійти обмеження функції implode. Принцип полягає в порівнянні одного рядка символів з іншим рядком, який називається modèle, за допомогою функції preg_match:

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

Функція preg_match повертає логічне значення, якщо modèle можна знайти в chaîne. Якщо так, то $champs[0] представляє підрядок, що відповідає шаблону. Крім того, якщо модель містить підмоделі в дужках, $champs[1] — це фрагмент $chaîne, що відповідає першій підмоделі, $champs[2] — це частина $chaîne, що відповідає другій підмоделі, тощо...

Розглянемо перший приклад. Шаблон визначено у рядку 8: він позначає послідовність однієї або декількох (+) цифр (\d), розміщених у будь-якому місці рядка. Крім того, шаблон визначає підшаблон, укладений у дужки.

  • 10-й рядок: шаблон /(\d+)/ (послідовність однієї або декількох цифр у будь-якому місці рядка) порівнюється з рядком «xyz1234abcd». Бачимо, що підрядок 1234 відповідає шаблону. Отже, $champs[0] дорівнює «1234». Крім того, шаблон містить підшаблони в дужках. Отже, $champs[1] дорівнює «1234».
  • рядок 11: шаблон /(\d+)/ порівнюється з рядком «12 34». Бачимо, що підрядки 12 та 34 відповідають шаблону. Порівняння зупиняється на першому підрядку, що відповідає шаблону. Отже, отримаємо: $champs[0]=12 та $champs[1]=12.
  • рядок 12: шаблон /(\d+)/ порівнюється з рядком «abcd». Збігів не знайдено.

Роз’яснимо шаблони, що використовуються далі в коді:


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

початок рядка (^), потім 0 або більше (*) довільних символів (.), потім 1 або більше (+) цифр, потім знову 0 або більше (*) довільних символів (.). Шаблон (.*) позначає 0 або більше довільних символів. Такий шаблон відповідатиме будь-якому рядку. Отже, шаблон /^(.*)(\d+)(.*)$/ ніколи не буде знайдений, оскільки перший підшаблон (.*) поглине весь рядок. Шаблон (.*?)(\d+) позначає 0 або більше довільних символів аж до наступного підшаблону (?), у даному випадку \d+. Отже, цифри тепер більше не поглинаються шаблоном (.*). Таким чином, наведений вище шаблон відповідає [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*$/";

відповідає [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. Спосіб передачі параметрів функцій (exemple_11)


<?php

// спосіб передачі параметрів

function f(&$i, $j) {
  // $i буде отримано за посиланням
  // $j буде отримано за значенням
  $i++;
  $j++;
  print "f[i,j]=[$i,$j]\n";
}

// ----------------------------------------тести
$i = 0;
$j = 0;
// $i та $j передані за значенням
f($i, $j);
print "test[i,j]=[$i,$j]\n";
?>

Результати:

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

Коментарі

Наведений вище код демонструє два способи передачі параметрів у функцію. Розглянемо такий приклад:

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

}

// головна програма
$i=10; $j=20;
f($i,$j);
  • рядок 1: визначає формальні параметри $a та $b функції f. Ця функція обробляє ці два формальні параметри та повертає результат.
  • рядок 7: виклик функції f з двома фактичними параметрами $i та $j. Зв’язки між формальними параметрами ($a, $b) та фактичними параметрами ($i, $j) визначено у рядку 7
  • &$a: знак & вказує, що формальний параметр $a прийме за значення адресу фактичного параметра $i. Інакше кажучи, $a та $i — це два посилання на одну й ту саму комірку пам’яті. Операції з формальним параметром $a еквівалентні операціям з фактичним параметром $i. Це підтверджується виконанням коду. Цей спосіб передачі підходить для вихідних параметрів та великих обсягів даних, таких як масиви та словники. Цей спосіб передачі називають передачею за посиланням.
  • $b: формальний параметр $b прийме значення, яке має фактичний параметр $j. Це передача за значенням. Формальні та фактичні параметри — це дві різні змінні. Операції з формальним параметром $b жодним чином не впливають на фактичний параметр $j. Це підтверджується виконанням коду. Цей режим передачі підходить для вхідних параметрів.
  • Розглянемо функцію échange, яка приймає два формальні параметри $a та $b. Функція міняє місцями значення цих двох параметрів. Отже, під час виклику з обміном ($i, $j) код, що викликає, очікує, що значення двох фактичних параметрів будуть поміняні місцями. Отже, це вихідні параметри (вони змінюються). Тому запишемо:
function échange(&$a,&$b){....}

3.7. Результати, що повертаються функцією (exemple_12)


<?php

// результати, що повертаються функцією
// функція може повертати кілька значень у масиві
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";

// функція може повертати псевдооб’єкт
$res = f2(10);
print "[$res->res1,$res->res2,$res->res3]\n";

// кінець
exit;

// функція f1
function f1($valeur) {
  // повертає масив ($valeur+1,$aleur+2,$baleur+3)
  return array($valeur + 1, $valeur + 2, $valeur + 3);
}

// функція f2
function f2($valeur) {
  // повертає псевдооб’єкт ($valeur+1,$aleur+2,$baleur+3)
  $res->res1 = $valeur + 1;
  ;
  $res->res2 = $valeur + 2;
  $res->res3 = $valeur + 3;
  // повертає об’єкт
  return $res;
}

?>

Результати

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

Коментарі

  • попередня програма показує, що функція PHP може повертати не одне, а декілька значень у вигляді масиву або об’єкта. Поняття об’єкта детальніше пояснюється трохи далі
  • рядки 19–22: функція f1 повертає кілька значень у вигляді масиву
  • рядки 25–33: функція f2 повертає кілька значень у вигляді об’єкта

3.8. Текстові файли (exemple_13)


<?php

// послідовна обробка текстового файлу
// цей файл є набором рядків у форматі login:pwd:uid:gid:infos:dir:shell
// кожен рядок заноситься до словника у вигляді login => uid:gid:infos:dir:shell

// визначається ім’я файлу
$INFOS = "infos.txt";

// файл відкривається для створення
if (!$fic = fopen($INFOS, "w")) {
  print "Erreur d'ouverture du fichier $INFOS en écriture\n";
  exit;
}

// генерується довільний вміст
for ($i = 0; $i < 100; $i++)
  fputs($fic, "login$i:pwd$i:uid$i:gid$i:infos$i:dir$i:shell$i\n");
// файл закривається
fclose($fic);

// використовуємо його — fgets зберігає маркер кінця рядка
// це дозволяє уникнути отримання порожнього рядка під час читання порожнього рядка
// файл відкривається для запису
if (!$fic = fopen($INFOS, "r")) {
  print "Erreur d'ouverture du fichier $INFOS en lecture\n";
  exit;
}
while ($ligne = fgets($fic, 1000)) {
  // видаляємо маркер кінця рядка, якщо він є
  $ligne = cutNewLineChar($ligne);
  // заносимо рядок у масив
  $infos = explode(":", $ligne);
  // отримуємо логін
  $login = array_shift($infos);
  // ігноруємо пароль
  array_shift($infos);
  // створюється запис у словнику
  $dico[$login] = $infos;
}
// закриваємо його
fclose($fic);

// використання словника
afficheInfos($dico, "login10");
afficheInfos($dico, "X");

// кінець
exit;

// --------------------------------------------------------------------------
function afficheInfos($dico, $clé) {
  // виводить значення, пов'язане з ключем у словнику $dico, якщо воно існує
  if (isset($dico[$clé])) {
    // значення існує — чи це масив?
    $valeur = $dico[$clé];
    if (is_array($valeur)) {
      print "[$clé," . join(":", $valeur) . "]\n";
    } else {
      // $valeur не є масивом
      print "[$clé,$valeur]\n";
    }
  } else {
    // $clé не є ключем словника $dico
    print "la clé [$clé] n'existe pas\n";
  }
}

// --------------------------------------------------------------------------
function cutNewLinechar($ligne) {
  // видаляється позначка кінця рядка з $ligne, якщо вона існує
  $L = strlen($ligne);  // довжина рядка
  while (substr($ligne, $L - 1, 1) == "\n" or substr($ligne, $L - 1, 1) == "\r") {
    $ligne = substr($ligne, 0, $L - 1);
    $L--;
  }
  // кінець
  return($ligne);
}

?>

Файл 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

Результати:

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

Коментарі

  • рядок 11: fopen(nom_fichier, "w") відкриває файл nom_fichier для запису (w=write). Якщо файл не існує, його створюють. Якщо він існує, його вміст очищують. Якщо створення файлу не вдається, fopen повертає значення false. В операторі if (!$fic = fopen($INFOS, "w")) {…} виконуються дві послідовні операції: 1) $fic = fopen(..) 2) if( ! $fic) {...}
  • рядок 18: fputs($fic, $chaîne) записує chaîne у файл $fic.
  • рядок 20: fclose($fic) закриває файл $fic.
  • рядок 25: fopen(nom_fichier,"r") відкриває файл nom_fichier для читання (r=read). Якщо відкриття не вдається (файл не існує), fopen повертає значення false.
  • рядок 29: fgets($fic,1000) зчитує наступний рядок з файлу, обмежуючи його довжину 1000 символами. В операції while ($ligne = fgets($fic, 1000)) {…} виконуються дві послідовні операції: 1) $ligne = fgets(...) 2) while ( ! $ligne). Після того, як прочитано останній символ файлу, функція fgets повертає порожній рядок, і цикл while зупиняється.
  • рядок 31: функція fgets зчитує рядок тексту, включаючи символ кінця рядка. Функція cutNewLineChar у рядках 70–79 видаляє можливий символ кінця рядка.
  • рядок 72: функція strlen($chaîne) повертає кількість символів у $chaîne.
  • рядок 73: функція substr($ligne, $position, $taille) повертає $taille символів з $ligne, починаючи з символу № $position, де перший символ має номер 0. На комп’ютерах з ОС Windows позначкою кінця рядка є «\r\n». На комп’ютерах з ОС Unix — це рядок «\n».
  • рядок 35: функція array_shift($tableau) видаляє перший елемент з $tableau і повертає його як результат.
  • рядок 37: використовується функція array_shift($tableau), але її результат ігнорується
  • рядок 57: функція is_array($variable) повертає true, якщо $variable є масивом, інакше — false.
  • рядок 58: функція join виконує те саме, що й функція implode, яку ми вже розглядали