Podręcznik PHP
Poprzedni | Rozdział 11. Typy danych | Następny

# Łańcuchy znaków (string)

Typ string oznacza łańcuch znaków. W PHP znak jest tym sam co bajt, co oznacza, że jest możliwych 256 różnych znaków. Oznacza to także, że PHP nie posiada żadnej wbudowanej obsługi Unikodu.

> Notatka: Nie ma technicznych problemów, które utrudniałyby tworzenie bardzo długich ciągów znaków. Nie ma też ustalonej maksymalnej długości łańcuchów znaków obsługiwanych w PHP, więc nie ma powodu do obaw, że dany łańcuch jest zbyt długi.

## Składnia

Łańcuch znaków można utworzyć na trzy sposoby.

- pojedyncze cudzysłowy

- podwójne cudzysłowy

- składnia heredoc

### Pojedyncze cudzysłowy

Najprostszym sposóbem na zdefiniowanie prostego łańcucha znaków, jest umieszczenie go w pojedynczych cudzysłowach (znak ').

Aby w takim łańcuch umieścić symbol pojedynczego cudzysłowu, należy go poprzedzić ukośnikiem wstecznym (\), tak jak w wielu innych językach programowania. Jeśli ukośnik wsteczny ma wystąpić przed symbolem pojedynczego cudzysłowu lub na końcu łańcucha, wtedy należy napisać go dwukrotnie. W przypadku użycia ukośnika wstecznego z innym znakiem, ukośnik też zostanie wyświetlony! Nie ma zatem potrzeby pisania ukośnika dwukrotnie w innych sytuacjach.

> Notatka: W PHP 3, ostrzeżenie na poziomie E_NOTICE zostanie wyświetlone, jeśli zajdzie powyższa sytuacja.

> Notatka: W przeciwieństwie do dwóch pozostałych składni, zmienne nie będą zamienione na swoje wartości, kiedy pojawią się pomiędzy pojedynczymi cudzysłowami.

`echo 'przykładowy tekst';
echo 'Wewnątrz łańcuchów znaków mogą się znajdować przełamania linii,
o właśnie takie.';
echo 'Adam powiedział: "I\'ll be back"';
// wynik: ... "I'll be back"
echo 'Czy na pewno chcesz skasować C:\\*.*?';
// wynik: ... skasować C:\*.*?
echo 'Czy na pewno chcesz skasować C:\*.*?';
// wynik: ... skasować C:\*.*?
echo 'Próbuję w tym miejscu wprowadzić: \n znak nowej linii';
// wynik: ... wprowadzić: \n znak nowej linii`

### Podwójne cudzysłowy

Kiedy łańcuch znaków jest umieszczony pomiędzy podwójnymi cudzysłowami, PHP interpretuje więcej sekwencji cytowania dla znaków specjalnych:

Tabela 11-1. Znaki cytowane (specjalne)

sekwencja | znaczenie
--- | ---
\n | nowa linia (LF lub 0x0A (10) w ASCII)
\r | powrót karetki (CR lub 0x0D (13) w ASCII)
\t | tabulacja pozioma (HT lub 0x09 (9) w ASCII)
\\ | odwrotny ukośnik
\$ | znak dolara
\" | cudzysłów podwójny
\[0-7]{1,3} | sekwencja znaków pasująca do powyższego wyrażenia regularnego daje znak zapisany w notacji ósemkowej
\x[0-9A-Fa-f]{1,2} | sekwencja znaków pasująca do powyższego wyrażenia regularnego daje znak zapisany w notacji szesnastkowej

Tak jak w poprzedniej składni, zapisanie ukośnika wstecznego przed każdym innymi znakiem spowoduje wyświetlenie zarówno ukośnika, jak i znaku.

Ale najważniejszą właściwością podwójnych cudzysłowów jest to, że zapisane w nich zmienne zostaną zamienione na ich wartości. Więcej informacji w rozdziale parsowanie łańcuchów znaków.

### Składnia Heredoc

Jeszcze jednym sposobem na zapisanie łańcucha znaków jest użycie skladni heredoc ("<<<"). Po operatorze <<< powinno się umieścić identyfikator i takim samym identyfikatorem trzeba zakończyć łańcuch znaków.

Identyfikator zamykający musi zaczynać się w pierwszej kolumnie nowej linii. Identyfikator musi też podlegać regułom nazewnictwa w PHP: musi się składać wyłącznie z alfanumerycznych znaków oraz znaku podkreślenia i musi zaczynać się od litery lub znaku podkreślenia.

Ostrzeżenie

Ważne by pamiętać, że linia zawierająca identyfikator zamykający nie może zawierać żadnych innych znaków, z wyjątkiem średnika (;). Znaczy to przede wszystkim, że identyfikator zamykający nie może być wcinany, i nie może być żadnych spacji ani tabulacji przed lub za średnikiem.

Najbardziej dokuczliwym ograniczeniem jest to, że wewnątrz tego łańcucha znaków nie może być znaku powrotu karetki (\r) na końcu linii, jedynie znak nowej linii (\n). Ponieważ Microsoft Windows używa jako znaku końca linii sekwencji \r\n, łańcuchy znaków zapisne w składni heredoc mogą nie działać, jeśli skrypt zostanie napisany w edytorze windowsowym. Na szczęście większość edytorów tekstowych udostępnia możliwość zapisania pliku w uniksowym formacie końca linii.

Składnia heredoc zachowuje się podobnie jak tekst w cudzysłowach podwójnych. Oznacza to też, ze nie ma potrzeby cytowania cudzysłowów w tej składni, ale nadal można używać znaków cytowanych, opisanych powyżej. W tej składni nazwa zmiennej zamieniana jest na jej wartość, ale należy zachować ostrożność przy zapisie złożonych zmiennych razem z tekstem.

Przykład 11-2. Przykład składni heredoc

`<?php
$str = <<<EOD
Przykład łańcucha znaków,
zajmującego kilka linii,
zapisanego w składni heredoc.
Przykładowe zastosowanie w przezentacji liryki.
Litwo! Ojczyzno moja! ty jesteś jak zdrowie;
Ile cię trzeba cenić, ten tylko się dowie,
Kto cię stracił. Dziś piękność twą w całej ozdobie
Widzę i opisuję, bo tęsknię po tobie.
\tAdam Mickiewicz - Pan Tadeusz
EOD;
/* Bardziej złożony przykład, ze zmiennymi */
class foo
{
var $foo;
var $bar;
function foo()
{
$this->foo = 'Foo';
$this->bar = array('Bar1', 'Bar2', 'Bar3');
}
}
$foo = new foo();
$name = 'MojeImię';
echo <<<EOT
Nazywam się "$name". Wyświetlam $foo->foo.
A teraz wyświetlam z tablicy: {$foo->bar[1]}.
Po dwukropku powinien pojawić się znak 'A': \x41
EOT;
?>`

> Notatka: Obsługa składni heredoc została dodana w PHP 4.

### Parsowanie zmiennych

Kiedy łańcuch znaków jest zapisany w cudzysłowach podwójnych lub w składni heredoc, zawarte w nim nazwy zmiennych są parsowane, tzn. zamieniane na ich wartości.

Są dwa rodzaje składni, prosta i złożona. Składnia prosta jest najbardziej popularna i najwygodniejsza, pozwala na parsowanie zmiennej, wartości z tablicy oraz właściwości obiektu.

Składnia złożona pojawiła się w PHP 4, i można ją rozpoznać po nawiasach klamrowych, otaczających wyrażenie.

#### Składnia prosta

Jeśli wewnątrz zmiennej pojawi się znak dolara ($), parser pobierze tyle znaków, ile tylko się da, aby utworzyć poprawną nazwę zmiennej. Aby jawnie określić koniec nazwy zmiennej, należy ją zapisać w klamrach.

`$beer = 'Heineken'; echo "$beer's taste is great"; /* działa, "'" nie jest poprawnym znakiem nazwy zmiennej*/ echo "He drunk some $beers"; /* nie działa, 's' jest poprawnym znakiem nazwy zmiennej*/ echo "He drunk some ${beer}s"; // działa`

Podobnie działa parsowanie elementu tablicy lub właściwości obiektu. Dla tablic, prawy nawias prostokątny (]) oznacza koniec indeksu. Dla właściwości obiektu obowiązują te same reguły jak dla zwykłych zmiennych, jednak nie działają tu opisane powyżej sztuczki ze zmiennymi.

