6. PHP – funkcje – definiowanie własnych funkcji oraz zwracanie wartości przez funkcje. Funkcje wbudowane.


Funkcje

TaskQuest

Dodatek

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
  1. 3 6 9 – continue pomija liczby niepodzielne przez 3.
  2. Jeden raz, wyświetli 5. do...while sprawdza warunek dopiero po wykonaniu. Zwykły while nie wykona się ani razu i nic nie wyświetli.
  3. $prog jest obliczony raz przed pętlą (100) i się nie zmienia. Warunek 250 >= 100 jest zawsze prawdziwy – pętla nieskończona. Próg trzeba liczyć w warunku: while ($xp >= $poziom * XP_NA_POZIOM).
  4. a) for (znana liczba powtórzeń), b) while (nieznana liczba powtórzeń, warunek przed), c) foreach, d) do...while.
  5. 00 10 20 – break przerywa tylko wewnętrzną pętlę, zewnętrzna działa dalej.
  6. foreach ($oceny as $imie => $ocena)
  7. Pętla for musi być zamknięta przez endfor;, a nie endforeach;.

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: camelCase lub snake_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:

  1. 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.
  2. 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.
  3. 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)
  4. Napisz funkcję obliczającą cenę brutto dla podanej ceny netto i stawki vat. Wyświetl: cena netto, wartość vat, cena brutto.
  5. Napisz funkcję showName wyświetlającą imię przekazane do niej jako argument.
  6. Napisz funkcję o nazwie checkNumber, która zwraca prawdę (true), jeżeli przekazany argument jest mniejszy od zera.
  7. Przygotuj funkcję, która jako argument przyjmuje liczbę i zwraca prawdę, jeśli liczba jest podzielna przez 5 i 7.
  8. 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
  9. Napisz funkcję rekurencyjną i zwykłą obliczający silnię dowolnej liczby.
  10. Napisz skrypt z użyciem pętli for wyświetlający:
    *
    **
    ***
    ****
    *****
  11. Napisz skrypt z użyciem pętli for wyświetlający:
    *
    **
    ***
    ****
    *****
    ****
    ***
    **
    *

  12. Napisz funkcję obliczającą pole trójkąta równobocznego.
  13. Napisz funkcję iloczyn zwracającą iloczyn dwóch liczb przekazanych jako argumenty.
  14. Napisz funkcję o nazwie czyUjemna, która zwraca prawdę (true), jeżeli przekazany argument jest mniejszy od zera.
  15. Napisz funkcję, która jako argument przyjmuje liczbę i zwraca prawdę, jeśli liczba jest podzielna przez 3 i 5.
  16. 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ę!!!”
  17. Napisz funkcję zwracającą średnią arytmetyczną liczb przekazanych jako tablica do funkcji.
  18. Napisz funkcję pobierającą dwa argumenty: kolor w formie heksadecymalnej oraz napis. Funkcja ma
    umieszczać na stronie napis w kolorze przekazanym jako argument.
  19. 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:

  1. otrzymać liczbę XP,
  2. rozpocząć liczenie od poziomu 1,
  3. za pomocą while obliczyć poziom,
  4. 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 $wynik1 nie 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ź:

XPPoziomXP w poziomieBrakuje
010100
991991
10020100
25035050
3994991
40050100

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 echo i return.
  • Potrafię przekazać argument do funkcji.
  • Przetestowałem funkcje dla kilku wartości XP.

