Низове

Низът представлява поредица от знаци. В PHP, знакът е същото като байт, т.е., съществуват точно 256 възможни знака. Това също означава, че PHP няма естествена поддръжка за Unicode. Вж. utf8_encode() и utf8_decode() за Unicode поддръжка.

Забележка: За даден низ не е проблем да стане много дълъг. Няма практическо ограничение в размера на низовете, наложено от PHP, така че не трябва да се безпокоите за дългите низове.

Синтаксис

Низов литерал може да бъде дефиниран по три различни начина.

Поставяне в апострофи

Най-лесният начин да се дефинира обикновен низ е да се загради с апострофи (знакът ').

За да укажете знака апостроф, трябва да го екранирате с обратно-наклонена черта (\), както това се прави и в редица други езици. Ако все пак се налага преди апострофа да се появи обратно-наклонена черта, ще трябва да я дублирате. Отбележете, че ако се опитате да екранирате който и да е друг символ, обратно-наклонената черта също ще бъде отпечатана! Така че обикновено тя няма нужда да бъде екранирана.

Забележка: В PHP 3 ще бъде изведено предупреждение от ниво E_NOTICE, когато това се случи.

Забележка: За разлика от другите два синтаксиса, тук променливите и екраниращите последователности за специални знаци няма да бъдат обработени.

<?php
echo 'това е обикновен низ';

echo 'Можете също да поставяте и
нови редове по този
начин';

// Извежда: Арнолд веднъж каза: "I'll be back"
echo 'Арнолд веднъж каза: "I\'ll be back"';

// Извежда: Вие изтрихте C:\*.*?
echo 'Вие изтрихте C:\\*.*?';

// Извежда: Вие изтрихте C:\*.*?
echo 'Вие изтрихте C:\*.*?';

// Извежда: Това няма да се изведе: \n - нов ред
echo 'Това няма да се изведе: \n - нов ред';

// Извежда: Променливите също: $alpha $beta
echo 'Променливите също: $alpha $beta';
?>

Поставяне в кавички

Ако низът е заграден в кавички ("), PHP разбира повече екраниращи последователности за специални знаци:

Таблица 11-1. Екранирани знаци

И тук ако се опитате да екранирате който и да е друг знак, обратно-наклонената черта също ще бъде отпечатана! Преди PHP 5.1.1, обратно-наклонената черта в \{$var} не се отпечатваше.

Най-важната особеност на кавичките, обаче, е че променливите ще бъдат обработени. За повече информация вижте разбор на низ.

Heredoc

Друг начин да се дефинира низ е да се използва heredoc-синтаксис ("<<<"). След <<< трябва да се укаже идентификатор (последван от нов ред), след това низа и накрая самия идентификатор, който да затвори цитата.

Затварящият идентификатор трябва да започне на в първата колона на реда. Освен това, използваният идентификатор трябва да следва същите правила за именуване като всеки друг етикет в PHP: трябва да се състои единствено от буквено-цифрови знаци или подчертавки и трябва да започва със знак, който не е цифра.

Внимание

Много важно е да се отбележи, че на реда със затварящия идентификатор няма никакви други символи, освен по възможност точка и запетая (;). Това преди всичко означава, че идентификаторът не може да бъде отместван като абзац и не може да има никакви интервали или табулации преди или след точката и запетаята. Важно е също да се разбере, че първият знак преди затварящия идентификатор трябва да бъде знака за нов ред, както е дефиниран от съответната операционна система. Например на Macintosh това е \r. Затварящият идентификатор (по желание последван от точка и запетая) също трябва и да бъде последван от знак за нов ред.

Ако това правило не се спази и затварящият идентификатор не е "чист", тогава той няма да бъде възприет като такъв и PHP ще продължи да го търси. Ако в този случай не бъде намерен правилен затварящ идентификатор, това ще доведе до синтактична грешка с номер на реда в края на скрипта.

Не е разрешена употребата на heredoc-синтаксис в инициализиране на членове на клас. В този случай използвайте другите низови синтаксиси.

Пример 11-3. Невалиден пример

<?php
class foo {
    public $bar = <<<EOT
bar
EOT;
}
?>

Heredoc-текстът работи по същия начин както и низът в кавички, само че без кавичките. Това означава, че няма нужда да екранирате кавичките, но че можете да използвате екраниращите кодове изброени по-горе. Променливите биват обработени, но трябва да се внимава при изразяване на сложни променливи вътре в heredoc както е и в случая при низовете.

Пример 11-4. Пример за heredoc-цитат

<?php
$str = <<<EOD
Пример за низ,
който преминава на няколко
реда с heredoc-синтаксис.
EOD;

/* По-сложен пример, с променливи. */
class foo
{
    var $foo;
    var $bar;

    function foo()
    {
        $this->foo = 'Foo';
        $this->bar = array('Bar1', 'Bar2', 'Bar3');
    }
}

$foo = new foo();
$name = 'MyName';

echo <<<EOT
Казвам се "$name". Отпечатвам някое $foo->foo.
Сега, отпечатвам накое {$foo->bar[1]}.
Това трябва да отпечата главно 'A': \x41
EOT;
?>

Забележка: Поддръжката на heredoc беше добавена в PHP 4.

Анализиране на променливи

Когато даден низ се дефинира в кавички или с heredoc, променливите в него биват анализирани.

Съществуват два типа синтаксис: прост и сложен. Простият синтаксис е най-разпространен и удобен. Той предлага начин да се анализира променлива, стойност от масив, или свойство на обект.

Сложният синтаксис беше въведен в PHP 4 и може да бъде разпознат по къдравите скоби, заграждащи израза.

Прост синтаксис

Ако срещне знака за долар ($), синтактичният анализатор ще се опита лакомо да поеме колкото се може повече знаци, за да образува валидно име на променлива. Заградете името на променливата в къдрави скоби, ако искате изрично да укажете края на името.

<?php
$beer = 'Heineken';
echo "$beer's taste is great"; // работи, "'" е невалиден знак за име на променлива
echo "He drank some $beers";   // няма да работи, 's' е валиден знак за име на променлива
echo "He drank some ${beer}s"; // работи
echo "He drank some {$beer}s"; // работи
?>

По същия начин се прави разбор и на елемент от масив или свойство на обект. При индексите на масиви, затварящата квадратна скоба (]) обозначава края на индекса. За свойствата на обекти важат същите правила както за обикновените променливи, макар че при обектните свойства не съществува трик като този при променливите.

<?php
// Тези примери са специфични за употребата на масиви в низове.
// Извън низ, винаги заграждайте с апострофи низовите ключове на масиви
// и съответно - не използвайте {къдрави скоби}.

// Нека се показват всички грешки
error_reporting(E_ALL);

$fruits = array('strawberry' => 'red', 'banana' => 'yellow');

// Работи, но отбележете, че това работи по друг начин извън низовите кавички
echo "A banana is $fruits[banana].";

// Работи
echo "A banana is {$fruits['banana']}.";

// Работи, но PHP първо търси константа с името "banana",
// както е обяснено по-долу.
echo "A banana is {$fruits[banana]}.";

// Няма да работи, използвайте къдрави скоби. Това ще предизвика синтактична грешка.
echo "A banana is $fruits['banana'].";

// Работи
echo "A banana is " . $fruits['banana'] . ".";

// Работи
echo "This square is $square->width meters broad.";

// Няма да работи. За решение, вижте сложния синтаксис.
echo "This square is $square->width00 centimeters broad.";
?>

За всичко по-сложно трябва да използвате сложния синтаксис.

Сложен (къдрав) синтаксис

Името "сложен" не е защото синтаксисът е сложен, а защото чрез него можете да включвате сложни изрази.

На практика, с този синтаксис можете да включите в низ коя да е стойност, която е налична в пространството от имена. Просто пишете израза по същия начин както бихте го направили извън низа, след което го поставяте между { и }. Тъй като не можете да екранирате '{', този синтаксис ще бъде разпознат единствено, когато $ следва непосредствено {. (Използвайте "{\$", за ад получите литерала "{$"). Няколко разяснителни примера:

<?php
// Нека се показват всички грешки
error_reporting(E_ALL);

$great = 'fantastic';

// Няма да работи, извежда: This is { fantastic}
echo "This is { $great}";

// Работи, извежда: This is fantastic
echo "This is {$great}";
echo "This is ${great}";

// Работи
echo "This square is {$square->width}00 centimeters broad."; 

// Работи
echo "This works: {$arr[4][3]}";

// Това е грешно по същата причина, поради която и $foo[bar] е грешно
// извън низ. С други думи, ще работи, но понеже PHP първо
// ще потърси константата foo, ще хвърли грешка от ниво
// E_NOTICE (недефинирана константа).
echo "This is wrong: {$arr[foo][3]}"; 

// Работи. При многомерни масиви, винаги поставяйте
// къдрави скоби около масивите, когато са в низове.
echo "This works: {$arr['foo'][3]}";

// Работи.
echo "This works: " . $arr['foo'][3];

echo "You can even write {$obj->values[3]->name}";

echo "This is the value of the var named $name: {${$name}}";
?>

Забележка: Извикването на функции и методи работи от PHP 5.

Познаков достъп и изменение в низ

Знаците в даден низ могат да бъдат достъпвани и изменяни чрез указване на отместване от нулата за желания знак след низа посредством квадратни скоби, например $str[42], така че бихте могли да мислите за даден низ като за масив от знаци.

Забележка: Те също могат да бъдат достъпвани и с къдрави скоби - $str{42}, със същата цел. Все пак, употребата на квадратни скоби е за предпочитане, тъй като {къдравият} стил става непрепоръчителен от PHP 6.

Пример 11-5. Някои низови примери

<?php
// Вземане на първия знак от низ.
$str = 'Това е тест.';
$first = $str[0];

// Вземане на третия знак от низ.
$third = $str[2];

// Вземане на последния знак от низ.
$str = 'Това продължава да бъде тест.';
$last = $str[strlen($str)-1];

// Промяна на последния знак от низ.
$str = 'На масата има ябълка';
$str[strlen($str)-1] = 'и';

// Алтернативният метод с {} е непрепоръчителен от PHP 6
$third = $str{2};
?>

Полезни функции и оператори

Низовете могат да бъдат съединявани посредством оператора '.' (точка). Забележете, че операторът '+' (събиране) няма да направи това. За повече информация вижте Низови оператори.

Съществуват доста на брой полезни функции за изменение на низове.

За основните функции вижте раздел низови функции, а за по-сложно търсене и заместване - функциите за регулярни изрази (в две разновидности: Perl и POSIX разширения).

Има също функции за URL-низове и функции за криптиране и декриптиране на низове (mcrypt и mhash).

Накрая, ако все още не сте намерили това, което търсите, вижте също и функциите за типове знаци.

Преобразуване в низ

Можете да превърнете стойност в низ посредством преобразуването (string) или функцията strval(). Низовото преобразуване се извършва автоматично в обхвата на израз, който се нуждае от низ. Това се случва, когато използвате функциите echo() и print(), или когато сравнявате стойността на променлива с низ. Прочитането на разделите за Типове и Манипулации с типове ще направи нещата още по-ясни. Вж. също settype().

Булевата стойност TRUE се преобразува в низа "1", а стойността FALSE се представя като "" (празен низ). По този начин можете да преобразувате двупосочно между булеви и низови стойности.

Цяло число (integer) или число с плаваща запетая (float) се преобразува в низ, който се състои от цифрите на числото (включително и експонентата - за числата с плаваща запетая).

Забележка: Знакът за десетична запетая се дефинира в локалните настройки на скрипта (категория LC_NUMERIC). Вж. setlocale().

Масивите винаги се преобразуват в низа "Array", така че не можете да покажете съдържанието на даден масив с echo() или print(). За да видите един елемент, трябва да направите нещо от рода на echo $arr['foo']. Погледнете по-долу за начини за показване на цялото съдържание.

Обектите винаги се преобразуват в низа "Object". Ако искате да покажете стойностите на член-променливите на даден обект, с цел отстраняване на програмни грешки, прочетете следващите абзаци. За да видите името на класа, на който е инстанция обектът, използвайте get_class(). От PHP 5 се използва метода __toString(), ако е приложим.

Ресурсите винаги се преобразуват в низове със структура "Resource id #1", където 1 е уникалното число на ресурса, присвоено от PHP по време на изпълнение. Ако искате да вземете типа на ресурса, използвайте get_resource_type().

NULL винаги се преобразува в празен низ.

Както можете да видите по-горе, отпечатването на масиви, обекти или ресурси не ви предоставя никаква полезна информация за самите стойности. Разгледайте функциите print_r() и var_dump() за по-добри начини за показване на стойностите, в процеса на отстраняване на грешки.

Можете също да превърнете стойности от PHP в низове за постоянно съхранение. Този метод се нарича сериализация и може да се осъществи посредством функцията serialize(). Можете също да сериализирате стойности от PHP в XML структури, стига да имате поддръжка за WDDX в инсталацията ви на PHP.

Превръщане на низ в число

Когато даден низ бъде разпознат като число, резултантната стойност и типът се определят както следва.

Низът ще се изчисли като плаващо ако съдържа който и да е от знаците '.', 'e' или 'E'. В противен случай, ще се изчисли като цяло число.

Стойността се взима от първата част на низа. Ако низът започва с валидни числови данни, това ще бъде и използваната стойност. В противен случай стойността ще бъде 0 (нула). Валидните числови данни са незадължителен знак, последван от една или повече цифри (по желание съдържащи и плаваща запетая), последвани от незадължителна експонента. Експонентата се изразява с буквата 'e' или 'E', последвана от една или повече цифри.

<?php
$foo = 1 + "10.5";                // $foo е плаващо (11.5)
$foo = 1 + "-1.3e3";              // $foo е плаващо (-1299)
$foo = 1 + "bob-1.3e3";           // $foo е цяло число (1)
$foo = 1 + "bob3";                // $foo е цяло число (1)
$foo = 1 + "10 малки прасета";    // $foo е цяло число (11)
$foo = 4 + "10.2 малки прасенца"; // $foo е плаващо (14.2)
$foo = "10.0 прасета " + 1;       // $foo е плаващо (11)
$foo = "10.0 прасета " + 1.0;     // $foo е плаващо (11)     
?>

За повече информация относно това преобразуване вижте страницата от ръководството на Unix за strtod(3).

В случай, че искате да проверите някой от примерите в този раздел, можете да ги препишете и да сложите следния ред, за да се уверите сами какво се случва:

<?php
echo "\$foo==$foo; типът е " . gettype ($foo) . "<br />\n";
?>

Не разчитайте да получите кода на даден низ като го преобразувате в цяло число (както бихте направили в C например). Използвайте функциите ord() и chr(), за да правите преобразувания между знаци и съответните им кодове.