`$owoce = array( 'truskawka' => 'czerwona' , 'banan' => 'żółty' ); // zauważ że to działa inaczej poza cudzysłowami echo "Banan jest $owoce[banan]."; echo "Kwadrat ma szerokość $kwadrat->szerokość metrów."; // Nie działa. Trzeba tu zastosować składnię złożoną echo "Kwadrat ma szerokość $kwadrat->szerokość00 centymetrów.";`

Do wyrażeń bardziej skomplikowanych należy używać składni złożonej.

#### Składnia złożona

Nazwa tej składni nie pochodzi od skomplikowanego zapisu, tylko od możliwości obsługi bardziej złożonych wyrażeń.

Za pomocą tej składni można umieszczać w łańcuchach znaków każdą wartość istniejącą w przestrzeni nazw. Odpowiednie wyrażenie pisze się tak, jakby miało ono znajdować się gdziekolwiek poza łańcuchem znaków, a potem tylko umieszcza się je między { i }. Ponieważ nie można cytować "{", składnia ta będzie prawidłowo rozpoznana tylko wtedy, kiedy $ znajduje się bezpośrednio za {. (Użyj "{\$" lub "\{$" aby uzyskać "{$"). Poniżej kilka przykładów:

`$fajne = 'fantastyczne';
echo "To jest { $fajne}"; // nie działa, zwraca: To jest { fantastyczne}
echo "To jest {$fajne}"; // działa, zwraca: To jest fantastyczne
echo "Kwadrat ma szerokość {$kwadrat->szerokość}00 centimetrów.";
echo "To działa: {$arr[4][3]}";
// Tak jest źle z tego samego powodu
// co $foo[bar] poza łańcuchem.
echo "Tak jest źle: {$arr[foo][3]}";
echo "Prawidłowo jest tak: {$arr['foo'][3]}";
echo "Można nawet pisać tak: {$obj->wartości[3]->nazwa}";
echo "To jest wartość zmiennej o nazwie $nazwa: {${$nazwa}}";`

### Indeksowanie łańcucha (ofsety)

Dostęp do pojedynczego znaku łańcucha jest możliwy po podaniu jego indeksu (ofsetu) w nawiasach klamrowych, zaraz po nazwie zmiennej. Pierwszy znak w łańcuchu ma indeks zero.

> Notatka: Dla zachowania kompatybilności wstecznej, nadal można używać nawiasów kwadratowych, jednak składnia ta w PHP 4 uznana jest za przestarzałą.

Przykład 11-3. Przykłady używania łańcuchów znaków

`<?php
/* Przypisywanie łańcucha do zmiennej */
$str = "To jest łańcuch znaków";
/* Dołączanie innego łańcucha */
$str = $str . " a to jego dalsza część";
/* inny sposób dołączania, ze znakiem nowej linii na końcu */
$str .= " wraz ze znakiem nowej linii na końcu.\n";
/* Ten łańcuch będzie zawierać: "<p>Liczba: 9</p>" */
$num = 9;
$str = "<p>Liczba: $num</p>";
/* Natomiast tutaj będzie: "<p>Liczba: $num</p>" */
$num = 9;
$str = '<p>Liczba: $num</p>';
/* Pobranie pierwszego znaku łańcucha */
$str = 'To jest przykład.';
$pierwszy = $str{0};
/* Ostatni znak łańcucha */
$str = 'Dalsza część przykładu.';
$ostatni = $str{strlen($str)-1};
?>`

## Przydatne funkcje i operatory

Łańcuchy znaków łączy się za pomocą operatora '.' (kropka). Proszę pamiętać, że operator dodawania '+' nie wykonuje operacji łączenia łańcuchów. Więcej informacji w rozdziale operatory łańcuchowe.

PHP posiada mnóstwo funkcji operujących na łańcuchach znaków.

Najwięcej na ten temat w rozdziale funkcje łańcuchowe. Poza tym obsługiwane są wyrażenia regularne dla potrzeb zaawnsowanych operacji znajdź i zamień (w dwóch odmianach: Perl oraz POSIX extended).

Są także funkcje obsługi łańcuchów URL, jak również funkcje szyfrowania i deszyfrowania łańcuchów (mcrypt oraz mhash).

Jeśli nadal nie znalazłeś tego, czego potrzebujesz, być może pomogą ci funkcje kontroli typu znaków.

## Konwersja łańcuchów znaków

Jeśli łańcuch znaków jest konwertowany na postać liczbową, rezultat konwersji będzie zależał od poniższych czynników.

Łańcuch zostanie skonwertowany do typu float, jeśli zawiera znaki ".", "e" lub "E". W przeciwnym razie zostanie skonwertowany do typu integer.

Wartość liczbowa łańcucha znaków zależy od pierwszych znaków tego łańcucha. Jeśli łańcuch zaczyna się od poprawnej wartości liczbowej, wartość ta będzie używa przy konwersji. W przeciwnym razie zwrócona będzie wartość 0 (zero). Poprawna wartość liczbowa zaczyna się od opcjonalnego znaku, po którym znajduje się jedna, lub kilka cyfr (opcjonalnie zawierające przecinek dziesiętny), po którym opcjonalnie znajduje się eksponent. Eksponent jest to znak "e" lub "E", po którym następuje jedna, lub więcej cyfr.

Kiedy pierwszym wyrażeniem jest łańcuch znaków, typ zmiennej będzie zależał od drugiego wyrażenia.

`$foo = 1 + "10.5"; // $foo jest typu float (11.5)
$foo = 1 + "-1.3e3"; // $foo jest typu float (-1299)
$foo = 1 + "bob-1.3e3"; // $foo jest typu integer (1)
$foo = 1 + "bob3"; // $foo jest typu integer (1)
$foo = 1 + "10 małych świnek"; // $foo jest typu integer (11)
$foo = 1 + "10 malutkich świnek"; // $foo jest typu integer (11)
$foo = "10.0 świnek " + 1; // $foo jest typu float (11)
$foo = "10.0 świnek " + 1.0; // $foo jest typu float (11)`

Więcej informacji na temat tej konwersji znajduje się w podręczniku Uniksa, na stronie polecenia strtod(3).

Jeśli chciałbyś przetestować któryś z przykładów w tym rozdziale, możesz je skopiować i wkleić, a następnie dodać poniższą linię i obserwować rezultaty.

`echo "\$foo==$foo; jest typu " . gettype ($foo) . "<br>\n";`

Poprzedni | Spis treści | Następny
Liczby zmiennoprzecinkowe (float) | Początek rozdziału | Tablice (array)