Funkcje
Szybki quiz – przypomnienie poprzedniej lekcji
1. Co zostanie wyświetlone?
for ($i = 1; $i <= 10; $i++) {
if ($i % 3 != 0) {
continue;
}
echo $i . " ";
}
2. Ile razy wykona się echo? Co zostanie wyświetlone?
$i = 5;
do {
echo $i;
$i++;
} while ($i < 3);
Jak zmieni się wynik, jeżeli zamienimy tę pętlę na while ($i < 3) { ... }?
3. Dlaczego ten kod zawiesi skrypt?
$xp = 250;
$poziom = 1;
$prog = $poziom * XP_NA_POZIOM;
while ($xp >= $prog) {
$poziom++;
}
4. Którą pętlę (for, foreach, while, do...while) najlepiej wybrać?
a) wyświetlenie 10 segmentów paska XP,
b) awansowanie użytkownika tak długo, jak ma wystarczająco dużo XP,
c) wypisanie wszystkich elementów tablicy,
d) menu, które musi wyświetlić się co najmniej raz.
5. Co zostanie wyświetlone?
for ($i = 0; $i < 3; $i++) {
for ($j = 0; $j < 3; $j++) {
if ($j == 1) {
break;
}
echo "$i$j ";
}
}
6. Uzupełnij kod tak, aby wyświetlił Ania: 5 Jan: 4.
$oceny = ['Ania' => 5, 'Jan' => 4];
foreach ($oceny ____ $imie ____ $ocena) {
echo "$imie: $ocena ";
}
7. Znajdź błąd w składni alternatywnej.
<ul>
<?php for ($i = 1; $i <= 3; $i++): ?>
<li>Element <?= $i ?></li>
<?php endforeach; ?>
</ul>
Odpowiedzi
3 6 9–continuepomija liczby niepodzielne przez 3.- Jeden raz, wyświetli
5.do...whilesprawdza warunek dopiero po wykonaniu. Zwykływhilenie wykona się ani razu i nic nie wyświetli. $progjest obliczony raz przed pętlą (100) i się nie zmienia. Warunek250 >= 100jest zawsze prawdziwy – pętla nieskończona. Próg trzeba liczyć w warunku:while ($xp >= $poziom * XP_NA_POZIOM).- a)
for(znana liczba powtórzeń), b)while(nieznana liczba powtórzeń, warunek przed), c)foreach, d)do...while. 00 10 20–breakprzerywa tylko wewnętrzną pętlę, zewnętrzna działa dalej.foreach ($oceny as $imie => $ocena)- Pętla
formusi być zamknięta przezendfor;, a nieendforeach;.
Funkcja to nazwany, wielokrotnie używalny fragment kodu, który:
- Wykonuje określone zadanie
- Może przyjmować argumenty (parametry)
- Może zwracać wartość
- Pomaga unikać powtórzeń w kodzie (zasada DRY – Don’t Repeat Yourself)
W celu zdefiniowania funkcji należy podać jej nazwę, argumenty i instrukcje:
function przykladowa_nazwa_funkcji ($argument1,$argument2,$argument3.........)
{
instrukcja1;
instrukcja2;
instrukcja3......
}
Zasady nazywania funkcji:
- Nazwa może zawierać litery, cyfry, podkreślenia
- Nazwa musi zaczynać się od litery lub podkreślenia
- Konwencja:
camelCaselubsnake_case - Nazwa powinna opisywać, co funkcja robi
Funkcje mogą zwracać konkretne wartości lub wyświetlać komunikat.
Aby wywołać funkcję wystarczy podać jej nazwę z nawiasami!
przykladowa_nazwa_funkcji(); // wywołanie funkcji w kodzie
echo i return
echo nie zwraca wartości tylko wyświetla wynik na ekranie;
return zwraca wartość, którą możemy później wykorzystać jako zmienną.
| Aspekt | echo | return |
|---|---|---|
| Zwraca wartość | nie | tak |
| Wyświetla na ekranie | tak | nie |
| Można przypisać do zmiennej | nie | tak |
| Kończy wykonanie funkcji | nie | tak |
//używamy słowa kluczowego function, następnie podajemy nazwę funkcji oraz nawiasy.
//W nawiasie przekazujemy argument $x wewnątrz funkcji (zmienną na której będziemy pracowali
function funkjaZEcho($x) {
echo $x * 2;
}
function funkcjaZReturn($x) {
return $x * 2;
}
// Echo - nie możemy użyć wyniku
$wynik1 = funkjaZEcho(5); // wyświetli 10
var_dump($wynik1); // NULL - nic nie zostało zwrócone
// Return - możemy użyć wyniku
$wynik2 = funkcjaZReturn(5); // nic nie wyświetli
var_dump($wynik2); // int(10) - wartość została zwrócona
echo $wynik2; // wyświetli 10
Przykład funkcji bez argumentów:
function wyswietl_tekst() // deklaracja funkcji bez argumentów
{
echo "Witam serdecznie!"; // instrukcje do wykonania
}
wyswietl_tekst(); //ponieważ wewnątrz funkcji jest echo to dostaniemy napis: Witam serdecznie!
Przykład funkcji z argumentami:
function dodawanie($liczba1, $liczba2)
{
$wynik = $liczba1+$liczba2;
echo $wynik;
}
dodawanie(2,3); //ponieważ wewnątrz funkcji jest echo to dostaniemy napis: 5
Funkcja zwracająca wartość
function dodawanie($liczba1, $liczba2) {
$wynik = $liczba1 + $liczba2;
return $wynik;
}
echo dodawanie(2, 3); // Wynik: 5
$suma = dodawanie(10, 20); // $suma = 30
Nowoczesna składnia funkcji (PHP 7.0+)
Deklaracje typów argumentów
function dodawanie(int $a, int $b): int {
return $a + $b;
}
echo dodawanie(5, 10); // 15
// echo dodawanie(5.5, 10.2); // TypeError w strict mode
Strict types
Wymuszenie ścisłego sprawdzania typów bez automatycznej konwersji.
Po co?
- Eliminuje ukryte konwersje typów (type juggling)
- Wyłapuje więcej błędów na etapie wywołania funkcji
- Kod jest bardziej przewidywalny
Jak włączyć? Dodaj na samym początku pliku PHP: declare(strict_types=1);
UWAGA! declare(strict_types=1) działa tylko w pliku, w którym został zadeklarowany (nie jest globalny).
// Bez strict_types (domyślnie - tryb coercive)
function suma(int $a, int $b): int {
return $a + $b;
}
echo suma(5, 10); // 15
echo suma("5", "10"); // 15 - stringi automatycznie skonwertowane na int!
echo suma(5.9, 10.1); // 15 - float automatycznie obcięty do int!
// Ze strict_types
declare(strict_types=1);
function suma(int $a, int $b): int {
return $a + $b;
}
echo suma(5, 10); // 15 ✓
// echo suma("5", "10"); // TypeError: Argument must be of type int, string given
// echo suma(5.9, 10.1); // TypeError: Argument must be of type int, float given
Nullable Types (Typy dopuszczające null) – PHP 7.1+
Możliwość zaakceptowania wartości null oprócz określonego typu.
Po co?
- Funkcja może otrzymać wartość opcjonalną
- Jasno komunikuje, że brak wartości jest dopuszczalny
- Alternatywa dla wartości domyślnych
Składnia: Dodaj ? przed typem
// Bez nullable - null nie jest dozwolone
function powitanie(string $imie): string {
return "Witaj, $imie!";
}
// powitanie(null); // TypeError
// Z nullable - null jest dozwolone
function powitanie(?string $imie): string {
if ($imie === null) {
return "Witaj, nieznajomy!";
}
return "Witaj, $imie!";
}
echo powitanie("Jan"); // Witaj, Jan!
echo powitanie(null); // Witaj, nieznajomy!
Union Types (Typy złożone) – PHP 8.0+
Możliwość określenia, że funkcja akceptuje jeden z kilku typów.
Po co?
- Funkcja może pracować z różnymi typami danych
- Bardziej elastyczne niż pojedynczy typ
- Lepsze niż
mixed(zbyt ogólne) - Czytelniejsze niż komentarze PHPDoc
Składnia: Typy oddzielone | (pipe)
function formatuj(int|float $liczba): string {
return number_format($liczba, 2);
}
echo formatuj(10); // 10.00
echo formatuj(10.567); // 10.57
Named Arguments (Nazwane argumenty) – PHP 8.0+
Przekazywanie argumentów do funkcji przez podanie ich nazw zamiast kolejności.
Po co?
- Nie musisz pamiętać kolejności parametrów
- Możesz pominąć parametry opcjonalne (z wartościami domyślnymi)
- Kod jest bardziej czytelny
- Łatwiej wywołać funkcje z wieloma parametrami
function stworzUzytkownika(
string $imie,
string $email,
int $wiek = 18,
bool $aktywny = true
) {
// ...
}
// Stary sposób - musimy pamiętać o kolejności
stworzUzytkownika("Jan", "jan@example.com", 25, true);
// Nowy sposób - możemy podać tylko wybrane argumenty
stworzUzytkownika(
email: "jan@example.com",
imie: "Jan",
wiek: 25
);
Callback
Callback to funkcja (lub metoda) przekazywana jako argument do innej funkcji, która następnie wywołuje ją w swoim wnętrzu. Pozwala to na wstrzyknięcie własnego kodu lub logiki do gotowej, działającej już struktury, co czyni kod znacznie bardziej elastycznym i wielokrotnego użytku.
W PHP funkcje przekazywane jako callback są najczęściej definiowane na jeden z trzech sposobów:
1. Jako zwykła funkcja (jako ciąg znaków)
Gdy masz gotową nazwę funkcji, przekazujesz ją w formie zwykłego tekstu (stringa).
function mojaWitajka($imie) {
return "Cześć, " . $imie . "!";
}
function uruchomCallback($funkcjaZwrotna) {
echo $funkcjaZwrotna("Jan");
}
uruchomCallback('mojaWitajka'); // Wynik: Cześć, Jan!
//nie podajemy ()
2. Jako funkcja anonimowa (Closure)
To najpopularniejsza metoda. Definiujesz funkcję „w locie” (inline) bezpośrednio w wywołaniu metody.
Główny sens stosowania funkcji anonimowych (zarówno tradycyjnych, jak i strzałkowych) sprowadza się do jednej zasady: tworzenia kodu jednorazowego użytku dokładnie tam, gdzie jest potrzebny, bez zaśmiecania pamięci i globalnej przestrzeni nazw.
Wyobraź sobie funkcję anonimową jako „jednorazową chusteczkę” – używasz jej do wykonania drobnego zadania i natychmiast wyrzucasz, zamiast szyć trwałą, materiałową chustkę (zwykłą funkcję), którą musisz potem gdzieś przechowywać i prać.
// Tradycyjna funkcja anonimowa
$kwadrat = function($x) {
return $x ** 2;
};
// Arrow function - krótsza składnia
$kwadrat = fn($x) => $x ** 2;
echo $kwadrat(5); // 25
// Przydatne z array_map
$liczby = [1, 2, 3, 4, 5];
$kwadraty = array_map(fn($x) => $x ** 2, $liczby);
print_r($kwadraty); // [1, 4, 9, 16, 25]
$liczby = [1, 2, 3, 4];
$noweLiczby = array_map(function($n) {
return $n * 2;
}, $liczby);
print_r($noweLiczby); // Wynik: Array ( [0] => 2 [1] => 4 [2] => 6 [3] => 8 )
Przykład: Sortowanie użytkowników po wieku
$pracownicy = [
['imie' => 'Ania', 'wiek' => 35],
['imie' => 'Jan', 'wiek' => 24],
['imie' => 'Kasia', 'wiek' => 28]
];
usort($pracownicy, function($a, $b) {
// $a i $b to dwa porównywane w danym momencie elementy (czyli wewnętrzne tablice)
return $a['wiek'] <=> $b['wiek'];
/*
funkcja za pomocą operatora <=> (spaceship operator) zwraca liczbę:
- ujemną (jeśli $a ma być przed $b)
- dodatnią (jeśli $a ma być po $b)
- zero (jeśli są równe)
*/
});
//Aby odwrócić kolejność sortowania na malejącą (od najwyższej wartości do najniższej) za pomocą operatora <=> (spaceship operator), wystarczy zamienić zmienne miejscami w wyrażeniu porównującym. Zamiast pisać $a <=> $b, piszesz $b <=> $a.
3. Jako metoda w klasie
Możesz również wywołać metodę należącą do obiektu, przekazując w argumencie tablicę z obiektem i nazwą metody.
class MojaKlasa {
public function powitanie($imie) {
return "Witaj ponownie, " . $imie;
}
}
$obiekt = new MojaKlasa();
call_user_func([$obiekt, 'powitanie'], 'Anna');
Argumenty domyślne
function powitanie($imie = "Gość") {
return "Witaj, $imie!";
}
echo powitanie("Jan"); // Witaj, Jan!
echo powitanie(); // Witaj, Gość!
UWAGA! Argumenty z wartościami domyślnymi muszą być na końcu listy parametrów!
// ŹLE
function zle($a = 5, $b) { }
// DOBRZE
function dobrze($b, $a = 5) { }
Zmienna liczba argumentów
//Sposób tradycyjny
function suma() {
$args = func_get_args();
return array_sum($args);
}
echo suma(1, 2, 3, 4, 5); // 15
//Spread operator (PHP 5.6+)
function suma(...$liczby): int {
return array_sum($liczby);
}
echo suma(1, 2, 3, 4, 5); // 15
// Możemy też rozwinąć tablicę
$liczby = [10, 20, 30];
echo suma(...$liczby); // 60
Zasięg zmiennych
Zmienne lokalne
function test() {
$lokalna = "Jestem lokalna";
echo $lokalna;
}
test(); // Jestem lokalna
// echo $lokalna; // Błąd: niezdefiniowana zmienna
Zmienne globalne (unikaj)
$globalna = "Jestem globalna";
function test() {
global $globalna;
echo $globalna;
}
test(); // Jestem globalna
NIE UŻYWAJ zmiennych globalnych!
Dlaczego?
- Trudne do debugowania
- Ryzyko konfliktów nazw
- Zagrożenie bezpieczeństwa
- Utrudniają testowanie
- Naruszają zasady czystego kodu
Zamiast tego – przekazuj jako argumenty:
// ŹLE
$podatek = 0.23;
function obliczBrutto() {
global $podatek;
// ...
}
// DOBRZE
function obliczBrutto(float $netto, float $podatek): float {
return $netto * (1 + $podatek);
}
echo obliczBrutto(100, 0.23); // 123
Zmienne statyczne
function licznik() {
static $count = 0;
$count++;
return $count;
}
echo licznik(); // 1
echo licznik(); // 2
echo licznik(); // 3
Zastosowanie: Liczniki, cache, singleton pattern.
Przekazywanie przez referencję
Wartość vs Referencja
// Przekazywanie przez wartość (domyślne)
function podwojPrzezWartosc($x) {
$x *= 2;
}
$liczba = 10;
podwojPrzezWartosc($liczba);
echo $liczba; // 10 - nie zmienione
// Przekazywanie przez referencję (&)
function podwojPrzezReferencje(&$x) {
$x *= 2;
}
$liczba = 10;
podwojPrzezReferencje($liczba);
echo $liczba; // 20 - zmienione!
UWAGA! Używaj referencji tylko gdy naprawdę potrzebujesz modyfikować oryginalną zmienną.
Funkcje rekurencyjne
Funkcja rekurencyjna to funkcja, która wywołuje samą siebie.
Przykład: Silnia
function silnia(int $n): int {
if ($n <= 1) {
return 1; // warunek stopu
}
return $n * silnia($n - 1);
}
echo silnia(5); // 120 (5 * 4 * 3 * 2 * 1)
Przykład: Fibonacci
function fibonacci(int $n): int {
if ($n <= 1) {
return $n;
}
return fibonacci($n - 1) + fibonacci($n - 2);
}
echo fibonacci(10); // 55
UWAGA! Rekurencja może być nieefektywna dla dużych wartości (przepełnienie stosu). Często lepsze są iteracyjne rozwiązania lub memoizacja.
Przykładowe funkcje
Funkcja formatująca przekreślenie
function skresl(string $text): string {
return "<s>$text</s>";
}
echo "To jest tekst niesformatowany<br>";
echo skresl("to jest tekst przekreślony.");
Funkcja kantor przeliczająca wartość kupna EUR na PLN wg podanego kursu
function kantor(float $kurs, float $kwota): array {
return [
'kwota_euro' => $kwota,
'kurs' => $kurs,
'kwota_pln' => round($kwota * $kurs, 2)
];
}
$wynik = kantor(4.3051, 10);
echo "Kupno {$wynik['kwota_pln']} PLN za {$wynik['kwota_euro']} EUR";
Funkcja, która za pomocą znaków * (gwiazdki) narysuje trójkąt.
function rysujTrojkat(int $wysokosc): void {
echo '<pre>';
for ($i = 1; $i <= $wysokosc; $i++) {
echo str_repeat(' ', $wysokosc - $i);
echo str_repeat('*', 2 * $i - 1);
echo "\n";
}
echo '</pre>';
}
rysujTrojkat(5);
Funkcja, która za pomocą znaków * (gwiazdki) narysuje „koło”.
function rysujKolo(int $promien): void {
echo '<pre>';
for ($y = -$promien; $y <= $promien; $y++) {
for ($x = -$promien; $x <= $promien; $x++) {
if ($x**2 + $y**2 <= ($promien + 0.3)**2) {
echo '*';
} else {
echo ' ';
}
echo ' ';
}
echo "\n";
}
echo '</pre>';
}
rysujKolo(10);
Funkcja rysująca tabelę w HTML składająca się z podanej ilości wierszy i kolumn.
function rysujTabele(int $wiersze, int $kolumny): void {
echo '<table border="1">';
for ($w = 1; $w <= $wiersze; $w++) {
echo '<tr>';
for ($k = 1; $k <= $kolumny; $k++) {
echo "<td>W$w K$k</td>";
}
echo '</tr>';
}
echo '</table>';
}
rysujTabele(4, 5);
//z HTML
function generujTabele(int $wiersze, int $kolumny): string {
$html = '<table border="1">';
for ($w = 1; $w <= $wiersze; $w++) {
$html .= '<tr>';
for ($k = 1; $k <= $kolumny; $k++) {
$html .= "<td>W$w K$k</td>";
}
$html .= '</tr>';
}
$html .= '</table>';
return $html;
}
echo generujTabele(4, 5);
Funkcja rysująca tabliczkę mnożenia.
function tabliczkaMnozenia(int $rozmiar): void {
echo '<table style="border-collapse: collapse;">';
for ($i = 1; $i <= $rozmiar; $i++) {
echo '<tr>';
for ($j = 1; $j <= $rozmiar; $j++) {
$wynik = $i * $j;
$style = 'border: 1px solid black; padding: 5px; text-align: center;';
if ($i == 1 || $j == 1) {
$style .= ' background-color: #333; color: white;';
}
echo "<td style='$style'>$wynik</td>";
}
echo '</tr>';
}
echo '</table>';
}
tabliczkaMnozenia(10);
Ciąg Fibonacciego PHP
function fibonacci(int $n): array {
if ($n <= 0) {
return [];
}
if ($n == 1) {
return [0];
}
$ciag = [0, 1];
for ($i = 2; $i < $n; $i++) {
$ciag[] = $ciag[$i - 1] + $ciag[$i - 2];
}
return $ciag;
}
$wynik = fibonacci(10);
echo implode(' ', $wynik); // 0 1 1 2 3 5 8 13 21 34
echo "\n10. elementem ciągu Fibonacciego jest " . end($wynik);
Funkcje wbudowane
Pełną listę funkcji znajdziecie w dokumentacji PHP, poniżej najczęściej wykorzystywane.
Funkcje daty i czasu – opracowane w temacie PHP – obsługa daty i czasu
Funkcje operacji na ciągach – opracowane w temacie PHP. Łańcuchy znaków i wyrażenia regularne.
Funkcje operacji na katalogach – opracowane w temacie PHP – operacje na strukturze systemu plików
Funkcje operacji na plikach – opracowane w temacie PHP – Operacje na plikach
Funkcje tablicowe – opracowane w temacie PHP – operacje na tablicach
phpinfo()
Wyświetla informacje o konfiguracji serwera.
<?php phpinfo(); ?>
Funkcje obsługi zmiennych
Pełną listę funkcji znajdziecie w dokumentacji PHP, poniżej najczęściej wykorzystywane.
empty()
ustala czy zmienna jest pusta.
$zmienna=0;
if (empty($zmienna)) { echo '$var jest równe zero, puste lub w ogóle nie zostało ustalone';}
Następujące wartości są uważane za puste:
- „” (pusty ciąg)
- 0 (0 jako integer)
- 0.0 (0 jako float)
- „0” (0 jako string)
- NULL
- FALSE
- [] (pusta tablica)
- niezidentyfikowana zmienna
gettype() i get_debug_type()
pobiera typ zmiennej
echo gettype(1); // integer
echo gettype(1.5); // double
echo gettype(null); // NULL
echo gettype('tekst'); // string
echo gettype([]); // array
echo gettype(true); // boolean
//Nowoczesne podejście (PHP 8.0+):
echo get_debug_type(1); // int
echo get_debug_type(1.5); // float
echo get_debug_type('tekst'); // string
is_null()
ustala czy zmienna jest ustawiona na NULL
$zmienna = null;
if (is_null($zmienna)) {
echo "Zmienna jest NULL";
}
// Równoważne z:
if ($zmienna === null) {
echo "Zmienna jest NULL";
}
is_numeric()
sprawdza czy zmienna jest liczbą, lub liczbowym stringiem
var_dump(is_numeric("42")); // true
var_dump(is_numeric(1337)); // true
var_dump(is_numeric("1e4")); // true
var_dump(is_numeric([])); // false
var_dump(is_numeric(9.1)); // true
var_dump(is_numeric("abc")); // false
isset()
Sprawdza czy zmienna została przesłana i nie jest NULL
$zmienna = '';
if (isset($zmienna)) {
echo "Zmienna została zdefiniowana";
}
// Różnica między isset a empty
$x = 0;
var_dump(isset($x)); // true
var_dump(empty($x)); // true
settype()
Konwertuje typ zmiennej (modyfikuje oryginalną zmienną).
$zmienna1 = "5bar";
$zmienna2 = true;
settype($zmienna1, "integer"); // $zmienna1 = 5
settype($zmienna2, "string"); // $zmienna2 = "1"
echo $zmienna1; // 5
echo $zmienna2; // 1
//Preferowane rzutowanie:
$zmienna1 = "5bar";
$zmienna2 = true;
$zmienna1 = (int)$zmienna1; // 5
$zmienna2 = (string)$zmienna2; // "1"
unset()
usuwa zmienną
$zmienna=5; echo is_null($zmienna) ? 'jest NULL' : 'nie jest NULL'; unset($zmienna); echo isset($zmienna) ? 'istnieje' : 'nie istnieje';
Funkcje matematyczne
Pełną listę funkcji znajdziecie w dokumentacji PHP, poniżej najczęściej wykorzystywane.
abs()
Wartość bezwzględna (moduł z liczby)
echo abs(-4.2); // 4.2 (double/float) echo abs(5); // 5 (integer) echo abs(-5); // 5 (integer)
round()
Zaokrągla liczbę zmiennoprzecinkową
echo round(3.4); // 3 echo round(3.5); // 4 echo round(3.6); // 4 echo round(3.6, 0); // 4 echo round(1.95583, 2); // 1.96 echo round(1241757, -3); // 1242000 echo round(5.045, 2); // 5.05 echo round(5.055, 2); // 5.06
ceil()
Zaokrągla ułamki w górę
echo ceil(4.3); // 5; echo ceil(9.999); // 10; echo ceil(-3.14); // -3
floor()
Zaokrągla ułamki w dół
echo floor(4.3); // 4; echo floor(9.999); // 9; echo floor(-3.14); // -4
hypot()
Oblicza długość przeciwprostokątnej trójkąta prostokątnego. hypot() zwraca długość przeciwprostokątnej trójkąta prostokątnego, o długościach przyprostokątnych x i y, lub odległość punktu o współrzędnych (x, y) od początku układu współrzędnych. Jest to równoważne wyrażeniu sqrt(x*x + y*y).
echo hypot(20,21); //29
log()
Logarytm naturalny. Jeśli opcjonalny argument podstawa został podany, log() zwraca logpodstawaargument, w przeciwnym przypadku log() zwraca logarytm naturalny z argument.
echo log(1000000,10); //6
pi() lub M_PI
Funkcja pi() wyświetla wartość liczby Pi, tą samą wartość można wywołać używając stałej wbudowanej M_PI.
echo pi(); // 3.1415926535898 echo M_PI; // 3.1415926535898
pow()
potęgowanie.
number pow ( number $podstawa , number $wykładnik ) echo 2**3; //8 echo pow(2,3); //8
sqrt()
Pierwiastek kwadratowy.
echo sqrt(9); // 3 echo sqrt(10); // 3.16227766 ...
max() i min()
max() znajduje największą liczbę, a min() najmniejszą.
PHP będzie uznawał nieliczbowe wartości typu string jako 0, jednakże zwracany będzie ciąg znakowy, jeśli zostanie on uznany numerycznie za największą/najmniejszą wartość. Jeśli wiele argumentów zostanie uznanych za wartość 0, to max()/min() zwróci wartość największą/najmniejszą alfanumerycznie, jeśli zostały podane jakiekolwiek ciągi znakowe. W przeciwnym przypadku zwrócona zostanie wartość 0.
echo max(1, 3, 5, 6, 7); // 7
echo max(array(2, 4, 5)); // 5
echo max(0, 'hello'); // 0
echo max('hello', 0); // hello
echo max(-1, 'hello'); // hello
// W przypadku podania wielu tablic, max porównuje je od lewej do prawej, a więc w poniższym przykładzie 2 == 2, ale 4 < 5
print_r($val = max(array(2, 4, 8), array(2, 5, 7))); // wyświetli tablicę array(2, 5, 7)
// Jeśli podane zostaną tablice i nie-tablice, zawsze zwracana jest tablica, jako że zawsze jest uznawana za element największy
print_r($val = max('string', array(2, 5, 7), 42)); // wyświetli tablicę array(2, 5, 7)
echo min(1, 3, 5, 6, 7); // 1
echo min(array(2, 4, 5)); // 2
echo min(0, 'hello'); // 0
echo min('hello', 0); // hello
echo min(-1, 'hello'); // -1
// W przypadku podania wielu tablic, max porównuje je od lewej do prawej, a więc w poniższym przykładzie 2 == 2, ale 4 < 5
print_r($val = min(array(2, 4, 8), array(2, 5, 7))); // wyświetli tablicę array(2, 4, 8)
// Jeśli podane zostaną tablice i nie-tablice, zawsze zwracana jest tablica, jako że zawsze jest uznawana za element największy
print_r($val = min('string', array(2, 5, 7), 42)); // wyświetli string
deg2rad()
Przelicza stopnie na radiany.
echo deg2rad(45); //0.785398163397
rad2deg()
Przelicza radiany na stopnie.
echo rad2deg(0.785398163397); //44.999999999974
Funkcje trygonometryczne
sin()
Oblicza sinus kąta. Kąt musi zostać podany w radianach.
echo sin(deg2rad(60)); // 0.866025403 ... echo sin(60); // -0.304810621 ...
cos()
Oblicza cosinus kąta. Kąt musi zostać podany w radianach.
$stopnie=360; echo cos(deg2rad($stopnie)); //1
tan()
Oblicza tangens kąta. Kąt musi zostać podany w radianach.
$stopnie=60; echo tan(deg2rad($stopnie)); //1.7320508075689
Funkcje związane z losowaniem
rand() i mt_rand()
rand() generuje losową liczbę stałoprzecinkową, mt_rand() generuje lepsza liczbę losową, funkcja ta jest szybsza od rand().
echo rand(); //7771 echo rand(); //22264 echo rand(5, 15); //11 echo mt_rand(); //1604716014 echo mt_rand(); //1478643278 echo mt_rand(5, 15); //6
PHP 7.0+ – random_int() (kryptograficznie bezpieczne):
echo random_int(1, 100); // losowa liczba 1-100 (bezpieczna)
getrandmax() i mt_getrandmax()
Pokazuje największą możliwą do wylosowania przez funkcję rand() lub mt_rand() liczbę. mt_getrandmax() jest szybsza.
echo getrandmax(); //2147483647 echo mt_getrandmax(); //2147483647
Konwersja liczb
base_convert()
Konwertuje liczbę pomiędzy różnymi systemami liczbowymi. Może tracić precyzję przy dużych liczbach!
$hexadecimal = 'a37334'; echo base_convert($hexadecimal, 16, 2); //wyświetli 101000110111001100110100
bindec()
Konwertuje liczbę dwójkową na dziesiętną. Podana liczba musi być stringiem, czyli w ”
echo bindec('110011'); //wyświetli 51
echo bindec('000110011'); //wyświetli 51
echo bindec('111'); //wyświetli 7
decbin()
Konwertuje liczbę dziesiętną do dwójkowej.
echo decbin(12); //wyświetli 1100 echo decbin(26); //wyświetli 11010
dechex()
Konwertuje liczbę dziesiętną do szesnastkowej.
echo dechex(10); //wyświetli a echo dechex(47); //wyświetli 2f
hexdec()
Konwertuje liczbę szesnastkową do dziesiętnej.
echo hexdec("to"); //wyświetli 0
echo hexdec("a0"); //wyświetli 160
decoct()
Konwertuje liczbę dziesiętną do ósemkowej.
echo decoct(15); //wyświetli 17 echo decoct(264); //wyświetli 410
octdec()
Konwertuje liczbę ósemkowej do dziesiętnej.
echo octdec(17); //wyświetli 15 echo octdec(410); //wyświetli 264
Funkcja mail
mail()
Funkcja mail() wymaga poprawnej konfiguracji serwera SMTP!
$do = 'osoba@example.com';
$temat = 'Temat wiadomości';
$tresc = 'Treść wiadomości';
$naglowki = 'From: nadawca@example.com' . "\r\n" .
'Reply-To: nadawca@example.com' . "\r\n" .
'X-Mailer: PHP/' . phpversion();
if (mail($do, $temat, $tresc, $naglowki)) {
echo 'Wiadomość wysłana';
} else {
echo 'Błąd wysyłania';
}
Dokładny opis funkcji mail() dostępny na stronie dokumentacji PHP
Nowoczesne podejście – użyj biblioteki PHPMailer lub Symfony Mailer:
// Przykład z PHPMailer (zainstaluj przez Composer)
use PHPMailer\PHPMailer\PHPMailer;
$mail = new PHPMailer(true);
$mail->setFrom('nadawca@example.com', 'Nadawca');
$mail->addAddress('odbiorca@example.com');
$mail->Subject = 'Temat';
$mail->Body = 'Treść wiadomości';
$mail->send();
Podsumowanie
Kluczowe pojęcia:
- Funkcja – nazwany, wielokrotnie używalny fragment kodu
- Parametr – zmienna w definicji funkcji
- Argument – wartość przekazana do funkcji
- Return – zwracanie wartości z funkcji
- Zasięg – gdzie zmienna jest dostępna (lokalny, globalny)
- Rekurencja – funkcja wywołująca samą siebie
Pamiętaj:
- Używaj typów dla parametrów i wartości zwracanych
- Jedna funkcja = jedno zadanie
- Unikaj zmiennych globalnych
- Zwracaj wartości zamiast echo (gdy to możliwe)
- Waliduj argumenty wejściowe
- Używaj znaczących nazw funkcji
- Preferuj pure functions (bez efektów ubocznych)
- Dokumentuj złożone funkcje (PHPDoc)
Zadania:
- Napisz funkcję, która przyjmuje 3 argumenty: 2 z nich to liczby, a trzecia to znak operatora arytmetycznego. Funkcja ma wykonać działanie na liczbach w zależności od wprowadzonego znaku np. 1,2,+ wykona dodawanie, 5,6,** wykona potęgowanie itd. Tam gdzie to możliwe wykorzystaj funkcje wbudowane.
- Napisz funkcję, która dla 3 losowo wygenerowanych liczb sprawdzi, czy są one pitagorejskie (czyli spełniają warunek: a2+b2=c2). Jeżeli tak to ma wyświetlić „Wylosowane liczby są liczbami pitagorejskimi”, w przeciwnym wypadku odwrotny komunikat.
- Napisz funkcję, która wyświetli na ekranie wszystkie trójki pitagorejskie z zakresu podanego przez użytkownika. (np. dla zakresu od 1-10 sprawdzamy trójki: 1 2 3; 2 3 4; 3 4 5; 4 5 6 itd)
- Napisz funkcję obliczającą cenę brutto dla podanej ceny netto i stawki vat. Wyświetl: cena netto, wartość vat, cena brutto.
- Napisz funkcję showName wyświetlającą imię przekazane do niej jako argument.
- Napisz funkcję o nazwie checkNumber, która zwraca prawdę (true), jeżeli przekazany argument jest mniejszy od zera.
- Przygotuj funkcję, która jako argument przyjmuje liczbę i zwraca prawdę, jeśli liczba jest podzielna przez 5 i 7.
- Przygotuj program, który podaną przez użytkownika kwotę pieniędzy (liczba całkowita) rozmieni na jak najmniejszą ilość monet i banknotów o nominałach 1, 2, 5, 10 złotych
- Napisz funkcję rekurencyjną i zwykłą obliczający silnię dowolnej liczby.
- Napisz skrypt z użyciem pętli for wyświetlający:
*
**
***
****
***** - Napisz skrypt z użyciem pętli for wyświetlający:
*
**
***
****
*****
****
***
**
* - Napisz funkcję obliczającą pole trójkąta równobocznego.
- Napisz funkcję iloczyn zwracającą iloczyn dwóch liczb przekazanych jako argumenty.
- Napisz funkcję o nazwie czyUjemna, która zwraca prawdę (true), jeżeli przekazany argument jest mniejszy od zera.
- Napisz funkcję, która jako argument przyjmuje liczbę i zwraca prawdę, jeśli liczba jest podzielna przez 3 i 5.
- Napisz funkcję BMI, obliczającą indeks masy ciała z dwóch wartości: masy i wzrostu przekazanych jako
argumenty. Do obliczeń użyj następującego wzoru: BMI=masa(kg)/(wzrost(m)*wzrost(m)). Funkcja ma
wyświetlać trzy komunikaty zależne od indeksu BMI:
• BMI < 18,5: „Masz niedowagę”
• 18,5 < BMI < 24,99: „Twoja waga jest prawidłowa”
• BMI > 25,00: „Masz nadwagę!!!” - Napisz funkcję zwracającą średnią arytmetyczną liczb przekazanych jako tablica do funkcji.
- Napisz funkcję pobierającą dwa argumenty: kolor w formie heksadecymalnej oraz napis. Funkcja ma
umieszczać na stronie napis w kolorze przekazanym jako argument. - Napisać funkcję o nazwie DzielenieTekstow (o 1 parametrze: $wyrazenie_zlozone), która jako parametr przyjmuje zmienną $wyrazenie_zlozone; w parametrze powinien być wczytany do funkcji ciąg znaków (tekst) postaci:
pojedyncze wyrażenia oddzielone przecinkami:
(np. „Komputer,Serwer,Router,Klawiatura,Mysz,Karta sieciowa,Monitor,Zasilacz”).
Funkcja ma za zadanie wypisać każde pojedyncze wyrażenie znajdujące się w zmiennej $wyrazenie_zlozone w osobnej linii.
Dodatkowo, przy wypisywaniu muszą być spełnione następujące założenia:
1. Pierwsze i ostatnie pojedyncze wyrażenie mają być wypisane dużymi literami.
2. Wszystkie pojedyncze wyrażenia (poza pierwszym i ostatnim), zawierające więcej niż 7 znaków należy wypisać małymi literami oraz jako pogrubione.
Ostatecznie funkcja zwraca ilość pojedynczych wyrażeń, które wystąpiły w zmiennej $wyrazenie_zlozone.
TaskQuest — Twój projekt na cały semestr
KARTA PRACY
TaskQuest 0.6 — zamykamy logikę w funkcjach
Cel lekcji
Wykorzystać funkcje do uporządkowania kodu stworzonego podczas poprzednich lekcji.
Po tej lekcji TaskQuest:
- nadal poprawnie oblicza poziom użytkownika,
- nadal oblicza postęp XP,
- nadal ustala tytuł użytkownika,
- ale najważniejsze operacje nie będą już zapisane bezpośrednio w głównym kodzie,
- będzie można wielokrotnie wykorzystać tę samą logikę.
Co dziś budujesz?
Na poprzedniej lekcji naprawiliśmy system poziomów.
Kod działa, ale zaczyna wyglądać mniej więcej tak:
$poziomStartowy = $poziom;
while ($xp >= $poziom * XP_NA_POZIOM) {
$poziom++;
}
$liczbaAwansow = $poziom - $poziomStartowy;
$tytul = match ($poziom) {
1 => "Nowicjusz",
2 => "Wojownik",
default => "Mistrz"
};
$xpNaPoczatkuPoziomu = ($poziom - 1) * XP_NA_POZIOM;
$xpWAktualnymPoziomie = $xp - $xpNaPoczatkuPoziomu;
$procentPostepu = ($xpWAktualnymPoziomie / XP_NA_POZIOM) * 100;
Działa.
Ale pojawia się nowy problem.
1. Najpierw znajdź problem
Wyobraź sobie, że za chwilę będziemy chcieli obliczać poziom:
- na stronie głównej,
- na profilu użytkownika,
- w rankingu,
- przy zdobyciu odznaki.
Czy w każdym miejscu mamy kopiować:
while ($xp >= $poziom * XP_NA_POZIOM) {
$poziom++;
}
Odpowiedź brzmi nie.
Poznaliśmy właśnie mechanizm, który pozwala nazwać fragment logiki i wykorzystywać go wielokrotnie.
2. SAMODZIELNIE — pierwsza funkcja
Utwórz funkcję:
obliczPoziom()
Funkcja powinna:
- otrzymać liczbę XP,
- rozpocząć liczenie od poziomu 1,
- za pomocą
whileobliczyć poziom, - zwrócić wynik.
Nie używaj w funkcji:
echo
Funkcja ma zwrócić poziom, abyśmy później mogli go wykorzystać.
HINT 1
Funkcja może wyglądać tak:
function obliczPoziom($xp)
{
// ...
}
HINT 2
Wewnątrz nadal możesz wykorzystać kod z poprzedniej lekcji:
$poziom = 1;
while ($xp >= $poziom * XP_NA_POZIOM) {
$poziom++;
}
Brakuje tylko jednego elementu.
Jak sprawić, żeby obliczony poziom wrócił do miejsca, w którym wywołaliśmy funkcję?
Potrzebujesz:
return $poziom;
3. Użyj wyniku funkcji
Po utworzeniu funkcji kod główny powinien móc wyglądać tak:
$xp = 250;
$poziom = obliczPoziom($xp);
echo $poziom;
Oczekiwany wynik:
3
Przetestuj również:
40 XP
100 XP
250 XP
550 XP
Wyniki powinny być identyczne jak w lekcji 5.
Usuwamy z logiki aplikacji zmienne liczbaAwansow i $poziomStartowy. W Lekcji 5 `poziomStartowybył potrzebny, ponieważ bezpośrednio zmienialiśmy wartość$poziom. W tej lekcji logika obliczania poziomu została przeniesiona do funkcji obliczPoziom()`, dlatego ta zmienna nie jest już potrzebna.
4. echo czy return?
Przeprowadź eksperyment.
Utwórz dwie funkcje:
function poziomEcho($xp)
{
echo 3;
}
function poziomReturn($xp)
{
return 3;
}
Następnie:
$wynik1 = poziomEcho(250);
$wynik2 = poziomReturn(250);
var_dump($wynik1);
var_dump($wynik2);
Sprawdź wynik.
Odpowiedz:
Dlaczego
$wynik1nie zawiera liczby 3, mimo że funkcja wyświetliła 3?
5. Funkcja odpowiedzialna za tytuł
Przenieś również mechanizm:
$tytul = match ($poziom) {
1 => "Nowicjusz",
2 => "Wojownik",
default => "Mistrz"
};
do funkcji:
function pobierzTytul($poziom)
{
// ...
}
Funkcja powinna zwracać napis.
W głównym kodzie:
$tytul = pobierzTytul($poziom);
6. Funkcja obliczająca XP aktualnego poziomu
Utwórz:
function obliczXpWAktualnymPoziomie($xp, $poziom)
{
// ...
}
Wykorzystaj wzór:
$xpNaPoczatkuPoziomu = ($poziom - 1) * XP_NA_POZIOM;
$xpWAktualnymPoziomie = $xp - $xpNaPoczatkuPoziomu;
Zwróć:
return $xpWAktualnymPoziomie;
7. Funkcja obliczająca procent
Utwórz:
function obliczProcentPostepu($xpWAktualnymPoziomie)
{
return ($xpWAktualnymPoziomie / XP_NA_POZIOM) * 100;
}
W kodzie głównym:
$xpWAktualnymPoziomie =
obliczXpWAktualnymPoziomie($xp, $poziom);
$procentPostepu =
obliczProcentPostepu($xpWAktualnymPoziomie);
8. Zadanie samodzielne — ile XP brakuje?
Napisz funkcję:
ileBrakujeXp()
która zwróci liczbę punktów potrzebnych do następnego poziomu.
Dla:
250 XP
poziom 3
powinna zwrócić:
50
Dla:
399 XP
poziom 4
powinna zwrócić:
1
HINT
Następny próg:
$poziom * XP_NA_POZIOM
9. Wersja z typami
Jeżeli korzystasz z PHP 8, zmień:
function obliczPoziom($xp)
na:
function obliczPoziom(int $xp): int
Podobnie możesz określić typy pozostałych funkcji.
Przetestuj:
obliczPoziom(250);
oraz:
obliczPoziom("abc");
Sprawdź różnicę.
10. Nie używamy global
Nie rozwiązuj dostępu do danych w taki sposób:
$xp = 250;
function obliczPoziom()
{
global $xp;
}
Przekazuj dane jako argument:
function obliczPoziom($xp)
{
// ...
}
Dzięki temu funkcja nie jest zależna od przypadkowej zmiennej znajdującej się gdzieś w programie.
11. PODSUMOWANIE ZMIAN
Poniżej zamieściłam elementy które należy usunąć i te, które dodaliśmy – pozostałe są bez zmian.
Dostosuj zmiany do swojego kodu
<?php
//usuwamy
~~$poziomStartowy = $poziom;~~
~~$liczbaAwansow = $poziom - $poziomStartowy;~~
~~if ($liczbaAwansow > 0){~~
~~echo "<p class=\"awans\">Awansowałeś o $liczbaAwansow poziomy!</p>";~~
~~}~~
//tworzymy funkcje
function obliczPoziom(int $xp) : int {
$poziom = 1;
while ($xp >= $poziom * XP_NA_POZIOM) {
$poziom++;
}
return $poziom;
}
$poziom = obliczPoziom($xp);
function pobierzTytul(int $poziom) : string {
return match ($poziom) {
1 => "Nowicjusz",
2 => "Wojownik",
default => "Mistrz"
};
}
$tytul = pobierzTytul($poziom);
function obliczXpWAktualnymPoziomie(int $xp, int $poziom) : int{
$xpNaPoczatkuPoziomu = ($poziom - 1) * XP_NA_POZIOM;
$xpWAktualnymPoziomie = $xp - $xpNaPoczatkuPoziomu;
return $xpWAktualnymPoziomie;
}
$xpWAktualnymPoziomie = obliczXpWAktualnymPoziomie($xp, $poziom);
function obliczProcentPostepu(int $xpWAktualnymPoziomie) : float {
return ($xpWAktualnymPoziomie / XP_NA_POZIOM) * 100;
}
$procentPostepu = obliczProcentPostepu($xpWAktualnymPoziomie);
function ileBrakujeXp(int $xp, int $poziom): int
{
$progNastepnegoPoziomu =
$poziom * XP_NA_POZIOM;
return $progNastepnegoPoziomu - $xp;
}
$brakujeXp = ileBrakujeXp($xp, $poziom);
CSS możesz dodać samodzielnie.
12. Testy
Sprawdź:
| XP | Poziom | XP w poziomie | Brakuje |
|---|---|---|---|
| 0 | 1 | 0 | 100 |
| 99 | 1 | 99 | 1 |
| 100 | 2 | 0 | 100 |
| 250 | 3 | 50 | 50 |
| 399 | 4 | 99 | 1 |
| 400 | 5 | 0 | 100 |
Do samodzielnego sprawdzenia
- Utworzyłem funkcję
obliczPoziom(). - Funkcja zwraca wynik przez
return. - Utworzyłem funkcję odpowiedzialną za tytuł.
- Obliczanie postępu znajduje się w funkcjach.
- Nie wykorzystuję
global. - Rozumiem różnicę pomiędzy
echoireturn. - Potrafię przekazać argument do funkcji.
- Przetestowałem funkcje dla kilku wartości XP.
Pytania kontrolne
- Po co tworzymy funkcje?
- Czym różni się
returnodecho? - Co oznacza argument funkcji?
- Co oznacza typ
intprzed argumentem? - Co oznacza
: intpo nawiasie funkcji? - Dlaczego nie powinniśmy bez potrzeby używać
global? - Co zwróci
obliczPoziom(550)? - Jaką zaletę daje nam teraz funkcja
obliczPoziom(), kiedy w przyszłości będziemy budować ranking?
PODSUMOWANIE LEKCJI
W skrócie
- Definicja to nie wykonanie. Kod wewnątrz
function nazwa() { ... }uruchamia się dopiero po wywołaniunazwa(). - Parametr to zmienna w definicji funkcji (
$xpwobliczPoziom($xp)), argument to wartość podana przy wywołaniu (obliczPoziom(250)). returnoddaje wynik i kończy funkcję. Kod zapisany poreturnsię nie wykona. Funkcja bezreturnzwracaNULL.echow funkcji tylko wyświetla – wyniku nie da się zapisać w zmiennej ani użyć w obliczeniach. W TaskQuest funkcje liczą i zwracają (return), a wyświetlanie zostaje w HTML.- Zmienne w funkcji są lokalne. Funkcja nie widzi zmiennych z głównego kodu i odwrotnie. Dane przekazujemy argumentami, nie przez
global. - Stałe z
define()są widoczne wszędzie – dlategoobliczPoziom()może korzystać zXP_NA_POZIOMbez przekazywania jej jako argumentu. - Parametry z wartością domyślną piszemy na końcu listy parametrów.
- Typy (
int $xp,: int) – bezstrict_typesPHP próbuje przekonwertować wartość ("250"→250), ale"abc"daTypeError.declare(strict_types=1);musi być pierwszą instrukcją pliku, inaczej skrypt zgłosi błąd krytyczny. static– zmienna pamięta wartość między kolejnymi wywołaniami funkcji.&(referencja) – funkcja zmienia oryginalną zmienną. Bez&pracuje na kopii.- Rekurencja bez warunku stopu nigdy się nie kończy (do przepełnienia stosu).
- Callback przekazany jako nazwa funkcji to tekst bez nawiasów:
'mojaWitajka', niemojaWitajka(). isset()iempty()to nie przeciwieństwa. Dla$x = 0obie zwracajątrue.
Co trzeba umieć na INF.03?
- odczytać z opisu funkcji (dokumentacji lub tabeli w arkuszu), jakie argumenty przyjmuje i co zwraca,
- zapisać wynik funkcji w zmiennej i wykorzystać go dalej (to jest praktyczna różnica między
returnaecho), - działanie
isset()– w arkuszu skrypt ma działać tylko wtedy, gdy dane zostały przesłane, albo użyć wartości domyślnej, gdy ich brak (formularze i$_GETpoznasz w lekcji 13), - napisać własną funkcję z parametrami i
returnoraz ją wywołać, - rozpoznawać podstawowe funkcje matematyczne (
round,ceil,floor,abs,sqrt,pow,max,min,rand) i przewidzieć ich wynik.
Minimum, które powinno wejść w pamięć
function nazwa($parametr) { return ...; }– definicja;$wynik = nazwa($argument);– wywołanie i zapisanie wyniku.returnzwraca wartość i kończy funkcję.echotylko wyświetla – funkcja z samymechozwracaNULL.- Zmienne z zewnątrz nie są widoczne w funkcji – przekazuj je jako argumenty. Stałe z
define()są widoczne. - Parametry z wartością domyślną zawsze na końcu.
int $x– typ parametru,: int– typ zwracanej wartości.- Funkcja rekurencyjna musi mieć warunek stopu.
isset($x)– czy zmienna istnieje i nie jestNULL;empty($x)– czy jest „pusta” (0,"","0",null,false,[]).round()– do najbliższej,ceil()– w górę,floor()– w dół (uwaga na liczby ujemne:floor(-3.14)to-4).
Ściągawka – najważniejsze polecenia i składnia
Własne funkcje
| Co | Składnia |
|---|---|
| definicja | function nazwa($a, $b) { ... } |
| zwrócenie wyniku | return $wynik; |
| wywołanie z zapisem wyniku | $x = nazwa(2, 3); |
| wartość domyślna | function powitanie($imie = "Gość") |
| typy | function f(int $a): int |
| brak zwracanej wartości | function rysuj(int $n): void |
typ z null | function f(?string $imie) |
| kilka typów (PHP 8) | function f(int\|float $liczba) |
| nazwane argumenty (PHP 8) | f(email: "a@b.pl", imie: "Jan") |
| dowolna liczba argumentów | function suma(...$liczby) |
| zmienna statyczna | static $licznik = 0; |
| referencja | function f(&$x) |
| ścisłe typy | declare(strict_types=1); – pierwsza linia pliku |
Funkcje anonimowe i callback
$kwadrat = function($x) { return $x ** 2; };
$kwadrat = fn($x) => $x ** 2; // funkcja strzałkowa
array_map(fn($x) => $x * 2, $liczby); // callback jako funkcja strzałkowa
uruchomCallback('mojaWitajka'); // callback jako nazwa – bez ()
Schemat rekurencji
function f(int $n): int {
if (/* warunek stopu */) {
return /* wartość bazowa */;
}
return /* ... */ f($n - 1);
}
Funkcje wbudowane – zmienne
| Funkcja | Zwraca |
|---|---|
isset($x) | true, gdy zmienna istnieje i nie jest NULL |
empty($x) | true, gdy wartość jest „pusta” |
is_null($x) | true, gdy NULL |
is_numeric($x) | true dla liczby lub tekstu liczbowego ("42") |
gettype($x) / get_debug_type($x) | nazwę typu |
unset($x) | usuwa zmienną |
(int)$x, (string)$x | rzutowanie (zalecane zamiast settype) |
Funkcje wbudowane – matematyka
| Funkcja | Przykład | Wynik |
|---|---|---|
round($x, $miejsca) | round(1.95583, 2) | 1.96 |
ceil($x) | ceil(4.3) | 5 |
floor($x) | floor(4.3) | 4 |
abs($x) | abs(-5) | 5 |
sqrt($x) | sqrt(9) | 3 |
pow($a, $b) / ** | 2 ** 3 | 8 |
max(), min() | max(1, 7, 3) | 7 |
rand($min, $max) | rand(1, 6) | liczba 1–6 |
random_int($min, $max) | random_int(1, 100) | bezpieczna liczba losowa |
pi() / M_PI | 3.1415926535898 | |
decbin(), bindec(), dechex(), hexdec() | decbin(12) | 1100 |
Quiz – sprawdź się
1. Co zostanie wyświetlone?
function podwoj($x) {
echo $x * 2;
}
$wynik = podwoj(4);
var_dump($wynik);
2. Znajdź błąd. Co faktycznie wyświetli ten kod?
function pole($a, $b) {
$wynik = $a * $b;
}
echo "Pole: " . pole(3, 4);
3. Dlaczego ten kod nie wyświetla 150? Jak go poprawić bez użycia global?
$bonus = 50;
function dodajBonus($xp) {
return $xp + $bonus;
}
echo dodajBonus(100);
Dodatkowe pytanie: dlaczego obliczPoziom() w TaskQuest może używać XP_NA_POZIOM, a dodajBonus() nie widzi $bonus?
4. Która definicja jest poprawna? Dlaczego?
// A
function nagroda($xp = 10, $zadanie) { }
// B
function nagroda($zadanie, $xp = 10) { }
5. Co zostanie wyświetlone?
function mnoz($a, $b = 2) {
return $a * $b;
}
echo mnoz(3) . " " . mnoz(3, 3);
6. Co zostanie wyświetlone?
function licznik() {
static $n = 0;
$n += 2;
return $n;
}
echo licznik();
echo licznik();
echo licznik();
7. Co wyświetlą oba fragmenty?
// A
function dodaj10($x) { $x = $x + 10; }
$liczba = 5;
dodaj10($liczba);
echo $liczba;
// B
function dodaj10(&$x) { $x = $x + 10; }
$liczba = 5;
dodaj10($liczba);
echo $liczba;
8. Plik NIE zawiera declare(strict_types=1);. Co się stanie w każdym przypadku?
function dodajJeden(int $x): int {
return $x + 1;
}
a) echo dodajJeden(5);
b) echo dodajJeden("5");
c) echo dodajJeden("abc");
d) Co zmieni się w przypadku b), jeśli na początku pliku dodamy declare(strict_types=1);?
9. Uzupełnij warunek stopu. Funkcja ma obliczać 2 do potęgi $n. Jaki wynik da potegaDwojki(4)?
function potegaDwojki(int $n): int {
if (__________) {
return 1;
}
return 2 * potegaDwojki($n - 1);
}
10. Uzupełnij kod tak, aby do każdego wyniku dodać 10 punktów bonusu. Co wyświetli print_r?
$wyniki = [1, 2, 3];
$poBonusie = array_map(__________, $wyniki);
print_r($poBonusie);
11. Co zwrócą poniższe wywołania (true / false)?
$x = 0;
var_dump(isset($x));
var_dump(empty($x));
var_dump(isset($nieIstnieje));
var_dump(empty("0"));
12. Podaj wynik każdej funkcji.
echo round(3.14159, 2);
echo ceil(-3.5);
echo floor(-3.5);
echo abs(-7);
13. Zadanie praktyczne – TaskQuest.
Napisz funkcję czyNowyPoziom(int $xpPrzed, int $xpPo): bool, która zwraca true, jeżeli po zdobyciu XP użytkownik ma wyższy poziom niż wcześniej. Nie kopiuj pętli while – wykorzystaj istniejącą funkcję obliczPoziom().
Przypadki testowe:
$xpPrzed | $xpPo | Oczekiwany wynik |
|---|---|---|
| 90 | 120 | true |
| 120 | 150 | false |
| 50 | 450 | true |
Odpowiedzi
8NULL– funkcja wyświetla8, ale nic nie zwraca, więc$wynikma wartośćNULL.- Brakuje
return $wynik;. Kod wyświetli tylkoPole:, bo funkcja zwracaNULL. $bonusjest zmienną spoza funkcji, więc wewnątrz jest niezdefiniowana. PHP zgłosi ostrzeżenie Undefined variable $bonus i wyświetli100. Poprawka:function dodajBonus($xp, $bonus) { return $xp + $bonus; }i wywołaniedodajBonus(100, $bonus). Stałe utworzone przezdefine()są widoczne w całym skrypcie, także w funkcjach – zmienne nie.- B. Parametry z wartością domyślną muszą być na końcu. W wersji A nie da się pominąć
$xpprzy wywołaniu, więc wartość domyślna nie ma sensu (PHP 8 zgłasza ostrzeżenie Deprecated). 6 9246– zmiennastaticzachowuje wartość między wywołaniami.- A:
5(funkcja pracuje na kopii). B:15(referencja&zmienia oryginał). - a)
6; b)6– tekst"5"zostaje przekonwertowany na liczbę; c)TypeError–"abc"nie da się zamienić naint; d)TypeError– w trybie ścisłym string nie jest akceptowany jakoint. $n == 0(lub$n <= 0).potegaDwojki(4)zwraca16.fn($x) => $x + 10(lubfunction($x) { return $x + 10; }). Wynik:Array ( [0] => 11 [1] => 12 [2] => 13 ).true,true,false,true.3.14,-3,-4,7(ceilzaokrągla w górę, czyli w stronę większej liczby: -3 > -3.5).- Przykładowe rozwiązanie:
function czyNowyPoziom(int $xpPrzed, int $xpPo): bool {
return obliczPoziom($xpPo) > obliczPoziom($xpPrzed);
}
Najważniejsze: funkcja korzysta z obliczPoziom() zamiast powtarzać pętlę while – dokładnie po to w tej lekcji przenieśliśmy logikę do funkcji.