Php занятие 5. функции языка

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

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


Функции сокращают количество повторений кода в программе. Функция позволяет извлекать часто используемый блок кода в один компонент. Теперь вы можете выполнить ту же задачу, вызывая эту функцию в любом месте вашего скрипта, без необходимости копировать и вставлять один и тот же блок кода снова и снова. Функции делают код намного проще в обслуживании — поскольку созданная однажды функция может использоваться многократно, поэтому любые изменения, сделанные внутри функции, автоматически внедряются во всех местах. Функции облегчают устранение ошибок. Когда программа подразделяется на функции и возникает какая-либо ошибка, вы точно знаете, какая функция вызвала ошибку и где ее найти. Поэтому исправление ошибок становится намного проще. Функции могут быть повторно использованы в другом приложении — поскольку функция отделена от остальной части скрипта, эту же функцию легко использовать в других приложениях, просто включив файл php, содержащий эту функцию.

Следующая глава покажет вам, как легко вы можете определить свою собственную функцию в PHP.

Introduction

Anonymous functions in PHP can be quite verbose, even when they only perform a simple operation. Partly this is due to a large amount of syntactic boilerplate, and partly due to the need to manually import used variables. This makes code using simple closures hard to read and understand. This RFC proposes a more concise syntax for this pattern.

function array_values_from_keys($arr, $keys) {
    return array_map(function ($x) use ($arr) { return $arr$x; }, $keys);
}

The actual operation performed by the closure is trivial, but is somewhat lost amidst the syntactic boilerplate. Arrow functions would reduce the function to the following:

function array_values_from_keys($arr, $keys) {
    return array_map(fn($x) => $arr$x, $keys);
}

The question of short closures has been extensively discussed in the past. A previous short closures RFC went through voting and was declined. This proposal tries to address some of the raised concerns with a different choice of syntax that is not subject to the limitations of the previous proposal.

Additionally, this RFC includes a lengthy discussion of different syntax alternatives as well as binding semantics. Unfortunately short closures are a topic where we’re unlikely to find a “perfect” solution, due to significant constraints on the syntax and implementation. This proposal makes the choice that we consider “least bad”. Short closures are critically overdue, and at some point we’ll have to make a compromise here, rather than shelving the topic for another few years.

Возвращение значений функцией, Return

Функция может не только выполнять какие-то конкретные действия, выводя их значения на экран, она также может просто возвращать в программу какие-то вычисленные значения.

Внутри такой функции используется оператор возврата (с англ. «вернуть»), после которого указывается возвращаемое значение (или переменная, массив, выражение и т.п.)

Вызов такой функции осуществляется либо через присваивание переменной, либо сразу через вывод на экран.

Пример: описать функцию с двумя аргументами, возвращающую сумму данных аргументов

Решение:

1
2
3
4
5
6
7
8
function sum($a, $b) {
    return $a + $b;
}
// 1 вариант вызова
echo sum(1, 2) ;
// 2 вариант вызова
$x=sum(1, 2);
echo $x;

Задание php 5_3: описать функцию с одним аргументом, возвращающую степень двойки. Степень передавать в качестве аргумента. Установить значение по умолчанию () для аргумента

Лабораторная работа 2:

Задание 1

  1. Опишите функцию
  2. Задайте для функции первый аргумент , в него будет передаваться массив, содержащий структуру меню
  3. Задайте для функции второй аргумент со значением по умолчанию равным (логический тип данных — true-истина, false-ложь).

Данный параметр указывает, каким образом будет отрисовано меню — вертикально или горизонтально

Задание 2

  1. Откройте файл c с отрисовкой меню
  2. Скопируйте код, который создает массив menu и вставьте скопированный код в данный документ
  3. Скопируйте код, который отрисовывает меню
  4. Вставьте скопированный код в тело функции
  5. Измените код таким образом, чтобы меню отрисовывалась в зависимости от входящих параметров и

Задание 3

  1. Отрисуйте вертикальное меню вызывая функцию с одним параметром
  2. Отрисуйте горизонтальное меню вызывая функцию со вторым параметром равным
  3. Сохраните код в отдельном файле

Future Scope

These are some possible future extensions, but we don’t necessarily endorse them.

Multi-statement bodies

This RFC allows arrow functions to only have a single, implicitly returned expression. However, it is common in other languages to also support of form that accepts a code block with an arbitrary number of statements:

fn(params) => {
    stmt1;
    stmt2;
    return expr;
}
// or possibly just
fn(params) {
    stmt1;
    stmt2;
    return expr;
}

