PHP-4 Эффективная работа


Общие правила построения программы
Типы данных
Выражения
Функции

3.3. Выражения

Краеугольным камнем в РНР как языке программирования является понятие выражения. Собственно говоря, большая часть вводимого вами кода представляет собой выражения в той или иной форме. Самое простое и в то же самое время самое емкое определение выражения может быть сформулировано следующим образом: выражением является любая конструкция, которая имеет некоторое значение.

Чаще всего в качестве выражений используются константы и переменные, которые рассматриваются в главе 4. Например, когда вы присваиваете некоторой переменной значение:

$dwa = 2;

вы фактически имеете дело с двумя выражениями: константой «2» и переменной $dwa.

Аналогичным образом выражением является как определение, так и вызов функции. Предположим, например, что мы определили следующую функцию (подробно вопросы определения и использования функций рассматриваются в главе 9):

function five () {
       return 5;
}

При таком определении вызов функции $с = five ( ) фактически эквивалентен операции присваивания $с = 5. Впрочем, это, конечно же, экстремальный вариант определения функции, который только иллюстрирует общий подход.

Следует отметить, что значения в РНР не обязательно должны быть целыми числами и чаще всего таковыми не являются. В РНР поддерживаются три основных скалярных типа: целые и вещественные числа, а также строки.

внимание
       Под скалярным значением понимается некоторая структура данных, которая с точки зрения языка не может быть разбита на более мелкие структуры. Так, массив не может рассматриваться как скаляр, поскольку состоит из множества элементов.

К числу сложных типов, поддерживаемых РНР, относятся массивы и объекты. Значение, принадлежащее любому из перечисленных выше типов, может быть присвоено любой переменной или может являться результатом работы функции.

Стоит обратить внимание на один вид выражений, заимствованный из Perl, который представляет собой тернарный условный оператор, имеющий вид: $first ? $second : $third

Если значение первого подвыражения $first отлично от нуля, производится оценка второго субвыражения $ second, значение которого становится результатом всего выражения в целом. Если же значение первого подвыражения равно нулю (или false), оценивается и возвращается в качестве результата третье подвыражение $third.

Теперь давайте взглянем на несколько примеров различных выражений, используемых в РНР:

function double($i) {
       return $i*2;
}

$b = $a = 5;                // Присваивает целое число 5 переменным $а и $b

$с = $а++;           // Присваивает 5 переменной $с, а затем
          // инкрементирует значение $а

$е = $d = ++$b;           // инкрементирует $а и присваивает переменным
          // $d и $е значение 6.


$f = double($d++);           // После вызова $f=12, $d = 7

$g = double(++$e);           // после вызова $е=7, $g=14

$h = $g += 10; /* Вначале $g увеличивается на 10 и получает
                          значение 24. Затем это значение
                          присваивается переменной $h, которая тоже
                          становится равной 24.
          */

В начале раздела мы указывали, что выражения могут представлять собой законченые операторы языка. Но из этого вовсе не следует, что любое выражение является оператором. В рассмотренных выше примерах оператор имеет вид:

'ехрr' ' ; '
то есть представляет собой выражение, за которым следует точка с запятой. В частности, в примере $b=$а=5 ; фрагмент $а=5 не является оператором. А вот полное выражение $b=$а=5 ; представляет собой полный оператор.

3.4. Функции

Как и в большинстве других языков программирования, в РНР можно определять пользовательские подпрограммы и функции или использовать библиотечные. Начнем, пожалуй, с определения собственных функций.

3.4.1. Пользовательские функции

Для определения собственной функции используется конструкция вида: function foo ($arg_l, $arg_2.....$arg_n) {
          echo "Пример определения функции.\n";
          return $retval;
}

Внутри тела функции может использоваться любой код РНР, включая определения локальных функций и классов.

Несмотря на свое «интерпретируемое» прошлое РНР не поддерживает перегрузку определений функций, и вы не можете отменить определение введенной ранее функции. Зато РНР 4 поддерживает как переменное количество аргументов функции, так и автоматическую подстановку значений по умолчанию.

3.4.2. Аргументы функции

Передача данных в функции осуществляется с помощью списка аргументов, который представляет собой список переменных и/или констант, разделенных запятыми. По умолчанию в РНР реализована передача аргументов по значению. Это означает, что если вы изменяете внутри функции значение аргумента, то тем самым вы модифицируете только значение локальной копии аргумента и все эти изменения за пределами тела функции видны не будут. Если же вам необходимо вернуть в вызывающую программу модифицированное значение, вы должны использовать передачу данных по ссылке.

Этот метод передачи аргументов реализуется следующим образом. Вы предваряете имя аргумента в определении функции символом &:

