Функции в PHP


Содержание

Создание функций в PHP

В PHP пользовательские функции создаются с помощью ключевого слова function , за которым следует имя функции, перечень её аргументов (количество которых может быть нулевым) и тело самой функции. Назначение функций очень широкое. Если вам приходится неоднократно выполнять какой-то один и тот же код, вам следует поместить его в свою функцию, и затем просто вызывать её там, где вам нужно. Имя функции должно начинаться с символа латинского алфавита, может содержать цифры и символ нижнего почеркивания. По принятому соглашению имена функций в PHP начинаются со строчных букв, а если в имени используетя не одно слово, то каждое новое начинается с заглавной буквы либо сразу, либо после символа нижнего подчеркивания.

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

Функция определена. Для того, чтобы вызвать её, в сценарии в нужном месте достаточно указать имя функции и передать ей необходимые параметры (если это требуется).

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

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

Суперглобальные массивы

$_SERVER , $_SESSION , $_COOKIE и другие — это суперглобальные массивы. Их данные доступны в любом месте сценария. Вот лишь несколько из них:

  • $_SERVER[‘REMOTE_ADDR’] — IP-адрес пользователя;
  • $_SERVER[‘SERVER_NAME’] — имя сервера;
  • $_SERVER[‘DOCUMENT_ROOT’] — корневой каталог сайта;
  • $_SERVER[‘REQUEST_URI’] — запрошенный адрес документа.

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

Если функция должна иметь доступ к данным переменной или константы, объявленных вне её тела, эти данные ей можно передавать в виде аргументов. Каждая функция может принимать любое количество аргументов (параметров), в том числе и нулевое. В приведенном примере мы не передавали функции никакие аргументы. Рассмотрим другой пример.

Необязательные параметры (параметры по умолчанию) функции

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

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

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

Возвращение значения

Одной из главный особенностей функций является их способность возвращать результат. Не всегда в сценарии необходимо что-то делать с результатом работы функции. Чаще его нужно просто сохранить и использовать в другом месте сценария совсем для других целей[?] собственно, для вывода некоего значения на экран функции вообще практически никогда не используются. . Для того, чтобы функция вернула значение в то место сценария, из которого она была вызвана, необходимо воспользоваться оператором return . Любой код, который следует за оператором return , не выполняется (если оператор return сработал как надо).

Функции в PHP, их синтаксис, создание и вызов

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

Это простая функция, которая рассчитывает квадрат числа.

Сначала, мы создаем функцию прописывая ключевое слово function , после которого мы можем задать любое имя для нашей функции, в нашем случае это имя — square . В скобках мы передаем аргумент функции (то, что нам нужно посчитать), в нашем случае это переменная — $num (какое-нибудь число).

Далее, в теле функции, мы прописываем все, что мы хотим, чтобы функция выполняла. В нашем случае, функция задает переменной $square квадрат числа, которое находится в $num , после мы просто выводим результат функции $square , с помощью оператора echo .

После этих действий, мы можем в любой части нашей страницы вызвать созданную функцию вот так: square(какое-нибудь число);

PHP: Функции

Автор: Артемьев Сергей Игоревич
ICQ: 438856621
email: _spin_@bk.ru

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

Функции бывают пользовательские и системные. Пользовательские функции (как следует из названия) программист пишет самостоятельно. Системные функции всегда доступны из любого места скрипта и объявлять их не надо.

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

Любая функция имеет имя, список параметров, тело функции и возвращаемые данные. Правила именования функций аналогичны правилам дя переменных. Параметры записываются в скобках через запятую, а если функции не требуются параметры — должны ставится пустные скобки «()». Любая функция должна возвращать какое-либо значение. Если в коде функции не встречается выражение return, то считается, что функция возвращает пустое значение. Немаловажный факт — в PHP тип возвращаемых данных заранее не определён. Поэтому одна функция может возвращать значения с различными типами данных в зависимости от входных параметров.

Теперь в любом месте скрипта можно написать

и в браузер будет выведено

Рассмотрим более интересный вариант применения — функцию преобразования данных. Например, у нас есть список, содержащий полные имена, фамилии и отчества сотрудников. Нам для составления отчёта надо преобразовать полное ФИО к формату фамилии с инициалами, т.е. преобразовать «Иванов Александр Владимирович» в «Иванов А.В.».

Функция для преобразования будет выглядеть так:

а код для вызова функции будет выглядеть так:

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

  1. В теле функции используются копии параметров, поэтому все изменения переменных будут потеряны привыходе из функции. Мы уже рассматривали такой пример при изучении областей видимости переменных.
  2. Если параметр должен быть изменён в функции — необходимо передавать его по ссылке, т.е. в описании функции надо перед именем параметра добавить «&»: function func($p1, &$p2)
  3. В старых версиях PHP функция должна была быть объявлена до первого использования, но в PHP версии 4.3 и выше порядок объявления и использования функции может быть любым.

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

лабы по информатике, егэ

лабораторные работы и задачи по программированию и информатике, егэ по информатике

PHP занятие 5. Функции языка

Встроенные php функции

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

Все функции языка PHP подразделяются на:

Встроенные функции — это предусмотренные синтаксисом языка конструкции, выполняющие конкретные действия. Примером могут служить рассмотренные ранее функции echo() и print() .

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

Что необходимо знать про любые функции:

  • после названия функции всегда ставятся круглые скобки (могут быть пустые или с аргументами функции внутри, перечисленными через запятые);
  • функция может принимать информацию из программы через список аргументов, разделенных запятыми (аргументы читаются слева направо);
  • если в функцию передаются аргументы не того типа, на который она «рассчитывает» (например string вместо array ), то будет выдаваться либо NULL либо ошибка;
  • для вызова функции достаточно написать ее имя и список фактических аргументов в круглых скобках.