This feature is omitted in this RFC, because the value-proposition of this syntax is much smaller: Once you have multiple statements, the relative overhead of the conventional closure syntax becomes small.

An advantage of supporting this syntax is that it is possible to use a single closure syntax for all purposes (excluding cases that need to control binding behavior), rather than having to mix two different syntaxes depending on whether they use a single expression or multiple statements.

Switching the binding mode

Arrow functions use by-value binding by default, but could be extended with the possibility to capture variables by reference instead. This is particularly useful in conjunction with the previous section, as multi-statement bodies are more likely to be interested in modifying variables from the outer scope. A possible syntax would be:

$a = 1;
$fn = fn() use(&) {
    $a++;
};
$fn();
var_dump($a); // int(2)

Another possibility would be to keep by-value binding as the default, but allow using some explicitly specified variables by reference:

$a = 1;
$b = 2;
$fn = fn() use(&$a) {
    $a += $b;
};
$fn();
var_dump($a); // int(3)

In this example is still implicitly used by-value, but is explicitly used by-reference. However, this syntax may be confusing as it is very close to the normal closure syntax, which would not implicitly bind .

Allow arrow notation for real functions

It would be possible to allow using the arrow notation for normal functions and methods as well. This would reduce the boilerplate for single-expression functions like getters:

class Test {
    private $foo;
    private $bar;
 
    fn getFoo() => $this->foo;
    fn getBar() => $this->bar;
}

There are some possible variations of this, e.g. allow but not .

PHP Return Type Declarations

PHP 7 also supports Type Declarations for the statement. Like with the type declaration for function arguments, by enabling the strict requirement, it will throw a «Fatal Error» on a type mismatch.

To declare a type for the function return, add a colon ( ) and the type right before the opening curly ( )bracket when declaring the function.

In the following example we specify the return type for the function:

Example

<?php declare(strict_types=1); // strict requirementfunction addNumbers(float $a, float $b) : float {  return $a + $b;}echo addNumbers(1.2, 5.2); ?>

You can specify a different return type, than the argument types, but make sure the return is the correct type:

Example


<?php declare(strict_types=1); // strict requirementfunction addNumbers(float $a, float $b) : int {  return (int)($a + $b);} echo addNumbers(1.2, 5.2); ?>

Области видимости переменных

function sayHello($name)
{
  echo "<h1>Hello, $name!</h1>";
  $name = "Вася";
}

sayHello("John");

$name = "Mike";
sayHello($name);
echo$name;//???

//Обращение к глобальным переменным: вариант 1
function sayHello($name)
{
  echo "<h1>Hello, $name!</h1>";
  global $name;
  $name = "Вася";
}

$name = "Mike";
sayHello($name);
echo$name;//Вася


//Обращение к глобальным переменным: вариант 2
function sayHello($name)
{
  echo "<h1>Hello, $name!</h1>";
  $GLOBALS= "Вася";
}

$name = "Mike";
sayHello($name);
echo$name;//Вася


//Обращение к глобальным переменным: вариант 3
function sayHello(&$name)
{
  echo "<h1>Hello, $name!</h1>";
  $name = "Вася";
}

$name = "Mike";
sayHello($name);
echo$name;//Вася
sayHello("John"); //ERROR!!!

PHP пользовательские функции

Пользовательские функции — те, которые не предусмотрены синтаксисом языка, а созданы пользователем в целях решения поставленной задачи.

Пример: создать функцию без аргументов, которая выводит на экран приветствие

Решение:

1
2
3
4
5
6
7
8
9
10
11
12
// описание функции
function sayHello(){
	echo "Привет!<br/>";
}
 
// вызов функции
sayHello();
 
// проверка существования функции
if (function_exists("sayHello")) {
	echo "есть";
	}

Результат:

Привет!
есть
  • Внутри функции может быть любая последовательность операторов и даже описание другой функции.
  • Все функции имеют глобальную область видимости, это значит, что они могут быть вызваны в любом месте программы, даже если были определены внутри функции и наоборот.

Рассмотрим пример:

Пример: создать первую функцию, внутри которой описать вторую функцию

Выполнение:

1
2
3
4
5
6
7
8
function function1() {
  echo "<p>Первая функция</p>";
    function function2() {
     echo "<p>Вторая функция</p>";
    }
}
function1();
function2();

Результат:

Первая функция
Вторая функция

Пример иллюстрирует, что средства php не позволяют создавать локальных функций, т.е. которые будут «видны» только в определенных местах кода программы. В нашем случае должна быть локальной, т.е. область ее видимости — только функция . Вызывая локальную функцию из общей программы, должна выдаваться ошибка. Но в php данный механизм отсутствует, и ошибки нет. Таким образом обе функции в примере глобальные.