Pytania kontrolne

  1. Po co tworzymy funkcje?
  2. Czym różni się return od echo?
  3. Co oznacza argument funkcji?
  4. Co oznacza typ int przed argumentem?
  5. Co oznacza : int po nawiasie funkcji?
  6. Dlaczego nie powinniśmy bez potrzeby używać global?
  7. Co zwróci obliczPoziom(550)?
  8. 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łaniu nazwa().
  • Parametr to zmienna w definicji funkcji ($xp w obliczPoziom($xp)), argument to wartość podana przy wywołaniu (obliczPoziom(250)).
  • return oddaje wynik i kończy funkcję. Kod zapisany po return się nie wykona. Funkcja bez return zwraca NULL.
  • echo w 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 – dlatego obliczPoziom() może korzystać z XP_NA_POZIOM bez przekazywania jej jako argumentu.
  • Parametry z wartością domyślną piszemy na końcu listy parametrów.
  • Typy (int $xp, : int) – bez strict_types PHP próbuje przekonwertować wartość ("250" → 250), ale "abc" da TypeError. 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', nie mojaWitajka().
  • isset() i empty() to nie przeciwieństwa. Dla $x = 0 obie 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 return a echo),
  • 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 $_GET poznasz w lekcji 13),
  • napisać własną funkcję z parametrami i return oraz 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ęć

  1. function nazwa($parametr) { return ...; } – definicja; $wynik = nazwa($argument); – wywołanie i zapisanie wyniku.
  2. return zwraca wartość i kończy funkcję. echo tylko wyświetla – funkcja z samym echo zwraca NULL.
  3. Zmienne z zewnątrz nie są widoczne w funkcji – przekazuj je jako argumenty. Stałe z define() są widoczne.
  4. Parametry z wartością domyślną zawsze na końcu.
  5. int $x – typ parametru, : int – typ zwracanej wartości.
  6. Funkcja rekurencyjna musi mieć warunek stopu.
  7. isset($x) – czy zmienna istnieje i nie jest NULL; empty($x) – czy jest „pusta” (0, "", "0", null, false, []).
  8. 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

CoSkładnia
definicjafunction nazwa($a, $b) { ... }
zwrócenie wynikureturn $wynik;
wywołanie z zapisem wyniku$x = nazwa(2, 3);
wartość domyślnafunction powitanie($imie = "Gość")
typyfunction f(int $a): int
brak zwracanej wartościfunction rysuj(int $n): void
typ z nullfunction 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ówfunction suma(...$liczby)
zmienna statycznastatic $licznik = 0;
referencjafunction f(&$x)
ścisłe typydeclare(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

FunkcjaZwraca
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)$xrzutowanie (zalecane zamiast settype)

Funkcje wbudowane – matematyka

FunkcjaPrzykładWynik
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 ** 38
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$xpPoOczekiwany wynik
90120true
120150false
50450true

Odpowiedzi
  1. 8NULL – funkcja wyświetla 8, ale nic nie zwraca, więc $wynik ma wartość NULL.
  2. Brakuje return $wynik;. Kod wyświetli tylko Pole: , bo funkcja zwraca NULL.
  3. $bonus jest zmienną spoza funkcji, więc wewnątrz jest niezdefiniowana. PHP zgłosi ostrzeżenie Undefined variable $bonus i wyświetli 100. Poprawka: function dodajBonus($xp, $bonus) { return $xp + $bonus; } i wywołanie dodajBonus(100, $bonus). Stałe utworzone przez define() są widoczne w całym skrypcie, także w funkcjach – zmienne nie.
  4. B. Parametry z wartością domyślną muszą być na końcu. W wersji A nie da się pominąć $xp przy wywołaniu, więc wartość domyślna nie ma sensu (PHP 8 zgłasza ostrzeżenie Deprecated).
  5. 6 9
  6. 246 – zmienna static zachowuje wartość między wywołaniami.
  7. A: 5 (funkcja pracuje na kopii). B: 15 (referencja & zmienia oryginał).
  8. a) 6; b) 6 – tekst "5" zostaje przekonwertowany na liczbę; c) TypeError – "abc" nie da się zamienić na int; d) TypeError – w trybie ścisłym string nie jest akceptowany jako int.
  9. $n == 0 (lub $n <= 0). potegaDwojki(4) zwraca 16.
  10. fn($x) => $x + 10 (lub function($x) { return $x + 10; }). Wynik: Array ( [0] => 11 [1] => 12 [2] => 13 ).
  11. true, true, false, true.
  12. 3.14, -3, -4, 7 (ceil zaokrągla w górę, czyli w stronę większej liczby: -3 > -3.5).
  13. 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.