Spis zagadnień:
Łańcuchy znaków
Łańcuch znaków (ciąg), to typ danych reprezentujący tekst, które możemy formatować za pomocą wielu funkcji wbudowanych języka PHP.
Pełną listę funkcji znajdziecie w dokumentacji PHP, poniżej najczęściej wykorzystywane.
Sposoby definiowania stringów:
// Podwójne cudzysłowy - interpretują zmienne i znaki specjalne
$imie = "Jan";
echo "Witaj, $imie!"; // Witaj, Jan!
echo "Nowa linia\n"; // \n zostanie zamienione na nowy wiersz
// Pojedyncze cudzysłowy - literalnie, bez interpretacji
echo 'Witaj, $imie!'; // Witaj, $imie!
echo 'Nowa linia\n'; // Nowa linia\n (dosłownie)
// Heredoc (jak podwójne cudzysłowy)
$tekst = <<<EOT
To jest wieloliniowy
tekst z interpretacją $imie
EOT;
// Nowdoc - PHP 5.3+ (jak pojedyncze cudzysłowy)
$tekst = <<<'EOT'
To jest wieloliniowy
tekst bez interpretacji $imie
EOT;
echo/print
Wyświetlanie treści na ekranie.
Różnice:
echo– szybsze, może przyjąć wiele argumentów, nie zwraca wartościprint– wolniejsze, jeden argument, zwraca 1
<?php
echo "Hello World!"; // wyświetli napis: Hello World!
print "Hello World!"; // alternatywne wyświetlanie: Hello World!
echo "<br>"; //w ten sposób dodajemy wyświetlanie nowej linii
//wyświetlanie wielu linii
echo "Ten zapis obejmuje wiele linii.
Będą one wyświetlane, ale w jednej linii.
Nie zostanie automatycznie dodany znacznik nowego wiersza.";
echo "<br>Ten zapis również obejmuje wiele linii.<br>
Będą one wyświetlane, w wielu liniach,<br>
przez dodanie znacznika nowego wiersza.";
echo "<br>";
//wyświetlanie znaków specjalnych tj. "" musimy poprzedzić backslash'em
echo "Jeżeli chcemy wyświetlić cudzysłów \"Przykład\".";
echo "<br>";
// Wyświetlanie zawartości zmiennych
$zmienna1 = "wartość zmiennej 1";
$zmienna2 = "wartość zmiennej 2";
echo "zmienna1 = $zmienna1, a zmienna2 = $zmienna2"; // foo is foobar
echo "<br>";
// używając apostrofu wyświetlamy dokładnie to co znajduje się pomiędzy apostrofami (nie pobiera zawartości zmiennej)
echo 'wartość zmiennej 1 znajduje się w $zmienna1'; // wartość zmiennej 1 znajduje się w $zmienna1
echo "<br>";
// jeżeli wyświetlamy samą zmienną nie musimy używać cudzysłowów, ani apostrofów
echo $zmienna1; // wartość zmiennej 1
echo "<br>";
//łączenie wielu elementów do wyświetlenia
echo $zmienna1.$zmienna2."<br>"; // za pomocą kropki dołączamy kolejne zmienne
echo $zmienna1,$zmienna2."<br>"; // przecinek działa podobnie, nie jest używany - stosujemy kropkę
// Some people prefer passing multiple parameters to echo over concatenation.
echo 'Można ', 'łączyć ', 'wiele ', 'elementów ', ' oraz dodawać zmienne ', $zmienna1, '<br>';
echo 'Można '. 'łączyć '. 'wiele '. 'elementów '. ' oraz dodawać zmienne '. $zmienna1. '<br>';
//alternatywna metoda wyświetlania. Działa pod warunkiem, iż łańcuch rozpocznie się i zakończy tym samym słowem, w tym wypadku END. Nie jest to jednak metoda często spotykana.
echo <<<END
Ten tekst może być wielolinijkowy w wedytorze.
Niestety w przeglądarce zostanie wyświetlony w jednej linii.
END;
echo "<br>";
// wyświetlanie tablicowe
$tablica = ["indeks" => "wartość"];
echo "wartość dla indeksu = {$tablica['indeks']} !"; // wyświetli: wartość dla indeksu = wartość !
echo "<br>";
// wyświetlanie z warunkiem jeżeli (warunek) ? 'wartość gdy prawda' : 'wartość gdy fałsz'
echo ($zmienna1) ? 'true' : 'false';
?>
//Krótka składnia w HTML (short echo tag)
<p>użycie PHP w HTML <?php echo $zmienna1; ?></p>
<p>użycie PHP w HTML w skróconej formie <?=$zmienna1;?></p>
addslashes()/stripslashes()
Funkcja addslashes() dodaje backslash \ do ciągu znaków zawsze wtedy, gdy natrafi na tzw. „znak ucieczki”.
<?php $text = "Muszę zapisać znak ', czyli apostrof."; echo addslashes($text); //zostanie wyświetlone: Muszę zapisać znak \', czyli apostrof. ?>
Funkcja stripslashes() usuwa backslash
<?php $text = "Muszę odczytać z bazy znak \', czyli usunąć backslash."; echo stripslashes($text); //zostanie wyświetlone: Muszę zapisać znak ', czyli usunąć backslash. ?>
explode() / implode() / join()
PHP umożliwia zamianę ciągów tekstowych na tablice i odwrotnie. Zamiana ciągu na tablicę jest bardzo przydatna jeśli zachodzi potrzeba „wyciągnięcia” jakiegoś fragmentu danych z ciągu. Załóżmy że w odczytaliśmy z pliku z danymi (o odczycie z plików w jednym z kolejnych rozdziałów) linię z logu zapisanego przez licznik WWW: „12/11/2000;19:23:33;Netscape Navigator;192.168.1.1”. Jak widać dane rozdzielone są średnikami. Do rozdzielania ciągów na tablicę służy funkcja explode(). Jako pierwszy parametr trzeba do niej podać znak lub dłuższy ciąg który oddziela kolejne pola, jako drugi ciąg do rozdzielenia. Opcjonalnie można podać trzeci argument, który oznacza maksymalną liczbę pól – jeśli jest ich więcej niż ta liczba, to ostatnie pole będzie zawierało wszystkie pozostałe pola. Funkcja zwraca tablicę zawierającą kolejne pola.
Przykładowo:
<?php
$dane = "alfa;beta;gamma;delta";
$tablica = explode(";", $dane);
print_r($tablica);
// Array([0] => alfa, [1] => beta, [2] => gamma, [3] => delta)
// Z limitem
$tablica = explode(";", $dane, 2);
print_r($tablica);
// Array([0] => alfa, [1] => beta;gamma;delta)
// Praktyczny przykład - parsowanie CSV
$csv = "Jan,Kowalski,30,Warszawa";
list($imie, $nazwisko, $wiek, $miasto) = explode(",", $csv);
echo "Imię: $imie, Nazwisko: $nazwisko";
?>
Czasem potrzebne jest działanie pozwalające na złącznie pól tablicy w jeden ciąg, w którym pola oddzielone są jakimś znakiem (lub kilkoma). Do tego służy funkcja implode() i join(). Jako pierwszy parametr podawany jest ciąg za pomocą którego „sklejane” są elementy tablicy, a jako drugi właśnie tablica do posklejania. Zwracany jest ciąg zawierający „posklejane” elementy. Przykład zastosowania:
<?php
$tablica = ['alfa', 'beta', 'gamma'];
$dane = implode(";", $tablica);
echo $dane; // alfa;beta;gamma
// Praktyczny przykład - tworzenie listy
$owoce = ['jabłko', 'gruszka', 'banan'];
echo "Mamy: " . implode(", ", $owoce); // Mamy: jabłko, gruszka, banan
// join() to alias implode() - możesz używać obu
$dane = join(";", $tablica);
?>
str_split()
Dzieli string na tablicę znaków lub fragmentów.
array str_split(string $string [, int $length = 1])
<?php
$str = "Hello Friend";
// Podział na pojedyncze znaki
$arr1 = str_split($str);
print_r($arr1);
// Array([0] => H, [1] => e, [2] => l, [3] => l, [4] => o, ...)
// Podział na fragmenty długości 3
$arr2 = str_split($str, 3);
print_r($arr2);
// Array([0] => Hel, [1] => lo , [2] => Fri, [3] => end)
// Praktyczny przykład - podział numeru karty
$karta = "1234567890123456";
$chunked = str_split($karta, 4);
echo implode("-", $chunked); // 1234-5678-9012-3456
?>
htmlspecialchars()/strip_tags()
Zabezpieczanie przed XSS (Cross-Site Scripting).
<?php
$niebezpieczny = '<script>alert("XSS")</script>';
echo htmlspecialchars($niebezpieczny);
// <script>alert("XSS")</script>
// Praktyczny przykład - wyświetlanie inputa użytkownika
$komentarz = $_POST['komentarz'] ?? '';
echo htmlspecialchars($komentarz, ENT_QUOTES, 'UTF-8');
?>
htmlspecialchars() – koduje znaki specjalne HTML:
- & → &
- ” → "
- ’ → ' (lub ')
- < → <
- > → >
Flagi:
ENT_QUOTES // Koduj i podwójne, i pojedyncze cudzysłowy
ENT_NOQUOTES // Nie koduj cudzysłowów
ENT_SUBSTITUTE // Zastąp nieprawidłowe sekwencje znakiem �
ENT_HTML5 // Obsługa HTML5
strip_tags() – usuwa tagi HTML/PHP:
$html = '<p>Cześć <b>świecie</b>!</p>';
echo strip_tags($html); // Cześć świecie!
// Dozwolone tagi
echo strip_tags($html, '<b>'); // Cześć <b>świecie</b>!
// PHP 7.4+ - tablica dozwolonych tagów
echo strip_tags($html, ['p', 'b']); // <p>Cześć <b>świecie</b>!</p>
Bezpieczeństwo:
// ŹLE - strip_tags nie chroni przed XSS!
$input = '<img src=x onerror=alert("XSS")>';
echo strip_tags($input); // Może wykonać JavaScript!
// DOBRZE - używaj htmlspecialchars
echo htmlspecialchars($input);
nl2br()
Funkcja zamienia wszystkie znaki \n na znacznik HTML <br />
<?php
$tekst = "Linia 1\nLinia 2\nLinia 3";
echo nl2br($tekst);
// Linia 1<br />
// Linia 2<br />
// Linia 3
// HTML5 (bez XHTML)
echo nl2br($tekst, false);
// Linia 1<br>
// Linia 2<br>
// Linia 3
?>
password_hash() / password_verify()
password_hash() – hashuje hasło:
Bezpieczne hashowanie haseł
<?php
// Podstawowe użycie (zalecane)
$haslo = 'moje_super_haslo';
$hash = password_hash($haslo, PASSWORD_DEFAULT);
echo $hash;
// $2y$10$... (hash bcrypt)
// PHP 7.4+ - Argon2
$hash = password_hash($haslo, PASSWORD_ARGON2ID);
// Własne ustawienia (opcjonalne)
$opcje = ['cost' => 12]; // wyższy cost = wolniejsze, bezpieczniejsze
$hash = password_hash($haslo, PASSWORD_BCRYPT, $opcje);
?>
password_verify()
Jest to funkcja sprawdzająca czy zahashowane hasła zgadzają się z podanymi.
<?php
$haslo = 'moje_super_haslo';
$hash = '$2y$10$...'; // hash z bazy danych
if (password_verify($haslo, $hash)) {
echo "Hasło poprawne!";
} else {
echo "Błędne hasło!";
}
?>
strlen() / mb_strlen()
Zwraca długość stringa (liczbę bajtów).
<?php
$str = 'abcdef';
echo strlen($str); // 6
$str = ' ab cd ';
echo strlen($str); // 7
// Uwaga na polskie znaki (UTF-8)
$str = 'ąćęł';
echo strlen($str); // 8 (2 bajty na znak w UTF-8!)
// Dla znaków Unicode - użyj mb_strlen()
echo mb_strlen($str, 'UTF-8'); // 4 (poprawna liczba znaków)
// Dla stringów z polskimi znakami
$tekst = "Zażółć gęślą jaźń";
echo mb_strlen($tekst, 'UTF-8'); // 17 znaków
?>
strpos() / mb_strpos()
Zwraca numeryczną pozycję pierwszego wystąpienia szukanego znaku w ciągu. Jako trzeci parametr, można ustawić numer znaku, od którego funkcja ma zacząć przeszukiwać.
strpos(string,find[,start])
<?php
$tekst = "I love PHP, I love PHP too!";
// Pierwsze wystąpienie
echo strpos($tekst, "PHP"); // 7
// Od określonej pozycji
echo strpos($tekst, "PHP", 8); // 19
// Nie znaleziono
var_dump(strpos($tekst, "Java")); // false
// Uwaga na pozycję 0!
if (strpos($tekst, "I") !== false) { // użyj !== zamiast !=
echo "Znaleziono!";
}
?>
str_contains(), str_starts_with(), str_ends_with()
// Sprawdza czy string zawiera podciąg
if (str_contains($tekst, "PHP")) {
echo "Zawiera PHP";
}
// Sprawdza czy zaczyna się od
if (str_starts_with($tekst, "I love")) {
echo "Zaczyna się od 'I love'";
}
// Sprawdza czy kończy się na
if (str_ends_with($tekst, "too!")) {
echo "Kończy się na 'too!'";
}
strtolower()/strtoupper()/ucfirst()/ucwords()
Funkcje odpowiedzialne za zmianę wielkości liter.
<?php
// strtolower() - wszystkie małe
$str = "Marysia Ma Małego Baranka";
echo strtolower($str); // marysia ma małego baranka
// strtoupper() - wszystkie wielkie
echo strtoupper($str); // MARYSIA MA MAŁEGO BARANKA
// ucfirst() - pierwsza litera wielka
echo ucfirst(strtolower($str)); // Marysia ma małego baranka
// ucwords() - każde słowo wielką literą
echo ucwords(strtolower($str)); // Marysia Ma Małego Baranka
// mb_strtolower() / mb_strtoupper() - dla polskich znaków
$polski = "ZAŻÓŁĆ GĘŚLĄ JAŹŃ";
echo mb_strtolower($polski, 'UTF-8'); // zażółć gęślą jaźń
echo mb_strtoupper("zażółć", 'UTF-8'); // ZAŻÓŁĆ
?>
str_replace() / str_ireplace()
Zamienia wszystkie wystąpienia podciągu.. Budowa:
str_replace(znajdź, zastąp, string[, $jakaś_nazwa]), gdzie do opcjonalnej zmiennej $jakaś_nazwa zostanie wpisana ilość zmian jakich dokona funkcja
<?php
// Podstawowe użycie
$tekst = "Jeśli jesteś za, podnieś rękę";
$wynik = str_replace("za", "przeciw", $tekst);
echo $wynik; // Jeśli jesteś przeciw, podnieś rękę
// Licznik zamian
$wynik = str_replace("za", "przeciw", $tekst, $count);
echo "Zmieniono: $count"; // Zmieniono: 1
// Wiele zamian naraz
$tekst = "czerwony niebieski czerwony";
$wynik = str_replace(
["czerwony", "niebieski"],
["różowy", "zielony"],
$tekst
);
echo $wynik; // różowy zielony różowy
// Operacje na tablicach
$arr = ["blue", "red", "blue", "yellow"];
print_r(str_replace("blue", "pink", $arr));
// Array([0] => pink, [1] => red, [2] => pink, [3] => yellow)
?>
str_ireplace() – zamiana bez względu na wielkość liter:
$tekst = "PHP php Php pHP";
echo str_ireplace("php", "JavaScript", $tekst);
// JavaScript JavaScript JavaScript JavaScript
substr()
Funkcja substr() wycina fragment ciągu wg podanych parametrów. Budowa:
substr(string, początek[, długość])
jeżeli:
początek>0 – wycinanie zacznie się od znaku o podanym numerze
początek<0 – wycinanie zacznie się od miejsca = długość-początek
długość>0 – wycinanie zacznie się od podanej cyfry określającej początek do początek+długość
długość<0 – wycinanie zakończy się o podaną liczbę znaków przed końcem
<?php
echo substr("abcdef", -1); // zwraca "f"
echo substr("abcdef", -2); // zwraca "ef"
echo substr("abcdef", -3, 1); // zwraca "d"
echo substr("abcdef", 0, -1); // zwraca "abcde"
echo substr("abcdef", 2, -1); // zwraca "cde"
echo substr("abcdef", 4, -4); // zwraca false
echo substr("abcdef", -3, -1); // zwraca "de"
echo substr('abcdef', 1); // bcdef
echo substr('abcdef', 1, 3); // bcd
echo substr('abcdef', 0, 4); // abcd
echo substr('abcdef', 0, 8); // abcdef
echo substr('abcdef', -1, 1); // f
//metoda zapisu dla tablic
$string = 'abcdef';
echo $string[0]; // a
echo $string[3]; // d
echo $string[strlen($string)-1]; // f
//mb_substr() - dla znaków Unicode:
$polski = "Zażółć gęślą jaźń";
echo mb_substr($polski, 0, 6, 'UTF-8'); // Zażółć
// Praktyczny przykład - skrócenie tekstu
function skroc($tekst, $dlugosc = 100) {
if (strlen($tekst) <= $dlugosc) {
return $tekst;
}
return substr($tekst, 0, $dlugosc) . '...';
}
echo skroc("Bardzo długi tekst, który chcemy skrócić", 20);
// Bardzo długi tekst, ...
?>
substr_replace()
Funkcja substr_replace() zastępuje fragment łańcucha innym, określonym przez użytkownika. Budowa: substr_replace(string,zamiennik,początek[,długość])
jeżeli:
początek>0 – zastępowanie zacznie się od znaku o podanym numerze
początek<0 – zastępowanie zacznie się od miejsca = długość-początek
długość>0 – tyle znaków ciągu zostanie zmienione od początku
długość<0 – zastępowanie zakończy się o podaną liczbę znaków przed końcem
<?php
$var = 'ABCDEFGH:/MNRPQR/';
echo "Orginalny tekst: $var<hr />\n";
/* poniższe przykłady zamieniają całe $var na 'bob'. */
echo substr_replace($var, 'bob', 0) . "<br />\n";
echo substr_replace($var, 'bob', 0, strlen($var)) . "<br />\n";
/* Dołącza napis 'bob' przed zmienną $var. */
echo substr_replace($var, 'bob', 0, 0) . "<br />\n";
/* Zastępuje napis 'MNRPQR' w zmiennej $var napisem 'bob'. */
echo substr_replace($var, 'bob', 10, -1) . "<br />\n";
echo substr_replace($var, 'bob', -7, -1) . "<br />\n";
/* usuwa 'MNRPQR' z $var. */
echo substr_replace($var, '', 10, -1) . "<br />\n";
//operacje na tablicach
$input = array('A: XXX', 'B: XXX', 'C: XXX');
//zamienia XXX w każdym elemencie tablicy na YYY.
echo implode('; ', substr_replace($input, 'YYY', 3, 3))."\n";
// sytuacja kiedy każdy element tablicy jest inny
$replace = array('AAA', 'BBB', 'CCC');
echo implode('; ', substr_replace($input, $replace, 3, 3))."\n";
// sytuacja kiedy długości sa pobierane z tablicy.
$length = array(1, 2, 3);
echo implode('; ', substr_replace($input, $replace, 3, $length))."\n";
?>
strstr() / stristr() / strrchr()
strstr(string,find[,przed_czy_po])
Wyszukuje podane znaki w ciągu, po czym wyświetla to co jest za znakiem (trzeci argument domyślnie ustawiony jest na false). Jeżeli użyjemy trzeciego argumentu z wartością true to wyświetli ciąg znaków poprzedzający szukany element. Funkcja rozróżnia wielkość znaków.
<?php
$email = 'name@example.com';
// Zwróć fragment od znalezionego ciągu
$domain = strstr($email, '@');
echo $domain; // @example.com
// Zwróć fragment PRZED znalezionym ciągiem (PHP 5.3+)
$user = strstr($email, '@', true);
echo $user; // name
// stristr() - bez względu na wielkość liter
$tekst = "Hello World";
echo stristr($tekst, "WORLD"); // World
// strrchr() - ostatnie wystąpienie
$path = '/var/www/html/index.php';
$filename = strrchr($path, '/');
echo $filename; // /index.php
?>
strtr()
Zamienia podany ciąg znaków na inny. Budowa: strtr(string,from,to) lub strtr(string,array)
<?php
// Zamiana znaków (jeden na jeden)
echo strtr("Hilla Warld", "ia", "eo"); // Hello World
// Zamiana par (tablica asocjacyjna)
$trans = [
"hello" => "hi",
"world" => "earth"
];
echo strtr("Hello world", $trans); // Hi earth
// Praktyczny przykład - usuwanie polskich znaków
$polish = [
'ą' => 'a', 'ć' => 'c', 'ę' => 'e', 'ł' => 'l',
'ń' => 'n', 'ó' => 'o', 'ś' => 's', 'ź' => 'z', 'ż' => 'z',
'Ą' => 'A', 'Ć' => 'C', 'Ę' => 'E', 'Ł' => 'L',
'Ń' => 'N', 'Ó' => 'O', 'Ś' => 'S', 'Ź' => 'Z', 'Ż' => 'Z'
];
$tekst = "Zażółć gęślą jaźń";
echo strtr($tekst, $polish); // Zazolc gesla jazn
?>
trim() / ltrim() / rtrim()
Funkcja trim() usuwa następujące znaki z początku i końca ciągu: odstępy, tabulacje poziome (\t) i pionowe (\x0b), nowy wiersz (\n), NULL (\0), powrót karetki (\r). Budowa:
trim(string[, lista_znaków])
parametr lista_znaków pozwala na określenie niestandardowych znaków do usunięcia.
Domyślnie usuwane znaki:
– spacja\t– tabulator\n– nowa linia\r– powrót karetki\0– NULL\x0B– tabulator pionowy
<?php
$text = " \t\tTutaj jest tekst :) ... \n";
// trim() - z początku i końca
echo trim($text); // "Tutaj jest tekst :) ..."
// ltrim() - tylko z lewej (początku)
echo ltrim($text); // "Tutaj jest tekst :) ... \n"
// rtrim() - tylko z prawej (końca)
echo rtrim($text); // " \t\tTutaj jest tekst :) ..."
// Własne znaki do usunięcia
echo trim($text, " \t."); // "Tutaj jest tekst :) ...\n"
// Praktyczny przykład - czyszczenie inputu
$input = trim($_POST['username'] ?? '');
?>
Przykład:
Funkcja PHP tworząca przyjazne linki
function slugify(string $text): string {
// Transliteracja Unicode na ASCII
$text = transliterator_transliterate('Any-Latin; Latin-ASCII', $text);
$text = strtolower($text);
$text = preg_replace('/[^a-z0-9]+/', '-', $text);
$text = trim($text, '-');
return $text;
}
Przykład:
Kwota, liczba słownie PHP
<?php
if (!function_exists('str_split')) {
function str_split($string, $len = 1) {
if ($len < 1) return false;
$result = [];
for ($i = 0; $i < ceil(strlen($string) / $len); $i++) {
$result[$i] = substr($string, $len * $i, $len);
}
return $result;
}
}
$slowa = [
'minus',
['zero','jeden','dwa','trzy','cztery','pięć','sześć','siedem','osiem','dziewięć'], ['dziesięć','jedenaście','dwanaście','trzynaście','czternaście','piętnaście','szesnaście','siedemnaście','osiemnaście','dziewiętnaście'], ['dziesięć','dwadzieścia','trzydzieści','czterdzieści','pięćdziesiąt','sześćdziesiąt','siedemdziesiąt','osiemdziesiąt','dziewięćdziesiąt'],
['sto','dwieście','trzysta','czterysta','pięćset','sześćset','siedemset','osiemset','dziewięćset'],
['tysiąc','tysiące','tysięcy'],
['milion','miliony','milionów'],
['miliard','miliardy','miliardów'],
['bilion','biliony','bilionów'],
['biliard','biliardy','biliardów'],
['trylion','tryliony','trylionów'],
['tryliard','tryliardy','tryliardów'],
['kwadrylion','kwadryliony','kwadrylionów'],
['kwintylion','kwintyliony','kwintylionów'],
['sekstylion','sekstyliony','sekstylionów'],
['septylion','septyliony','septylionów'],
['oktylion','oktyliony','oktylionów'],
['nonylion','nonyliony','nonylionów'],
['decylion','decyliony','decylionów']
];
function odmiana($odmiany, $int) {
$txt = $odmiany[2];
if ($int == 1) {
$txt = $odmiany[0];
}
$jednosci = (int) substr($int, -1);
$reszta = $int % 100;
if (($jednosci > 1 && $jednosci < 5) && !($reszta > 10 && $reszta < 20)) {
$txt = $odmiany[1];
}
return $txt;
}
function liczba($int) {
global $slowa;
$wynik = '';
$j = abs((int) $int);
if ($j == 0) {
return $slowa[1][0];
}
$jednosci = $j % 10;
$dziesiatki = ($j % 100 - $jednosci) / 10;
$setki = ($j - $dziesiatki * 10 - $jednosci) / 100;
if ($setki > 0) {
$wynik .= $slowa[4][$setki - 1] . ' ';
}
if ($dziesiatki > 0) {
if ($dziesiatki == 1) {
$wynik .= $slowa[2][$jednosci] . ' ';
} else {
$wynik .= $slowa[3][$dziesiatki - 1] . ' ';
}
}
if ($jednosci > 0 && $dziesiatki != 1) {
$wynik .= $slowa[1][$jednosci] . ' ';
}
return $wynik;
}
function slownie($int) {
global $slowa;
$in = preg_replace('/[^-\d]+/', '', $int);
$out = '';
if ($in[0] == '-') {
$in = substr($in, 1);
$out = $slowa[0] . ' ';
}
$txt = str_split(strrev($in), 3);
if ($in == 0) {
$out = $slowa[1][0] . ' ';
}
for ($i = count($txt) - 1; $i >= 0; $i--) {
$liczba = (int) strrev($txt[$i]);
if ($liczba > 0) {
if ($i == 0) {
$out .= liczba($liczba) . ' ';
} else {
$out .= ($liczba > 1 ? liczba($liczba) . ' ' : '')
. odmiana($slowa[4 + $i], $liczba) . ' ';
}
}
}
return trim($out);
}
function kwotaslownie($kwota) {
$kwota = explode('.', $kwota);
$zl = preg_replace('/[^-\d]+/', '', $kwota[0]);
$gr = preg_replace('/[^\d]+/', '', substr($kwota[1] ?? '0', 0, 2));
while (strlen($gr) < 2) {
$gr .= '0';
}
echo slownie($zl) . ' ' . odmiana(['złoty', 'złote', 'złotych'], $zl)
. ((int)$gr == 0 ? '' :
' ' . slownie($gr) . ' ' . odmiana(['grosz', 'grosze', 'groszy'], $gr));
}
?>
ZADANIA:
Zadanie 1
Napisz funkcję zmieniającą wielkość liter w tekście na:
- wielkie litery
- małe litery
- każdy wyraz pisany wielką literą
- jak w zdaniu
Zadanie 2
Napisz funkcję sprawdzającą domenę podanego adresu e-mail.
Zadanie 3
Stwórz funkcję zamieniającą podany wyraz w tekście na inny.
Zadanie 4
Napisz skrypt szyfrujący hasło. Użyj password_hash() i password_verify().
Zadanie 5
W zdaniu „Jestem mistrzem” dokonaj zmian przy pomocy substr i substr_replace:
- Zamień „Jestem” na swoje imię
- Dodaj na końcu „PHP”
- Wyświetl tylko „mistrzem”
Wyrażenia regularne i funkcja preg_match()
Wyrażenie regularne (regex, regexp) to wzorzec służący do wyszukiwania i manipulowania tekstem.
preg_match()
funkcja, która sprawdza występowanie podanego wzorca w danym ciągu. Jest przydatna w przypadku walidacji formularzy np. gdy chcemy sprawdzić czy została podana cyfra i znak specjalny w haśle, albo czy mail został podany poprawnie. Jeżeli wyrażenie zostanie znalezione w ciągu, funkcja zwraca 1, w przeciwnym wypadku zwraca 0.
preg_match(string $pattern, string $subject [, array &$matches])
Zwraca:
1– dopasowano0– brak dopasowaniafalse– błąd
Znaki specjalne i metacharaktery
| Znak | Znaczenie | Przykład |
|---|---|---|
. |
Dowolny znak | /k.t/ → kot, kit, k1t |
^ |
Początek stringa | /^Kot/ → Kot na początku |
$ |
Koniec stringa | /kot$/ → kot na końcu |
\ |
Znak ucieczki | /\./ → dosłowna kropka |
| ` | ` | OR (lub) |
() |
Grupowanie | `/(kot |
[] |
Zbiór znaków | /[aeiou]/ → samogłoska |
[^] |
Negacja zbioru | /[^0-9]/ → NIE cyfra |
Ale jak się tworzy wyrażenia regularne…
/…/
Wyrażenie, którego szukamy musi znajdować się pomiędzy dwoma slash’ami.
preg_match('/kot/', 'Ala ma kota.');
wyrażenie /kot/ będzie pasowało do każdego ciągu, w którym znajda sie obok siebie litery k o t. Nie ma znaczenia, czy są wewnątrz ciągu, na początku, czy na końcu. Znaczenie ma wielkość liter!
Przyklad:
preg_match('/kot/', 'Ala ma kota.');
preg_match('/kot/', 'Ala ma kota na punkcie kotów.');
preg_match('/kot/', 'Kotka i małe koty.');
^ i $
Jeżeli chcemy określić, czy dane wyrażenie ma znajdować się na początku ciągu używamy ^, jeżeli ma byc na końcy – używamy $.
Przyklad:
preg_match('/^Kot/', 'Kot należy do Ali.');
preg_match('/^kot/', 'Ten kot jest czarny.');
preg_match('/kot$/', 'Oto kot');
preg_match('/kot$/', 'Oto kot.');
preg_match('/^kot$/', 'kot');
. (kropka)
Kropka służy do znalezienia dowolnego znaku w ciągu. Jedna kropka to jeden znak.
Przyklad:
preg_match('/k.t/', 'Ala ma kota.');
preg_match('/k.t/', 'Ten kotek ma czarną kitę.');
preg_match('/k.t/', 'Wypłynął kutrem.');
preg_match('/k..t/', 'karta');
Kropka jest znakiem specjalnym, więc jeżeli chcielibyśmy sprawdzić czy w ciągu występuje kropka to musimy poprzedzić ją \ (backslashem)
Przyklad:
preg_match('/\./', 'Ala ma kota.');
Znaki specjalne
Poza kropką istnieją inne znaki specjalne, które należy poprzedzić znakiem \ (backslash).
. \ / * + ? [ ^ $ | { ( )
Przyklad:
preg_match('/\?/', 'Ala ma kota?');
[…]
W nawiasach kwadratowych określamy zbiory znaków jakie chcemy wyszukać. Musi wystąpić dokładnie jeden znak, obojętnie który oraz obojętnie w jakiej kolejności.
Przyklad:
preg_match('/[jest]/', 'se');
preg_match('/[Ala]/', 'Ala ma kota');
Możemy zbiory znaków łączyć swobodnie ze zwykłymi znakami:
Przyklad:
preg_match('/ol[wer]/', 'wyrewolwerowane pole');
Zbiory znaków mają swoje zakresy:
- [a-z] – oznacza dowolną małą literę od a do z
- [^a-z] – negacja [a-z], nie może wystąpić żadna mała litera od a do z
- [A-Z] – oznacza dowolną wielką literę od A do Z
- [^A-Z] – negacja [A-Z], nie może wystąpić żadna duża litera od A do Z
- [0-9] lub \d– oznacza dowolną cyfrę
- [^0-9] lub \D– negacja [0-9], nie może wystąpić żadna cyfra
- \w – oznacza wszystkie litery, cyfry i podkreślnik – [a-zA-Z0-9_]
- \W – stanowi negację \w – [^a-zA-Z0-9_]
- \s – oznacza znaki specjalne – spację, \n, \r\ i \t
- \S – stanowi negację \s
zakresy możemy łączyć ze sobą
Przyklad:
preg_match('/[a-zA-Z0-9]/', 'Jakiś ciąg znaków: liter aąbcć, cyfr 123456 oraz znaków !@#$%');
aby zanegowac dany zbiór umieszczamy na jego początku ^
Przyklad:
preg_match('/abc[^a-z]/', 'abcdef'); //nie będzie dopasowania, bo po abc nie może wystąpić żadna mała litera preg_match('/abc[^a-z]/', 'abc123'); // poprawne dopasowanie, po abc nie wystepuje żadna mała litera
|, czyli OR
jeżeli chcemy sprawdzić, czy któryś z ciągów istnieje, używamy |. Oznacza on to samo co logiczne OR. Sprawdzana jest całość członu po lewej lub prawej stronie |.
Przyklad:
preg_match('/abc|123/', 'abc'); preg_match('/abc|123/', '123');
(), czyli grupowanie
działa tak jak w matematyce, gdy musimy pogrupować elementy do dopasowania. Wyrażenie wewnątrz nawiasów traktujemy jako całość.
Przyklad:
preg_match('/^Oh(Karol|Karolina)$)/', 'OhKarol');
*, +, ?, {}, czyli kwantyfikatory
jeżeli chcemy określić ile dopasowań w ciągu ma wystąpić, to używamy kwantyfikatorów.
- * (gwiazdka) oznacza zero lub więcej wystąpień
- + (plus) oznacza jedno lub więcej wystąpień
- ? (znak zapytania) oznacza zero lub jedno wystąpienie
- {n} oznacza dokładnie n wystąpień znaku lub zakresu przed nawiasem
- {n,} oznacza co najmniej n wystąpień znaku lub zakresu przed nawiasem
- {m, n} oznacza od m do n wystąpień znaku lub zakresu przed nawiasem
Przyklady:
//wyrażenie pasuje do wszystkich ciągów //* zero lub więcej wystąpień preg_match('/abc[A-Z]*/', 'abc'); preg_match('/abc[A-Z]*/', 'abcC'); preg_match('/abc[A-Z]*/', 'abcXY'); preg_match('/abc[A-Z]*/', 'abcABCDE'); //+ jedno lub więcej wystąpień preg_match('/abc[A-Z]+/', 'abcB'); preg_match('/abc[A-Z]+/', 'abcC'); preg_match('/abc[A-Z]+/', 'abcXY'); preg_match('/abc[A-Z]+/', 'abcABCDE'); //? zero lub jedno wystąpienie preg_match('/abc[A-Z]?/', 'abc'); preg_match('/abc[A-Z]?/', 'abcC'); preg_match('/abc[A-Z]?/', 'abcX'); preg_match('/abc[A-Z]?/', 'abcZ'); //od 1 do 3 wystąpień znaków z zakresu [A-Z] preg_match('/abc[A-Z]{1,3}/', 'abcA'); preg_match('/abc[A-Z]{1,3}/', 'abcAC'); preg_match('/abc[A-Z]{1,3}/', 'abcAHX'); //od 1 do 3 wystąpień znaku c preg_match('/abc{1,3}/', 'abcc'); preg_match('/abc{1,3}/', 'abccc'); preg_match('/abc{1,3}/', 'abcccc'); //co najmniej 3 wystąpienia znaków z zakresu [A-Z] preg_match('/abc[A-Z]{3,}/', 'abcABC'); preg_match('/abc[A-Z]{3,}/', 'abcACGH'); preg_match('/abc[A-Z]{3,}/', 'abcAHTUX'); //co najmniej 3 wystąpienia znaków z zakresu (abc) preg_match('/(abc){3,}/', 'abcabcabc');
Modyfikatory
Dodawane po zamykającym /:
i – Ignoruj wielkość liter
m – Multiline (^ i $ dla każdej linii)
s – Dotall (. dopasowuje też \n)
u – UTF-8
x –Ignoruj białe znaki w wzorcu
// i - case insensitive
preg_match('/kot/i', 'KOT'); // 1 ✓
// m - multiline
$tekst = "linia1\nlinia2";
preg_match('/^linia2$/m', $tekst); // 1 ✓
// u - UTF-8
preg_match('/\w+/u', 'zażółć'); // dopasuje polskie znaki
Przechwytywanie
Wynik działania funkcji preg_match() możemy umieścić w tablicy, aby tego dokonać musimy dołożyć naszej funkcji dodatkowe parametry mianowicie: $matches i PREG_OFFSET_CAPTURE
preg_match(wyrazenie_regularne, badany_ciag, $matches, PREG_OFFSET_CAPTURE);
Wyniki zostają wrzucone do tablicy, gdzie w indeksie zerowym znajduje się część ciągu od, której zaczęło się dopasowanie, a w indeksie od 1 do n znajdują się dopasowania.
preg_match('/(\d+)\D+(\d+)/', 'Mam 70zł, wystarczy mi to na zakup 2 książek.', $matches, PREG_OFFSET_CAPTURE);
wykonanie tego kodu spowoduje otrzymanie tablicy:
Array
(
[0] => Array
(
[0] => 70zł, wystarczy mi to na zakup 2
[1] => 4
)
[1] => Array
(
[0] => 70
[1] => 4
)
[2] => Array
(
[0] => 2
[1] => 36
)
)
pogrupowanie elementów za pomocą (), powoduje że przechwytywanie zaczyna się od nawiasów zewnętrznych
preg_match('/((\d+)\D+)(\d+)/', 'Mam 70zł, wystarczy mi to na zakup 2 książek.', $matches, PREG_OFFSET_CAPTURE);
wykonanie tego kodu spowoduje otrzymanie tablicy:
Array
(
[0] => Array
(
[0] => 70zł, wystarczy mi to na zakup 2
[1] => 4
)
[1] => Array
(
[0] => 70zł, wystarczy mi to na zakup
[1] => 4
)
[2] => Array
(
[0] => 70
[1] => 4
)
[3] => Array
(
[0] => 2
[1] => 36
)
)
$tekst = 'Mam 70zł, wystarczy mi to na 2 książki.';
// Proste przechwytywanie
preg_match('/(\d+)/', $tekst, $matches);
print_r($matches);
// Array([0] => 70, [1] => 70)
// Wiele grup
preg_match('/(\d+)\D+(\d+)/', $tekst, $matches);
print_r($matches);
// Array(
// [0] => 70zł, wystarczy mi to na 2
// [1] => 70
// [2] => 2
// )
// PREG_OFFSET_CAPTURE - z pozycjami
preg_match('/(\d+)/', $tekst, $matches, PREG_OFFSET_CAPTURE);
print_r($matches);
// Array(
// [0] => Array([0] => 70, [1] => 4)
// [1] => Array([0] => 70, [1] => 4)
// )
// Nazwane grupy (PHP 7.2+)
preg_match('/(?<cyfry>\d+)/', $tekst, $matches);
echo $matches['cyfry']; // 70
Przykłady walidacji
// ----- Email:
function validateEmail(string $email): bool {
$pattern = '/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/';
return preg_match($pattern, $email) === 1;
}
// Lepsze - użyj filter_var
function validateEmail(string $email): bool {
return filter_var($email, FILTER_VALIDATE_EMAIL) !== false;
}
// ----- Telefon:
function validatePhone(string $phone): bool {
// Format: +48 123-456-789 lub 123456789
$pattern = '/^(\+48\s?)?(\d{3}[\s\-]?\d{3}[\s\-]?\d{3})$/';
return preg_match($pattern, $phone) === 1;
}
// ----- Kod pocztowy:
function validatePostcode(string $code): bool {
// Format: 00-000
return preg_match('/^\d{2}-\d{3}$/', $code) === 1;
}
// ----- Hasło (min 8 znaków, 1 wielka, 1 mała, 1 cyfra, 1 spec):
function validatePassword(string $password): bool {
$pattern = '/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/';
return preg_match($pattern, $password) === 1;
}
// ----- URL:
function validateURL(string $url): bool {
$pattern = '/^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&\/=]*)$/';
return preg_match($pattern, $url) === 1;
}
// Lepsze - użyj filter_var
function validateURL(string $url): bool {
return filter_var($url, FILTER_VALIDATE_URL) !== false;
}
Inne funkcje regex
// ----- preg_match_all() - znajdź wszystkie dopasowania:
$tekst = "Mam 3 koty, 5 psów i 2 papugi";
preg_match_all('/\d+/', $tekst, $matches);
print_r($matches[0]);
// Array([0] => 3, [1] => 5, [2] => 2)
// ----- preg_replace() - zamień dopasowane fragmenty:
$tekst = "Mam 3 koty i 5 psów";
$wynik = preg_replace('/\d+/', 'X', $tekst);
echo $wynik; // Mam X koty i X psów
// Z backreference (grupami)
$tekst = "Jan Kowalski";
$wynik = preg_replace('/(\w+) (\w+)/', '$2, $1', $tekst);
echo $wynik; // Kowalski, Jan
// ----- preg_split() - podziel string:
$tekst = "jedno,dwa;trzy:cztery";
$czesci = preg_split('/[,;:]/', $tekst);
print_r($czesci);
// Array([0] => jedno, [1] => dwa, [2] => trzy, [3] => cztery)
// ----- preg_grep() - filtruj tablicę:
$emails = ['jan@example.com', 'invalid', 'anna@test.pl'];
$valid = preg_grep('/@/', $emails);
print_r($valid);
// Array([0] => jan@example.com, [2] => anna@test.pl)
Narzędzie do testowania wyrażeń regularnych
Więcej informacji na temat wyrażeń regularnych znajdziecie na tej stronie
Zadania:
Zadanie 1. Napisz skrypt, który sprawdzi, czy podana zmienna zawiera dokładnie 1 cyfrę.
Zadanie 2. Napisz skrypt, który sprawdzi, czy nazwa pliku zawiera polskie znaki.
Zadanie 3: Napisz funkcję maskującą numer karty kredytowej (pokaż tylko ostatnie 4 cyfry).
Zadanie 4: Napisz funkcję generującą losowy, silny slug (URL-friendly ID).
Zadanie 5: Napisz funkcję wyciągającą wszystkie hashtagi z tekstu (np. z tweeta).
Tabela funkcji – szybka ściąga
| Operacja | Funkcja | Przykład |
|---|---|---|
| Długość | strlen(), mb_strlen() |
strlen("test") → 4 |
| Pozycja | strpos(), str_contains() |
strpos("abc", "b") → 1 |
| Zamiana | str_replace(), preg_replace() |
str_replace("a", "b", "cat") → „cbt” |
| Wycięcie | substr(), mb_substr() |
substr("abc", 1) → „bc” |
| Podział | explode(), preg_split() |
explode(",", "a,b") → [„a”,”b”] |
| Złączenie | implode(), join() |
implode(",", ["a","b"]) → „a,b” |
| Wielkość liter | strtolower(), strtoupper() |
strtolower("ABC") → „abc” |
| Czyszczenie | trim(), ltrim(), rtrim() |
trim(" a ") → „a” |
| HTML | htmlspecialchars(), strip_tags() |
htmlspecialchars("<b>") → „<b>” |
| Regex dopasowanie | preg_match() |
preg_match("/\d/", "a1") → 1 |
| Regex wszystkie | preg_match_all() |
preg_match_all("/\d/", "a1b2") → 2 |
Dobre praktyki
1. Używaj funkcji mb_* dla tekstów wielobajtowych
// ŹLE - błędne dla UTF-8
$polish = "zażółć";
echo strlen($polish); // 10 (bajty, nie znaki!)
// DOBRZE
echo mb_strlen($polish, 'UTF-8'); // 6 (znaki)
2. Waliduj dane wejściowe
// ŹLE
$email = $_POST['email'];
// użyj bez walidacji
// DOBRZE
$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
if ($email === false) {
die("Nieprawidłowy email");
}
3. Escapuj output HTML
// ŹLE - podatne na XSS
echo $_GET['name'];
// DOBRZE
echo htmlspecialchars($_GET['name'], ENT_QUOTES, 'UTF-8');
4. Używaj prepared statements zamiast addslashes
// ŹLE
$name = addslashes($_POST['name']);
$query = "SELECT * FROM users WHERE name='$name'";
// DOBRZE
$stmt = $pdo->prepare("SELECT * FROM users WHERE name = :name");
$stmt->execute(['name' => $_POST['name']]);
5. Preferuj filter_var nad regex dla walidacji
// ŹLE - skomplikowane regex
preg_match('/^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}$/i', $email);
// DOBRZE - wbudowana walidacja
filter_var($email, FILTER_VALIDATE_EMAIL);
Podsumowanie
Kluczowe pojęcia:
- String – ciąg znaków, podstawowy typ danych tekstowych
- Regex – wzorzec do wyszukiwania i manipulacji tekstem
- Escapowanie – zabezpieczanie znaków specjalnych
- Multibyte – obsługa znaków wielobajtowych (UTF-8)
Pamiętaj:
- Używaj mb_* funkcji dla tekstów z polskimi znakami
- Zawsze escapuj output HTML (htmlspecialchars)
- Używaj password_hash() do haseł, NIE md5() czy sha1()
- Preferuj filter_var() nad regex dla standardowej walidacji
- Używaj prepared statements, NIE addslashes()
- W regex używaj modyfikatora u dla UTF-8
- Dla regex użyj narzędzi online do testowania (regex101.com)
- NIE ufaj danym użytkownika – zawsze waliduj i escapuj