Создание функции php с аргументами

Рассмотрим синтаксис функции с аргументами на примере

Пример: создать функцию, которая выводит на экран приветствие с именем, передаваемым в качестве аргумента (например, Привет, Вася!)

Решение:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// описание функции
function sayHello($name){
	echo "Привет, $name!<br/>";
}
 
// вызов функции вариант 1
sayHello("Вася");
 
// вызов функции вариант 2
$name="Вася";
sayHello($name);
 
// вызов функции вариант 3
$myFunc="sayHello"; // здесь круглые скобки не нужны!
$myFunc("Вася");

Все три способа вызова функции равнозначны.

Задание php 5_1: Написать функцию с двумя аргументами, возвращающую результат возведения числа в степень.

Примечание: степень в php вычисляется при помощи функции pow() где — число, — степень

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

Рис. 5.2. Локальные и глобальные переменные в php

изменять значения аргумента и на уровне программы

Решение:

1
2
3
4
5
6
7
function add_str(&$str2)
{
    $str2 .= 'и кое-что еще.';
}
$str1 = 'Просто строка, ';
add_str($str1);
echo $str1; // выведет 'Просто строка, и кое-что еще.'

Лабораторная работа 1:Задание 1

  1. Опишите функцию
  2. Задайте для функции три аргумента: , ,

Задание 2

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

Задание 3

Отрисуйте таблицу умножения вызывая функцию с различными параметрами

Аргументы по умолчанию

В php в пользовательских функциях можно задавать значения по умолчанию для аргументов. Т.е. если в программе не передать значение аргумента, то аргумент примет то значение, которое установлено по умолчанию.


Рис. 5.4. Значение по умолчанию

Пример: создать функцию с аргументом для вывода приветствия. Установить значение по умолчанию для аргумента равное «Гость»

Решение:

1
2
3
4
5
6
7
function sayHello($p,$name = "Гость"){
	echo "$p, $name!<br/>";
}
 
sayHello("Привет","Вася"); // Привет, Вася!
sayHello("Здравствуйте"); // Здравствуйте, Гость!
sayHello("Привет",null); // Привет, !

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

Задание php 5_2: откройте выполненную этого урока. Продолжите выполнение задания:Задание 4

  1. Откройте предыдущее задание с отрисовкой таблицы в функции. Измените входящие параметры функции на параметры по умолчанию

Задание 5

Отрисуйте таблицу умножения вызывая функцию без параметров Отрисуйте таблицу умножения вызывая функцию с одним параметром Отрисуйте таблицу умножения вызывая функцию с двумя параметрами

Понятие «область видимости переменной»

Вы можете объявить переменные в любом месте PHP-скрипта. Но расположение объявления определяет степень видимости переменной в программе PHP, то есть где переменная может быть доступна. Эта доступность называется «область видимости переменной».

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

<?php
// Объявление функции
function test(){
  $greet = "Hello World!";
  echo $greet;
}

test(); // Результат: Hello World!

echo $greet; // Вызовет ошибку
?>

Так же, если вы попытаетесь получить доступ к внешней переменной внутри функции, вы получите ошибку «undefined varible», как показано в следующем примере:

<?php
$greet = "Hello World!";

// Объявление функции
function test(){
  echo $greet;
}

test(); // Вызовет ошибку

echo $greet; // Результат: Hello World!
?>

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

Функции с параметрами

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

function myFunc($oneParameter, $anotherParameter){
  // Тело функции
}

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

Функция getSum() в следующем примере принимает два целочисленных значения в качестве аргументов и просто складывает их вместе и затем отображает результат в браузере.

<?php
// Объявление функции
function getSum($num1, $num2){
  $sum = $num1 + $num2;
  echo "Сумма чисел $num1 и $num2: $sum";
}

// Вызов функции с аргументами
getSum(10, 20);
?>

Возвращение значений из функции

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

<?php
// Объявление функции
function getSum($num1, $num2){
  $total = $num1 + $num2;
  return $total;
}

// Вывод возвращаемого значения
echo getSum(5, 10); // Результат: 15
?>

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

<?php
// Объявление функции
function divideNumbers($dividend, $divisor){
  $quotient = $dividend / $divisor;
  $array = array($dividend, $divisor, $quotient);
  return $array;
}

// Инициализация переменных значениями из массива
list($dividend, $divisor, $quotient) = divideNumbers(10, 2);
echo $dividend; // Результат: 10
echo $divisor; // Результат: 2
echo $quotient; // Результат: 5
?>

С этим читают