Рис. 5.1. Пример использования встроенных функций php

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

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

// описание функции function sayHello()< echo "Привет!
«; > // вызов функции sayHello(); // проверка существования функции if (function_exists(«sayHello»))

Результат:

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

Результат:

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

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

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

// описание функции function sayHello($name)< echo "Привет, $name!
«; > // вызов функции вариант 1 sayHello(«Вася»); // вызов функции вариант 2 $name=»Вася»; sayHello($name); // вызов функции вариант 3 $myFunc=»sayHello»; // здесь круглые скобки не нужны! $myFunc(«Вася»);

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

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

Передача аргументов по ссылке

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

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

Рис. 5.3. Передача аргумента по ссылке

function add_str(&$str2) < $str2 .= 'и кое-что еще.'; >$str1 = ‘Просто строка, ‘; add_str($str1); echo $str1; // выведет ‘Просто строка, и кое-что еще.’

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

Задание 2


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

Задание 3

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

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

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

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

function sayHello($p,$name = «Гость»)< echo "$p, $name!
«; > sayHello(«Привет»,»Вася»); // Привет, Вася! sayHello(«Здравствуйте»); // Здравствуйте, Гость! sayHello(«Привет»,null); // Привет, !

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

Задание 5

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

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

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

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

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

    function sum($a, $b) < return $a + $b; >// 1 вариант вызова echo sum(1, 2) ; // 2 вариант вызова $x=sum(1, 2); echo $x;

    Задание 1

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

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

    Задание 2

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

    Задание 3

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

    Создание функций в PHP

    Наконец-то, мы подобрались к теме создания функций в PHP. Тема эта безумно важная и, пожалуй, функции в PHP создаются очень часто. И, разумеется, создавать их Вам придётся. Напоминаю, что функция — это блок кода, который является определённым шаблоном, действие которого зависит от входных параметров. А теперь переходим к созданию и использованию функций в PHP.

    Давайте с Вами напишем пример элементарной функции, которая просто печатает «Hello World«:

    В данном примере мы создали функцию с именем «printHello» без параметров (внутри круглых скобок ничего нет), затем мы в фигурных скобок написали код функции. То есть в данном случае, мы выводим строку. За пределами функции мы её вызываем. Как видите, всё очень просто. Но цена данной функции равна нулю, хотя бы потому, что она работает всегда одинаково. Безусловно, такое бывает нужно, поэтому не надо думать, что такой пример функции вообще бессмыслен. Однако, чаще всё-таки функция требует параметра, и давайте с Вами создадим функцию, которой будем передавать строку, а затем эту строку выводить:

    Здесь мы создали функцию, но уже с параметром. И дальше значение этого параметра мы и выводим через echo. За пределами функции printHello() мы её вызываем и передаём строку «Hello World. «. Как видите, и тут всё просто.

    И последнее, что хочется сказать, так это о параметрах по умолчанию, которые позволяют создавать функции с переменным числом параметров. Предлагаю решить такую задачу: создать функцию, которая будет принимать в качестве первого параметра массив, а в качестве второго параметра — булевскую переменную (true или false), значение по умолчанию которой будет false:

    Здесь смысл следующий: задача функции — формировать из массива строку, то есть просто превратить массив в строковый тип. В данном примере, самое интересное — это параметр bool, который имеет значение по умолчанию. Если она false (как по умолчанию, то есть если не указывали иного значения), то строка сразу печатается в браузере, а если передали true (как при втором вызове функции), то строка возвращается (return $str) функцией. Вот такой простой пример на создание функций с параметрами по умолчанию.

    Копирование материалов разрешается только с указанием автора (Михаил Русаков) и индексируемой прямой ссылкой на сайт (http://myrusakov.ru)!

    Добавляйтесь ко мне в друзья ВКонтакте: http://vk.com/myrusakov.
    Если Вы хотите дать оценку мне и моей работе, то напишите её в моей группе: http://vk.com/rusakovmy.

    Если Вы не хотите пропустить новые материалы на сайте,
    то Вы можете подписаться на обновления: Подписаться на обновления

    Если у Вас остались какие-либо вопросы, либо у Вас есть желание высказаться по поводу этой статьи, то Вы можете оставить свой комментарий внизу страницы.

    Порекомендуйте эту статью друзьям:

    Если Вам понравился сайт, то разместите ссылку на него (у себя на сайте, на форуме, в контакте):

    Она выглядит вот так:

  • BB-код ссылки для форумов (например, можете поставить её в подписи):
  • Комментарии ( 22 ):

    Как я понял в примере 2, что printHello(«Hello World. «); применяет значение для переменной $str, обозначенной функцией function printHello($str)? Тогда если допустим попытаться вывести переменную под printHello(«Hello World. «); например простым echo $str; не выводится повторно, почему?

    Если Вы хотите вот так: То так работать и не будет, так как переменная $str не определна.

    Здравствуйте Михаил! Я уже большую часть ваших статей прочитал, но до сих пор не могу понять как их можно применить на практике при создании сайта

    Надо не только читать, но ещё и что-то делать, какие-нибудь упражнения придумывать и делать их. Самое элементарное, хотя бы скопировать код из статьи и посмотреть, как он работает. Может быть, как-нибудь отредактировать его. Вот когда будете это делать, тогда и появится мысли, как это можно использовать при создании сайта.

    Илон Маск рекомендует:  Развевающийся флаг

    Здравствуйте .По какому учебнику php учились вы?

    PHP 5 в подлиннике. Автор: Дмитрий Котеров.

    функции на любом сайте пригодятся. А уж «мигающая кнопка» вряд ли)

    Михаил, а можете ли вы сделать статью/видеоурок о том, как сделать, чтобы если человек допустим в комментарии введёт слово «Превет», то оно автоматически исправлялось бы на «Привет». Т.е. функцию исправления ошибок

    Я запишу Вашу идею, спасибо. Может быть в дальнейшем реализую.

    Как создать доску обьявлений без регистрации?

    Для этого надо знать PHP и MySQL, затем написать движок.

    Загугли «Myrusakov чат» и измени стили єтого чата. Будет выглядеть как доска обьявлений.

    Здравствуйте Михаил, может я со своим вопросом забегаю немного вперед, но посоветуйте пожалуйста, как решить следующую проблему. В движке, внутри класса есть функция открытия страниц выглядит она вот так: return include «(имя страницы).php» В файле index.php написано следующее: echo ($(класс)->(эта функция)); В итоге выводится нормальная страница, но на конце всегда стоит ‘1’. Я так понял это результат выполнения функции include (true). Вопрос как убрать ‘1’, желательно не используя строковые функции?

    Не надо писать return, просто include и всё.

    Спасибо Михаил, ваш совет очень помог

    Здравствуйте Михаил, а можно ли как-нибудь обрабатывать переменные, объявленные вне функции, внутри функции?

    Да, для этого есть глобальные переменные. Достаточно её объявить за пределами функции, а внутри функции написать global $имя_переменной; И дальше её можно использовать внутри функции.

    Михаил, я не понял как работает эта строка . Что такое count и что делает тут знак меньше. И пожалуйста, в ответе дайте ссылки на уроки где можно подробно это все самому изучить. Спасибо. for ($i = 0; $i Ответить

    Здравствуйте, Алексей. Рекомендую изучить курс «PHP & mySQL» с нуля до гуру. Ссылка на курсы: http://srs.myrusakov.ru/php

    эта строка это цикл. $i=0 это значение переменной; $i Ответить

    Давненько в этой теме ни кто не отписывался. Я, по урокам Михаила, и не только, создал свой домашний сайт на php. Научился создавать базы данных, таблицы в них, выводить данные на страницы сайта (не без проблем конечно). На одном из сайтов наткнулся на упоминание о функции (dop_function.php), то есть, на том сайте сказано, что, данную функцию можно применять для скрытия информации для незарегистрированных пользователей. У меня возник вот такой вопрос/просьба: Можно попросить написать конкретный пример реализации функции скрытия контента?


    Для добавления комментариев надо войти в систему.
    Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.

    Copyright © 2010-2020 Русаков Михаил Юрьевич. Все права защищены.

    Функции в PHP

    Всем доброго времени суток. На связи Алексей Гулынин. В прошлой статье вы узнали, как перебрать массив в php. В данной статье я бы хотел рассказать об одной из важнейших тем — это функции в php. Синтаксис определения функции в общем виде такой:

    Объявление функции начинается с ключевого слова function . Далее идёт название функции (название не зависит от регистра букв). Затем в скобках указываются параметры функции. Параметры могут быть как со значениями (параметры по умолчанию), так и без них. Также в функции могут отсутствовать параметры вовсе. После задания параметров, в квадратных скобках (тело функции) содержится вся логика работы функции, т.е. все операторы.

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

    Функцию можно создавать в любом месте программы. Мы можем применять функцию, до того, как она определена. Это возможно из-за того, что в PHP фазы трансляции и исполнения разделены. Злоупотреблять данной возможностью я не советую, поэтому советую объявлять функции всегда в начале, либо в самом начале подключать файл с пользовательскими функциями через инструкцию require_once .

    Все переменные, которые описаны в теле функции, являются локальными. Они существуют только в теле функции и перестают существовать после окончания функции. Давайте напишем простой пример:

    Для того, чтобы значение изменилось, необходимо передавать ссылку function addTen(&$a). После этого, в конце мы увидим, что выведено число 30.

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

    Функция func_get_args() возвращает список всех аргументов, указанных при вызове функции.

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

    Проверить существует ли функция можно с помощью другой функции (тавтология) function_exists() , которая возвращает true, если функция существует:

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

    1) Прежде чем написать функцию, посмотрите документацию, может быть такая функция уже есть.

    2) Функция должна быть компактной, она не должна иметь большие размеры. Обычно функция должна быть в 20-30 строк. Где-то ещё слышал, что вся функция должна умещаться на экран

    3) Чем меньше своих функций — тем надежнее работает программа, и нужно меньше времени, чтобы её тестировать.

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

    В данной статье вы узнали, что такое функции на PHP и как их создать.

    На связи был Алексей Гулынин, оставляйте свои комментарии, увидимся в следующих статьях.

    9 PHP функций, которые нужно знать всем

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

    1. Создание функций с переменным числом аргументов

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

    Но для начала, вспомним как мы создаём функции обычным образом:

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

    2. Используем Glob() для поиска файлов

    Часто названия функций говорят сами за себя. Такого нельзя сказать о функции glob().

    Если не вдаваться в подробности, её функциональность схожа с методом scandir(). Она позволяет найти необходимый файл по шаблону:

    Для нахождения файлов нескольких типов надо писать так:

    Так же можно в шаблоне указать путь:

    Для того чтобы получить полный путь к документу используйте метод realpath():

    3. Информация об используемой памяти

    Если вы будете отслеживать количество памяти, которое съедается на работу ваших скриптов то, наверное, чаще будете их оптимизировать.

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

    4. Информация о процессоре

    Для этого необходимо использовать метод getrusage(). Но учтите, что на Windows эта функция работать не будет.

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

    • ru_oublock: количество операций блочной записи
    • ru_inblock: количество операций блочного чтения
    • ru_msgsnd: количество отправленных сообщений
    • ru_msgrcv: количество принятых сообщений
    • ru_maxrss: максимальный размер невыгружаемого набора
    • ru_ixrss: общий объем разделяемой памяти
    • ru_ >Для того чтобы узнать какие ресурсы вашего процессора используются скриптом, вам необходимо значение ‘user time’ (время работы в пользовательском режиме) и ’system time’ (время работы в привилегированном режиме). Вы можете получить результат как в секундах, так и в микросекундах. Для того чтобы превратить общее количество секунд в десятичное число, вам необходимо разделить значение микросекунд на 1 миллион и добавить к значению секунд.

    Запутанно как-то. Вот пример:

    Хотя выполнение скрипта заняло около 3-х секунд, процессор не был сильно нагружен. Дело в том, что при вызове (sleep) скрипт практически не потребляет ресурсов процессора. Вообще существует множество задач, которые занимают значительное время, но при этом не используют процессор. К примеру, ожидание операций связанных с диском. Так что вы не всегда используете процессорное время в своих скриптах.

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

    Время работы в привилегированном режиме (System Time) – это время, которое процессор затрачивает на выполнение системных запросов к ядру от имени программы. Пример:

    Теперь системного времени затратилось намного больше, чем в прошлом примере. Всё благодаря методу microtime(), который использует ресурсы системы.

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

    5. Магические константы

    В PHP существует множество магических констант, таких как номер текущей строки (__LINE__), путь к файлу (__FILE__), путь к каталогу (__DIR__), имя функции (__FUNCTION__), имя класса (__CLASS__), имя метода (__METHOD__) и пространства имён (__NAMESPACE__).

    Все мы их рассматривать не будем. Посмотрим только лишь парочку:

    Используйте __LINE__ при отладке скриптов:

    6. Генерирование уникальных >Бывают такие моменты, когда вам надо сгенерировать уникальную строку. Множество раз я видел, что для решения этой задачи используют функцию md5():

    Но на самом деле для этих целей в PHP есть специальная функция uniqid()

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

    Для того чтобы уменьшить шансы получения дубликата, мы можем добавить префикс или использовать второй параметр (увеличит количество символов):

    Этот метод генерирует строки размером меньше, чем md5, тем самым вы сможете сэкономить место.

    7. Сериализация

    Вам когда-нибудь приходилось хранить комплексные данные в базе или в файле? Для того чтобы сконвертировать объект в строку в PHP предусмотрена специальная функция.

    Вообще говоря, этих методов 2: serialize() и unserialize()

    Вот так вот работают эти функции. Однако из-за бурного роста популярности JSON, в PHP 5.2 были добавлены 2 метода json_encode() и json_decode(). Их работа схожа с serialize():

    Этот вариант более компактный и совместимый с другими языками, такими как JavaScript. Однако при работе с очень навороченными объектами может возникнуть потеря данных.

    8. Сжатие строк

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

    В следующем примере продемонстрируем работу функций gzcompress() и gzuncompress():

    В наших силах уменьшить объём текста на 50%. В этих же целях можно использовать методы gzencode() и gzdecode(), которые используют другой алгоритм сжатия.

    9. Выполнить перед завершением

    В PHP существует функция register_shutdown_function(), которая позволит вам выполнить какой-то код перед завершением работы скрипта.

    Допустим, вы хотите узнать какую-то информацию… Время работы скрипта:

    На первый взгляд это может показаться тривиальной задачей. Для этих целей, вы можете поместить код в конце файла. Однако если перед этим где-то сработает функция exit(), этот код никогда не сработает. Так же, он не сработает если на странице будет ошибка или пользователь прервёт загрузку страницы (нажав на соответствующую кнопку в своём браузере);

    При использовании метода register_shutdown_function() код выполнится в любом случае:

    Вывод

    PHP это целая планета, которая не перестаёт нас удивлять своим содержимым. А что думаете вы о данных функциях?

    Данный урок подготовлен для вас командой сайта ruseller.com
    Источник урока: www.net.tutsplus.com/tutorials/php/9-useful-php-functions-and-features-you-need-to-know/
    Перевел: Станислав Протасевич
    Урок создан: 4 Марта 2011
    Просмотров: 86844
    Правила перепечатки


    5 последних уроков рубрики «PHP»

    Фильтрация данных с помощью zend-filter

    Когда речь идёт о безопасности веб-сайта, то фраза «фильтруйте всё, экранируйте всё» всегда будет актуальна. Сегодня поговорим о фильтрации данных.

    Контекстное экранирование с помощью zend-escaper

    Обеспечение безопасности веб-сайта — это не только защита от SQL инъекций, но и протекция от межсайтового скриптинга (XSS), межсайтовой подделки запросов (CSRF) и от других видов атак. В частности, вам нужно очень осторожно подходить к формированию HTML, CSS и JavaScript кода.

    Подключение Zend модулей к Expressive

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

    Совет: отправка информации в Google Analytics через API

    Предположим, что вам необходимо отправить какую-то информацию в Google Analytics из серверного скрипта. Как это сделать. Ответ в этой заметке.

    Подборка PHP песочниц

    Подборка из нескольких видов PHP песочниц. На некоторых вы в режиме online сможете потестить свой код, но есть так же решения, которые можно внедрить на свой сайт.

    Функции

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

    Основная синтаксическая структура, обеспечивающая использование (или вызов) функции, показана ниже:

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

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

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

    Вызов встроенных функций PHP

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

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

    Еще один вариант состоит в том, что полученный результат может вкладываться в более сложные выражения, как в следующем примере:

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

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

    Определение собственных функций

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

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

    Определения функций имеют следующую форму:

    Это означает, что определения функций состоят из перечисленных ниже четырех частей:

    Ключевое слово function.

    Имя, которое должно быть присвоено функции.

    Список параметров функции — имена переменных с префиксом в виде знака доллара, разделенные запятыми (параметры могут отсутствовать).

    Тело функции — набор операторов, заключенный в фигурные скобки.

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

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

    Интерпретатор PHP выполняет поиск функции по имени (если функция еще не была определена, то активизируется ошибка).

    Интерпретатор PHP подставляет значения параметров вызова (или фактических параметров) вместо переменных в списке параметров определения (или формальных параметров).

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

    Пример определения функции

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

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

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

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

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

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

    Использование меньшего количества параметров

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

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

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

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

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

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

    Подавлять ошибки, возникающие при выполнении любого отдельно взятого выражения с помощью операции управления выводом сообщений об ошибках — @. Знак этой операции можно помещать перед любым выражением для подавления сообщений об ошибках, возникающих только при выполнении этого выражения. Например, если во время вызова функции my_function() вырабатывается предупреждающее сообщение, то при вызове @my_function() этого не происходит. Следует отметить, что и данный вариант является опасным, поскольку подавляются сообщения об ошибках всех типов за исключением ошибок интерпретации.

    Функции и область определения переменных

    Про область определения переменных и описание локальных, глобальных, суперглобальных и статических переменных мы говорили в статье «Переменные и константы» ранее. Напомню, любая переменная объявленная внутри функции является локальной, ее можно сделать глобальной за счет использования ключевого слова global. Статические переменные используются внутри функции и сохраняют свое значение между вызовами этой функции. Суперглобальные переменные, представленные в виде массивов, доступны повсеместно.

    Область определения функции

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

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

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

    Рекурсия

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

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

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

    Это означает, что начиная с версии PHP4 можно без каких-либо проблем определять рекурсивные функции (функции, вызывающие сами себя). Например, как показано ниже, можно определить рекурсивную функцию, а затем сразу же вызвать ее:

    В результате в окне браузера отображается следующий вывод:

    Пример использования рекурсии в PHP

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

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

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

    приводит к получению в окне браузера такого вывода:

    Взаимно рекурсивные функции

    Переменное количество параметров


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

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

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

    Использовать функции с переменным количеством параметров (func_num_args(), func_get_arg() и func_get_args()).

    В следующих разделах каждая из этих возможностей рассматривается отдельно.

    Параметры, заданные по умолчанию

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

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

    В окне браузера формируется примерно такой вывод, как показано ниже:

    Переменное количество параметров при вызове функции

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

    Использование массивов для замены многочисленных параметров

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

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

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

    Использование многочисленных параметров

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

    Функция func_num_args()

    He принимает параметров и возвращает данные о количестве параметров, переданных в функцию, из которой она вызвана.

    Функция func_get_arg()

    Принимает целочисленный параметр n и возвращает n-й параметр в функцию, из которой она вызвана. Нумерация параметров начинается с нуля.

    Функция func_get_args()

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

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

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

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

    В функции Sum() используется функция func_get_arg() для выборки отдельных параметров и устанавливаются пределы действия цикла с использованием результатов выполнения функции func_num_args(), поэтому не предпринимается попытка осуществить выборку большего количества параметров, чем фактически было передано.

    Вызов по значению

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

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

    Одно из наиболее важных различий между версией PHP5 и предшествующими ей версиями состоит в том, что в ней экземпляры объектов фактически всегда передаются по ссылке, даже при том, что любые параметры другого типа передаются по значению. Это связано с тем, что в версии PHP5 переменные типа «объект» хранят дескрипторы объектов, а не сами объекты, поэтому в режиме передачи параметров по значению фактически копируются сами дескрипторы, а не основополагающие объекты (более подробное обсуждение этого вопроса будет дано в разделе по объектно-ориентированному программированию в PHP).

    Ниже приведен пример очень простой функции, увеличивающей переданное ей в параметре число на 10:

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

    Передача параметров функции по значению

    Вызов по ссылке

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

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

    Теперь, после выполнения точно такого же вызова функции переменная $number изменяется и будет равна 30:

    Передача параметров функции по ссылке

    Дело в том, что в данном случае формальный параметр $a ссылается на переменную $number, поэтому его модификация в функции приводит к изменению переменной $number.

    Начиная с версии PHP4 ссылки на переменные могут также использоваться вне вызовов функции. Вообще говоря, в результате присваивания переменной ссылки на переменную (например, &$varname) имена этих двух переменных становятся псевдонимами по отношению друг к другу, а не отдельными переменными с тем же значением. Рассмотрим пример:

    который приводит к получению в окне браузера следующего вывода:

    Передача переменной по ссылке

    Переменные в качестве функций

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

    В определенном смысле это позволяет использовать функции в качестве данных. Подобный прием должен быть знаком квалифицированным программистам, работающим на языке C, и даже начинающим пользователям, которые применяют какую-либо разновидность языка Lisp (например, Scheme или Common Lisp). В частности, два приведенных ниже вызова функции полностью эквивалентны:

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

    Функции (function) на PHP. Урок 10

    2014-09-29 / Вр:01:49 / просмотров: 6896

    Итак, что такое функция (function)на PHP?

    Функция (function)- это мини-программа, которая выполняет какие-то полезные действия и выдает готовый результат.
    Давайте посмотрим на схемку:

    Попробуем по готовому шаблону функции написать мини программу.
    Готовый шаблон функции:

    Припустим, нам нужно написать функцию, которая сможет подсчитать сумму чисел 5 и 2 . Смотрим на шаблон и пишем:

    Разберем код .
    function suma() — это функция с именем suma ;
    echo 5 + 2; — в теле функции мы указали, что числа 5 и 2 нужно сложить вместе (5 + 2) ;
    suma(); — вызываем функцию. Вызов функции означает ее выполнение. То есть, задачка 5 + 2 должна быть выполнена и дать результат 7 .

    Теперь попробуем рассмотреть функции поэтапно.

    Этапы создания функции на PHP

    Этап I. Создание функции
    Вспомните готовый шаблон функции:

    Вот таким способом создается функция на PHP.
    Давайте в теле функции напишем текст « Я рад видеть вас на блоге bloggood.ru ».
    Только не забудьте: текст пишем через оператор вывода «echo».

    Теперь нужно вызвать функцию « bloggood_ru() ».

    Этап II. Вызов готовой функции на PHP
    Функция создана и теперь она должна быть выполнена. Для выполнения и вывода функции достаточно указать « имя функции(); »

    Это будет выглядеть вот так:

    Можно это сделать и так:

    Сохраните как « function.php » в папку « test-1 » локального сервера (см. урок 1).

    Введите в браузере адрес:

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

    Все примеры с функциями выше были без аргументов. Что такое аргумент я вам объясню на коде:

    Итак, я создал функцию с именем « bloggood_ru ». В параметрах (там, где скобки) прописал через запятую две переменные $a и $b .

    function bloggood_ru ( $a , $b )

    $a и $b – это и есть два аргумента.
    echo «$a + $b = «; – здесь я вывел на монитор текст. Результат: 5 + 5 =
    echo $a + $b; – здесь я указал функции, что переменную $a и $b нужно сложить вместе.
    bloggood_ru (15, 5); – вызвал функцию. Внимание: в скобках я указал два аргумента (15, 5) , которые ждет переменная $a и $b . Переменная $a получит первый аргумент – 15 , $b – второй 5 .

    Для тех, кто не понял, куда подставляется аргумент и в какой очередности, вот схема:

    Итак, готовый код:


    Сохраните как « function.php » в папку « test-1 » локального сервера (см. урок 1).

    Введите в браузере адрес:

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

    Разбор вызовов функций в PHP

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

    Обычно применяется метод strlen:

    Однако такой вариант примерно на 20% медленнее этого:

    Выглядит неплохо. Наверняка вы уже собрались открыть ваши исходники и заменить все вызовы strlen() на isset(). Но если внимательно прочитать оригинальную статью, то можно заметить, что причина 20-процентной разницы в производительности — многократные вызовы strlen(), порядка 60-80 тысяч итераций.

    Почему?

    Дело не в том, как strlen() вычисляет длины строк в PHP, ведь все они уже известны к моменту вызова этого метода. Большинство по возможности вычисляется еще во время компиляции. Длина PHP-строки, отправляемой в память, инкапсулируется в С-структуру, содержащую эту самую строку. Поэтому strlen() просто считывает эту информацию и возвращает как есть. Вероятно, это самая быстрая из PHP-функций, потому что она вообще ничего не вычисляет. Вот ее исходный код:

    Учитывая, что isset() не является функцией, причина 20-процентного проигрыша в производительности strlen() по большей части заключается в сопутствующих задержках при вызове функции в движке Zend.

    Есть и ещё один момент: при сравнении производительности strlen() с чем-либо ещё добавляется дополнительный opcode. А в случае с isset() используется лишь один уникальный opcode.

    Пример дизассемблированной структуры if(strlen()):

    А вот семантически эквивалентная структура if(isset()):

    Как видите, в коде isset() не задействуется вызов какой-либо функции (DO_FCALL). Также здесь нет opcode IS_SMALLER (просто проигнорируйте операторы RETURN); isset() напрямую возвращает булево значение; strlen() же сначала возвращает временную переменную, затем она передаётся в opcode IS_SMALLER, а уже финальный результат вычисляется с помощью if(). То есть в структуре strlen() используется два opcode, а в структуре isset() — один. Поэтому isset() демонстрирует более высокую производительность, ведь одна операция выполняется обычно быстрее, чем две.

    Давайте теперь разберёмся, как в PHP работают вызовы функций и чем они отличаются от isset().

    Вызовы функций в PHP

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

    Для начала разберём время выполнения (runtime) вызовов. Во время компиляции (compile time) на выполнение операций, связанных с PHP-функциями, требуется много ресурсов. Но если вы будете использовать кэш opcode, то во время компиляции у вас не будет проблем.

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

    Для понимания механизма вызова функции, необходимо знать две вещи:

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

    Вот почему в последнем примере говорится о вызове «внутренней» функции: strlen() представляет собой PHP-функцию, являющуюся частью С-кода. Если бы мы сделали дамп opcode «пользовательской» PHP-функции (то есть функции, которая написана на языке PHP), то могли бы получить либо точно такой же, либо какой-то другой opcode.

    Дело в том, что независимо от того, известна PHP эта функция или нет, он не генерирует такой же opcode во время компиляции. Очевидно, что внутренние PHP-функции известны во время компиляции, поскольку они объявляются до того, как запускается компилятор. Но ясности в отношении пользовательских функций может и не быть, потому что они могут вызываться ещё до своего объявления. Если говорить об исполнении, то внутренние PHP-функции эффективнее пользовательских, к тому же им доступно больше механизмов валидации.

    Из приведённого выше примера видно, что для управления вызовами функций используется больше одного opcode. Также нужно помнить, что функции имеют собственный стек. В PHP, как и в любом другом языке, для вызова функции сначала нужно создать стековый кадр и передать в него аргументы функции. Затем вы вызываете функцию, которая эти аргументы подтянет из стека для своих нужд. По завершении вызова вам придётся уничтожить созданный ранее кадр.

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

    Opcode SEND_VAR отвечает за отправку аргументов в стековый кадр. Компилятор в обязательном порядке генерирует такой opcode до вызова функции. Причём для каждой переменной создаётся свой собственный:

    Здесь вы видите ещё один opcode — SEND_VAL. Всего существует 4 вида opcode для отправки чего-либо в стек функции:

    • SEND_VAL: отправляет значение константы (строковое, целочисленное и т.д.)
    • SEND_VAR: отправляет PHP-переменную ($a)
    • SEND_REF: отправляет PHP-переменную в виде ссылки в функцию, которая принимает аргумент ссылкой
    • SEND_VAR_NO_REF: оптимизированный обработчик, применяемый в случаях с вложенными функциями

    Что делает SEND_VAR?

    SEND_VAR проверяет, является ли переменная ссылкой. Если да, то он её отделяет, тем самым создавая несоответствие ссылки. Почему это очень плохо, вы можете почитать в другой моей статье. Затем SEND_VAR добавляет количество ссылок на нее (ссылка здесь – это не ссылка в терминах PHP, то есть не та которая &, а просто показатель того, сколько кто использует это значение) — к переменной и отправляет в стек виртуальной машины:

    Каждый раз, вызывая функцию, вы увеличиваете на единицу refcount каждого переменного аргумента стека. Это происходит потому, что на переменную будет ссылаться не код функции, а её стек. Отправка переменной в стек слабо влияет на производительность, но стек занимает память. Он размещается в ней во время исполнения, но его размер высчитывается во время компиляции. После того как мы отправили в стек переменную, запускаем DO_FCALL. Ниже — пример того, какое количество кода и проверок используется только для того, чтобы мы считали вызовы PHP-функций «медленными» операторами (slow statement):

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

    Далее мы вызываем zend_do_fcall_common_helper(). Я не буду выкладывать здесь код этой функции, он слишком объёмный. Я покажу только те операции, которые там были выполнены. Если вкратце, это множество различных проверок, сделанных во время исполнения. PHP — динамический язык, во время выполнения он может объявлять новые функции и классы, попутно автоматически загружая файлы. Поэтому PHP вынужден проводить во время выполнения множество проверок, что плохо сказывается на производительности. Но от этого никуда не деться.

    Видите, сколько проверок? Идём дальше:

    Вы знаете, что каждое тело функции имеет собственную область видимости переменной. Движок переключает таблицы видимости перед вызовом кода функции, так что если он запросит переменную, то она будет найдена в соответствующей таблице. А поскольку функции и методы по сути одно и то же, можете почитать о том, как забиндить на метод указатель $this.

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

    Приведённая строка вызывает обработчик внутренней функции. В случае с нашим примером относительно strlen() данная строка вызовет код:

    Что делает strlen()? Он извлекает аргумент из стека с помощью zend_parse_parameters(). Это «медленная» функция, потому что ей приходится поднимать стек и конвертировать аргумент в ожидаемый функцией тип (в нашем случае — в строковый). Поэтому независимо от того, что вы передадите в стек для strlen(), ей может понадобиться конвертировать аргумент, а это не самый лёгкий процесс с точки зрения производительности. Исходный код zend_parse_parameters() дает неплохое представление о том, сколько операций приходится выполнить процессору во время извлечения аргументов из стекового кадра функции.

    Переходим к следующему шагу. Мы только что выполнили код тела функции, теперь нам нужно «прибраться». Начнём с восстановления области видимости:

    Затем очистим стек:

    И, наконец, если во время выполнения функции были сделаны какие-то исключения, нужно направить виртуальную машину на блок отлова этого исключения:

    О вызовах PHP-функций

    Теперь вы можете представить, сколько времени тратит компьютер на вызов «очень маленькой и простой» функции strlen(). А поскольку она вызывается многократно, увеличьте это время, скажем, в 25 000 раз. Вот так микро- и миллисекунды превращаются в полноценные секунды… Обратите внимание, что я продемонстрировал только самые важные для нас инструкции во время каждого вызова PHP-функции. После этого случается ещё много всего интересного. Также имейте в виду, что в случае с strlen() «полезную работу» выполняет лишь одна строка, а сопутствующие процедуры по подготовке вызова функции по объёму больше, чем «полезная» часть кода. Однако в большинстве случаев собственный код функций всё же больше влияет на производительность, чем «вспомогательный» код движка.

    Та часть кода PHP, которая относится к вызову функций, в PHP 7 была переработана с целью улучшения производительности. Однако это далеко не конец, и исходный код PHP ещё не раз будет оптимизироваться с каждым новым релизом. Не были забыты и более старые версии, вызовы функций были оптимизированы и в версиях от 5.3 до 5.5. Например, в версиях с 5.4 до 5.5 был изменён способ вычисления и создания стекового кадра (с сохранением совместимости). Ради интереса можете сравнить изменения в исполняющем модуле и способе вызова функций, сделанные в версии 5.5 по сравнению с 5.4.

    Хочу подчеркнуть: все вышесказанное не значит, что PHP плох. Этот язык развивается уже 20 лет, над его исходным кодом работало множество очень талантливых программистов. За этот период он много раз перерабатывался, оптимизировался и улучшался. Доказательством этого служит тот факт, что вы сегодня используете PHP и он демонстрирует хорошую общую производительность в самых разных проектах.

    А что насчёт isset()?

    Это не функция, круглые скобки не обязательно означают «вызов функции». isset() включён в специальный opcode виртуальной машины Zend (ISSET_ISEMPTY), который не инициализирует вызов функции и не подвергается связанным с этим задержкам. Поскольку isset() может использовать параметры нескольких типов, его код в виртуальной машине Zend получается довольно длинным. Но если оставить только часть, относящуюся к параметру offset, то получится примерно так:

    Если убрать многочисленные точки принятия решения (конструкции if), то «основной» вычислительный алгоритм можно выразить строкой:

    Если offset больше нуля (вы не имели в виду isset($a[-42])) и строго меньше длины строки, результат будет принят равным 1. Тогда итогом операции будет булево TRUE. Не волнуйтесь насчёт вычисления длины, Z_STRLEN_P(container) ничего не вычисляет. Помните, что PHP уже известна длина вашей строки. Z_STRLEN_P(container) просто считывает это значение в память, на что тратится крайне мало ресурсов процессора.

    Теперь вы понимаете, почему с точки зрения использования смещения строки обработка вызова функции strlen() требует ГОРАЗДО больше вычислительных ресурсов, чем обработка isset(). Последний существенно «легче». Пусть вас не пугает большое количество условных операторов if, это не самая тяжёлая часть С-кода. К тому же их можно оптимизировать с помощью С-компилятора. Код обработчика isset() не ищет в хэш-таблицах, не производит сложных проверок, не присваивает указателя одному из стековых кадров, чтобы позднее достать его. Код гораздо легче, чем общий код вызова функции, и намного реже обращается к памяти (это самый важный момент). И если закольцевать многократное выполнение такой строки, можно добиться большого улучшения производительности. Конечно, результаты одной итерации strlen() и isset() будут мало отличаться — примерно на 5 мс. Но если провести 50 000 итераций…

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

    Чем нам может быть полезен OPCache

    Если кратко — ничем.

    OPCache оптимизирует код. Об этом можно почитать в презентации. Часто спрашивают, можно ли добавить оптимизационный проход, при котором strlen() переключается в isset(). Нет, это невозможно.

    Оптимизационные проходы OPCache осуществляются в OPArray до того, как он помещается в совместно используемую память. Это происходит во время компиляции, а не во время выполнения. Откуда нам знать во время компиляции, что переменная, которая передаётся в strlen(), является строкой? Это известная проблема PHP, и она отчасти решается с помощью HHVM/Hack. Если бы мы записали в PHP наши переменные со строгой типизацией, то во время проходов компилятора можно было бы оптимизировать гораздо больше вещей (как и в виртуальной машине). Так как PHP является динамическим языком, во время компиляции не известно почти ничего. OPCache может оптимизировать только статические вещи, известные к моменту начала компиляции. Например, вот это:

    Во время компиляции известно, что длина строки «foo» не больше 8, поэтому можно выкинуть все opcode if(), а от конструкции if оставить только часть с else.

    Но что такое $a? Оно вообще существует? Это строка? К моменту прохода оптимизатора мы ещё не можем ответить на все эти вопросы — это задача для исполняющего модуля виртуальной машины. Во время компиляции мы обрабатываем абстрактную структуру, а тип и нужный объём памяти будут известны во время выполнения.

    OPCache оптимизирует многие вещи, но из-за самой природы PHP он не может оптимизировать всё подряд. По крайне мере не столько, сколько в компиляторе Java или С. Увы, PHP никогда не будет языком со строгой типизацией. Также периодически высказываются предложения по введению в декларирование свойств класса указания read-only:

    Если не касаться функциональности, подобные предложения имеют смысл с точки зрения оптимизации производительности. Когда мы компилируем подобный класс, нам известно значение $a. Мы знаем, что оно не изменится, поэтому его можно где-нибудь хранить, использовать кэшированный указатель и оптимизировать каждую итерацию обращения к подобной переменной при проходе компилятора или OPCache. Здесь основная мысль в том, что чем больше информации о типе и использовании ваших переменных или функций вы можете дать компилятору, тем больше OPCache сможет оптимизировать, тем ближе будет результат к тому, что требуется процессору.

    Подсказки по оптимизации и заключительное слово

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

    Вторая подсказка: PHP работает действительно быстро, эффективно и надёжно. Возможностей оптимизации PHP-скриптов не так много — например, их меньше, чем в более низкоуровневых языках вроде С. Поэтому усилия по оптимизации нужно направлять на циклы без конкретных условий на выход из них. Если профайлер покажет узкое место скрипта, вероятнее всего, оно будет внутри цикла. Именно здесь крохотные задержки накапливаются в полновесные секунды, поскольку количество итераций в циклах измеряется десятками тысяч. В PHP такие циклы одинаковы, за исключением foreach(), и ведут к одному и тому же opcode. Менять в них while на for бессмысленно, и профайлер вам это докажет.

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

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

    Да, и старайтесь избегать таких глупостей, как:

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

    Чаще профилируйте свой скрипт и проверяйте каждое предположение, не следуйте слепо чужим инструкциям. Всегда всё проверяйте.

    Разработчики профайлера Blackfire заложили в свой продукт механизм сбора интересных метрик, способных помочь пользователям в их работе. Регистрируется множество параметров (хотя GUI показывает ещё не все): например, когда запускается сборщик мусора, что он делает, сколько объектов создано/уничтожено в функциях, сколько несоответствий ссылок было создано во время вызовов функций, время сериализации, неправильное поведение foreach() и т.д. и т.п.

    Также не забывайте, что в один прекрасный момент вы столкнётесь с ограничениями языка. Возможно, тогда будет целесообразно выбрать какой-то другой. PHP не годится для создания ORM, видеоигр, HTTP-серверов и многих других задач. Его можно для этого использовать, но это будет неэффективно. Так что для каждой задачи лучше выбирать наиболее подходящий язык, благо сегодня есть из чего выбрать: Java, Go или, наверное, самый эффективный язык нашего времени — C/C++ (Java и Go написаны именно на нем).

    Илон Маск рекомендует:  Что такое код intval
    Понравилась статья? Поделиться с друзьями:
    Кодинг, CSS и SQL