function add_some_extra(&$string) {
          $string .= 'и маленькая тележка.';
}
$str = 'Вагон ' ;
add_some_extra($str) ;
echo $str;                // напечатает 'Вагон и маленькая тележка.'

При таком оформлении подпрограммы аргумент будет всегда передаваться в нее по ссылке, а не по значению. Если же вы хотите передать переменную по ссылке в функцию, в которой не предусмотрено использование этого метода по умолчанию, вы можете приписать & к имени аргумента в строке, содержащей вызов функции:

function foo ($bar) {
          $bar .= ' и маленькая тележка.';
}
$str = ' Вагон ';
foo ($str);
echo $str;                    // напечатает 'Вагон ' foo (&$str);
echo $str;                    // напечатает 'Вагон и маленькая тележка.'

3.4.3. Значения аргументов по умолчанию

Начиная с версии РНР 4.0 вы можете использовать значения аргументов, подставляемые по умолчанию, примерно так же, как это происходит в C++. Делается это следующим образом:

function makecoffee ($type = "кофе с молоком") {
       return "Сделайте чашечку $type.\n";
}
echo makecoffee ( );                     // ''кофе с молоком''
echo makecoffee ("экспрессе");

Значение по умолчанию должно представлять собой константное выражение и не может являться переменной или членом класса. Все аргументы, для которых предусмотрено значение по умолчанию, в списке аргументов функции должны следовать после обязательных аргументов. В противном случае дела могут пойти, скажем так, неожиданным образом. Взгляните на следующий фрагмент:

function makeyogurt ($type = "йогурта", $flavour) {
       return "Смешиваю стаканчик $flavour $type.\n";
}
echo makeyogurt ("черничного");           // это не сработает

При попытке выполнения этого фрагмента вы получите сообщение вида:

Warning: Missing argument 2 in call to makeyogurt( ) in
/usr/local/etc/httpd/htdocs/php3test/functest.html on line 41
Смешиваю стаканчик черничного .

А вот если поступить следующим образом:


function makeyogurt ($flavour, $type = "йогурта") {
          return "Смешиваю стаканчик $flavour $type.\n";
}

echo makeyogurt ("черничного");           // нормально!

то результат будет вполне ожидаемым:

Смешиваю стаканчик черничного йогурта.

3.4.4. Списки аргументов переменной длины

Пользовательские функции в РНР 4 могут иметь переменную длину, то есть переменное количество аргументов. Для работы с такими списками используются функции func_num_args( ) (см. раздел 9.2.3), func_get_arg( ) (см. раздел 9.2.1) и func_get_args() (см. раздел 9.2.2).

Никакой специальный синтаксис для поддержки переменных списков йе требуется, и явно введенные параметры функции используются обычным образом.

3.4.5. Возврат значений из функций

Для возврата значений из функции используется оператор return. С его помощью вы можете вернуть данные любого типа, включая списки и объекты:

function square ($num) {
          return $num * Snum;
}
echo square (4);      // получим '16'.

Конечно, вернуть несколько значений из функции вы таким образом не можете, но эта проблема легко решается, если применить в качестве возвращаемого значения список:

function small_numbers() {
          return array (0, 1, 2); }
list ($zero, $one, $two) = small_numbers();

А чтобы вернуть в качестве значения функции ссылку, вы должны использовать оператор & как в объявлении функции, так и при присвоении возвращаемого значения некоторой переменной:

function &returns_reference( ) {
          return $someref;
}
$newref =&returns_reference( );

3.4.6. Переменные функции

PHP поддерживает концепцию переменных функций. Это означает, что если имя переменной заключено в скобки, PHP-машина ищет функцию с именем, которое представляет собой значение переменной, заключенной в скобки, и при обнаружении такой функции пытается ее выполнить. Это средство, среди всего прочего, используется для организации обратных вызовов, построения функциональных таблиц и т. п.

Необходимо иметь в виду, что переменные функции не будут работать с такими конструкциями, как echo(), unset (),isset() и empty (). В этом как раз и состоит одно из принципиальных различий между функциями РНР и конструкциями языка:

<?рhр
function foo() {
          echo "Мы внутри foo()<br>\n";
}

function bar( $arg = '' ) {
          echo "Мы внутри bar(); аргумент имеет значение - '$arg'.<br>\n"; }

$func = ' foo' ;
$func() ;
$func = ' bar ' ;
$func( 'test' );
?>

Результат выполнения этой программы представлен на рис. 3.2.

Рис. 3.2. Подстановка имени вызываемой подпрограммы может запутать кого угодно

назад
далее

Сайт управляется системой uCoz