Домой / Офис / Использование ob_start при поддержке проектов на php. Public Морозов и другие: антипаттерны в программировании Определение и применение

Использование ob_start при поддержке проектов на php. Public Морозов и другие: антипаттерны в программировании Определение и применение

В PHP имя переменной всегда начинается со знака доллара ($), за которым обязательно должна следовать буква, после которой можно использовать буквы, цифры и знак подчёркивания. Имена чувствительны к регистру символов, т.е. переменные $value, $Value, $VALUE и $VaLuE - четыре РАЗНЫХ переменных, хотя их имя и читается одинаково.

Примеры синтаксически правильных имён переменных:

Пример некорректных имён:

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

Пример плохо читаемого кода

Краткость, конечно, сетстра таланта, но жертвовать простотой восприятия кода ради его компактности - неразумно. Тем более, что длина имени никак не влияет на производительнось скрипта. Но не стоит и впадать в противоположную крайность - давать переменным слишком длинные имена. Если имя должно состоять из двух и более слов - части имени нужно выделять заглавными буквами или разделять подчёркиваниями. Например, имя $strusernameadndomain намного лучше воспринимается в виде $str_UserNameAndDomain.

Пример хорошо читаемого кода

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

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

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

Передача переменных по значению

Для работы с переменными есть в PHP особые функции:

isset() - проверяет, была ли объявлена переменная и отличается ли её значение от NULL;
empty() - аналог isset()
unset() - встроенная функция языка, удаляющая значение переменной и удаляющая саму переменную из списка доступных переменных (уничтожающая переменную).

$name = "Иван Иваныч";
if(isset($name))
{
// Выводим сообщение с именем
echo "Моё имя: $name";
// уничтожаем переменную
unset($name);
}
else "Имя ещё не определено";

echo $name;
// ничего не выведет,
// т.к. значение переменной $name
// ещё не определено
// или переменная уже уничтожена

Область видимости переменных
Очень важная характеристика переменной - её область видимости (область действия), т.е. описание того, из каких мест программы (скрипта) можно прочитать или изменить её значение. Следует всегда помнить, что переменная, объявленная внутри блока программы, видна только в пределах этого блока, а для того, чтобы обратиться к переменной, объявленной снаружи блока, необходимо её особым образом объявить.

Блоками программы в данном случае являются "скрипт", "функция" или "класс". Например:

Вроде бы всё правильно, но - не работает. Почему? Потому что если явно не сказать, что переменная $name внутри функции - это в действительности глобальная переменная $name, то интерпретатор создать временную копию переменной с именем $name и пустым значением. А так как значение пустое (неопределённое), то и результат сложения строк будет неопределён (пуст).

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

В данном примере переменная $name имеет область видимости, равную всему скрипту, а переменная $fullName, объявленная внутри функции, имеет область определения равную этой самой функции. Это значит, при выходе их функции переменная $fullName будет уничтожена, а все попытки прочитать её значение приведут к ошибке.

Примеры работы с классами мы рассмотрим в разделе "Классы и наследование".

Переменные переменные
Да-да, здесь нет ошибки, именно так (двумя словами) называются некоторые переменные в PHP. Смысл в том, что текстовая часть имени переменной (т.е. имя без знака доллара) может сама быть именем. Например:

Настоятельно не рекомендуется пользоваться подобными приёмами без острой необходимости. Код, напичканый такими трюками, очень сложно сопровождать. Особенно это важно при работе с данными, вводимыми пользователями. Главная причина сложностей - неявные зависимости. Например, что случится, если вместо имени "Вася" написать что-то вроде """""_;%//^q""? Правильно! Скрипт в большинстве случаев не сможет выполниться! Можно, конечно, добавить кучу проверок на наличие "неправильных" символов, но проще вообще не пользоваться такими трюками.

Константы
Константа - это некая неизменная величина. Константа объявляется одновременно с именем и значением. Для объявления константы служит функция define(), а для определения наличия константы (т.е. была она определена или нет) - функция defined(). Имя константы строится по тем же правилам, что и имена переменных.

Примеры констант:

Отдельный вид констант PHP - так называемые "магические константы". Это системные константы, значение которых определяет и устанавливает интерпретатор. Таких констант немного:

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

jQuery эффекты Определение и применение

jQuery метод .show() позволяет отобразить скрытые выбранные элементы. Для того, чтобы скрыть выбранные элементы вы можете воспользоваться методом .hide() .

Обращаю Ваше внимание, что когда метод .show() используется без параметров, то элемент отображается без анимации. Это эквивалентно * использованию метода .css() со следующим значением:

$(selector ).css("display ", "block ")

* - за исключением того, что значение свойства display сохраняется внутри jQuery и может позже быть восстановлено к первоначальному значению.

Если вы используете стили элемента с !important , то метод .show() не сможет отобразить элемент. В этом случае рекомендуется использовать такие методы как .addClass() , .removeClass() , .toggleClass() , или .attr() .

jQuery синтаксис: Синтаксис 1.0: $(selector ).show() // метод используется без параметров $(selector ).show(duration , complete ) duration - Number , или String complete - Function $(selector ).show({ options } ) // option: value (описание ниже) options - PlainObject Синтаксис 1.4.3: $(selector ).show(duration , easing , complete ) duration - Number , или String easing - String complete - Function Добавлен в версии jQuery 1.0 (синтаксис обновлен в версии 1.4) Значения параметров Параметр Описание
duration Строковое или числовое значение, которое определяет, как долго анимация будет продолжаться. Значение по умолчанию 400 (в миллисекундах). Строковые ключевые слова "fast" и "slow" соответствуют 200 и 600 миллисекундам соответственно (высокие значения указывают на медленную анимацию, а более низкие на быструю).
easing Ключевое слово (строка), которое опряеделяет кривую скорости для анимации (используется математическая функция - кубическая кривая Безье). Без использования внешних плагинов имеет только два значения - linear (эффект анимации с одинаковой скоростью от начала до конца) и swing (эффект анимации имеет медленный старт и медленное окончание, но скорость увеличивается в середине анимации). Значение по умолчанию swing .
complete Функция, которая будет выполнена после завершения анимации, она вызывается один раз для каждого соответствующего элемента. Внутри функции, переменная this ссылается на DOM элемент к которому применяется анимация.
options
  • duration (по умолчанию: 400 ).
    Тип: Number , или String .
    Строковое или числовое значение, которое определяет, как долго анимация будет продолжаться (смотри выше).
  • easing (по умолчанию: swing ).
    Тип: String .
    Ключевое слово (строка), которое определяет кривую скорости для анимации (смотри выше).
  • queue (по умолчанию: true ).
    Тип: Boolean , или String .
    Логическое значение, которое указывает следует ли размещать анимацию в очереди эффектов. Если указано false , то анимация начнется сразу же. С версии jQuery 1.7 опция queue также может принимать строку, в этом случае анимация будет добавлена к очереди, представленной этой строкой. Когда используется пользовательское имя очереди анимации, то она не запускается автоматически, вы должны при этом использовать метод .dequeue("имя очереди ") , чтобы запустить её.
  • specialEasing .
    Тип: PlainObject .
    Объект, содержащий одно или несколько свойств CSS, определенных параметром свойства и соответствующие им функции замедления. Добавлено в версии 1.4 .
  • step .
    Тип: Function (Number now, Tween tween).
    Функция вызывается для каждого анимируемого свойства каждого анимированного элемента. Эта функция дает возможность изменять Tween Object, чтобы изменить значение свойства, прежде чем оно будет установлено.
  • progress .
    Тип: Function .
    Функция, которая будет вызываться после каждого шага анимации, только один раз для каждого анимированного элемента, независимо от количества анимированных свойств. Добавлено в версии 1.8 .
  • complete .
    Тип: Function .
    Функция (callback ), которая будет выполнена после завершения анимации, она вызывается один раз для каждого соответствующего элемента (смотри выше).
  • start .
    Тип: Function (Promise Object animation).
    Функция, вызывается, когда анимация элемента начинается. Добавлено в версии 1.8 .
  • done .
    Тип: Function (Promise Object animation, Boolean jumpedToEnd).
    Функция вызывается, когда анимация элемента завершается. Добавлено в версии 1.8 .
  • fail .
    Тип: Function (Promise Object animation, Boolean jumpedToEnd).
    Функция вызывается, когда анимацию элемента не удается завершить. Добавлено в версии 1.8 .
  • always .
    Тип: Function (Promise Object animation, Boolean jumpedToEnd).
    Функция вызывается, когда анимация элемента завершается или останавливается незавершенной. Добавлено в версии 1.8 .
Пример использования Использование jQuery методов.hide() и.show() (без параметров) $("p ").hide(); // скрывыаем все элементы

$("p ").show(); // отображаем все элементы

} ); } ); Скрыть Показать

Первый абзац

Второй абзац

Третий абзац

.hide() и .show()

в документе.

Результат нашего примера:

.hide() и .show() различные значения продолжительности анимации:

Использование jQuery методов.hide() и.show() (различная скорость анимации) $(document ).ready(function (){ $(".hide ").click(function (){ // задаем функцию при нажатиии на элемент с классом hide $("p:first ").hide("slow "); // скрывыаем первый элемент

В документе $("p:nth-of-type(2) ").hide(2000 ); // скрывыаем второй элемент

В документе $("p:last ").hide("fast "); // скрывыаем последний элемент

В документе } ); $(".show ").click(function (){ // задаем функцию при нажатиии на элемент с классом show $("p:first ").show("slow "); // отображаем первый элемент

В документе $("p:nth-of-type(2) ").show(2000 ); // отображаем второй элемент

В документе $("p:last ").show("fast "); // отображаем последний элемент

В документе } ); } ); Скрыть Показать

Первый абзац

Второй абзац

Третий абзац

В этом примере с использованием jQuery методов .hide() и .show() мы при нажатии на определенную кнопку скрываем, либо отображаем все элементы

в документе. При этом первый элемент

скрывается, или отображается за 600 миллисекунд (ключевое слово "slow" ), второй элемент за 2000 миллисекунд, а третитй за 200 миллисекунд (ключевое слово "fast" ).

Результат нашего примера:

Рассмотрим следующий пример в котором зададим методам .hide() и .show() не только продолжительность анимации, но и укажем скорость анимации и функцию, которая будет выполнена после завершения анимации:

Использование jQuery методов.hide() и.show() (с callback функцией) $(document ).ready(function (){ $(".hide ").click(function (){ // задаем функцию при нажатиии на элемент с классом hide $("p ").hide(500 , "linear ", function (){ // скрывыаем элементы

В документе $(".status ").text("Элементы исчезли "); // задаем функцию при нажатиии на элемент с классом show $("p ").show(500 , "linear ", function (){ // отображаем элементы

В документе $(".status ").text("Элементы появились "); // добавляем текстовую информации в элемент с классом status } ); } ); } ); Скрыть Показать

Первый абзац

Второй абзац

Третий абзац

В этом примере с использованием jQuery методов .hide() и .show() мы при нажатии на определенную кнопку скрываем, либо отображаем все элементы

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

Результат нашего примера:

Рассмотрим следующий пример в котором передадим в качестве параметра методов .hide() и .show() объект, содержащий различные опции, которые будут контролировать анимацию:

Использование jQuery методов.hide() и.show() (объект с опциями в качестве параметра) $(document ).ready(function (){ $(".hide ").click(function (){ // задаем функцию при нажатиии на элемент с классом hide $("p ").hide({ // скрывыаем элементы

В документе duration: 800 , easing: "linear ", // скорость анимации Элементы исчезли "); } , queue: false // не ставим в очередь } ); } ); $(".show ").click(function (){ // задаем функцию при нажатиии на элемент с классом show $("p ").show({ // отображаем элементы

В документе duration: 800 , // продолжительность анимации easing: "linear ", // скорость анимации complete: function (){ // callback $(".status ").text("Элементы появились "); } , queue: false // не ставим в очередь } ); } ); } ); Скрыть Показать

Первый абзац

Второй абзац

Третий абзац

В этом примере с использованием jQuery методов .hide() и .show() мы при нажатии на определенную кнопку скрываем, либо отображаем все элементы

в документе. При этом мы в качестве параметров метода передаем объект содержащий следующие параметры:

  • продолжительность анимации равную 800 миллисекунд (duration: 800 )
  • эффект анимации происходит с одинаковой скоростью от начала до конца (easing: linear )
  • функция, которая после завершения анимации находит элемент с классом status и добавляет текстовую информацию (complete: function ).
  • анимация не размещается в очереди эффектов (queue: false ).

Результат нашего примера.

Straight from the php.ini file:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Error handling and logging ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; This directive informs PHP of which errors, warnings and notices you would like ; it to take action for. The recommended way of setting values for this ; directive is through the use of the error level constants and bitwise ; operators. The error level constants are below here for convenience as well as ; some common settings and their meanings. ; By default, PHP is set to take action on all errors, notices and warnings EXCEPT ; those related to E_NOTICE and E_STRICT, which together cover best practices and ; recommended coding standards in PHP. For performance reasons, this is the ; recommend error reporting setting. Your production server shouldn"t be wasting ; resources complaining about best practices and coding standards. That"s what ; development servers and development settings are for. ; Note: The php.ini-development file has this setting as E_ALL. This ; means it pretty much reports everything which is exactly what you want during ; development and early testing. ; ; Error Level Constants: ; E_ALL - All errors and warnings (includes E_STRICT as of PHP 5.4.0) ; E_ERROR - fatal run-time errors ; E_RECOVERABLE_ERROR - almost fatal run-time errors ; E_WARNING - run-time warnings (non-fatal errors) ; E_PARSE - compile-time parse errors ; E_NOTICE - run-time notices (these are warnings which often result ; from a bug in your code, but it"s possible that it was ; intentional (e.g., using an uninitialized variable and ; relying on the fact it is automatically initialized to an ; empty string) ; E_STRICT - run-time notices, enable to have PHP suggest changes ; to your code which will ensure the best interoperability ; and forward compatibility of your code ; E_CORE_ERROR - fatal errors that occur during PHP"s initial startup ; E_CORE_WARNING - warnings (non-fatal errors) that occur during PHP"s ; initial startup ; E_COMPILE_ERROR - fatal compile-time errors ; E_COMPILE_WARNING - compile-time warnings (non-fatal errors) ; E_USER_ERROR - user-generated error message ; E_USER_WARNING - user-generated warning message ; E_USER_NOTICE - user-generated notice message ; E_DEPRECATED - warn about code that will not work in future versions ; of PHP ; E_USER_DEPRECATED - user-generated deprecation warnings ; ; Common Values: ; E_ALL (Show all errors, warnings and notices including coding standards.) ; E_ALL & ~E_NOTICE (Show all errors, except for notices) ; E_ALL & ~E_NOTICE & ~E_STRICT (Show all errors, except for notices and coding standards warnings.) ; E_COMPILE_ERROR|E_RECOVERABLE_ERROR|E_ERROR|E_CORE_ERROR (Show only errors) ; Default Value: E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED ; Development Value: E_ALL ; Production Value: E_ALL & ~E_DEPRECATED & ~E_STRICT ; http://php.net/error-reporting error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT

For pure development I go for:

Error_reporting = E_ALL ^ E_NOTICE ^ E_WARNING

Also don"t forget to put display_errors to on

Display_errors = On

After that restart your server for apache on Ubuntu:

Sudo /etc/init.d/apache2 restart

Привет, Хабр!

Сегодня я бы хотел познакомить начинающих вебмастеров с разнообразными изящными способами использования буферизации вывода в php. Опытные вебмастера для себя здесь врят ли найдут что-то полезное. Хотя - кто знает?

Как вы все знаете, буферизацией вывода в php управляет набор функций, начинающихся на «ob_». Самая главная из них - ob_start. При запуске она собирает последующий вывод, то есть всевозможные print(), echo и прочее, что потом отдастся посетителю в форме html-странички. И если перед тем, как выводить, мы запустили буферизацию, то с этой, почти готовой уже, страничкой, можно будет напоследок что-нибудь сотворить.


Например, мы хотим отфильтровать все ссылки на посторонние сайты.

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

"http://blackjack-hookers.com" => "http://myoldforum.ru/redirect.php?url=blackjack-hookers.com"

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

Function f_callback($buffer){ $buffer = preg_replace("#http://(www.)?myoldforum\.ru/#","/",$buffer); $buffer = preg_replace("#href="http://([^"]*)"#","#href="/redirect\.php\?url=$1",$buffer); return $buffer; } ob_start(f_callback);

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

Меняя контент таким образом, мы не ограничены рамками методов движка. Это бывает весьма ценно. Можно, например, добавить плагин:

Function generate_plugin(){ /*что-то генерируем*/ } function f_callback($buffer){ /*...*/ $buffer = str_replace ("",generate_plugin(),$buffer); /*...*/ return $buffer; } ob_start("f_callback");

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

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

{GENERATE BIG CRAZY THING}

Должно быть, вы уже заметили все эти обороты: «не хочется лезть», «древний, как стул тиранозавра», «криво написанный редактор»… В идеальном мире оболочки вокруг буфера вывода не нужны. Все что можно сделать с помощью ob_start, теоретически можно было бы сделать и без него. Этот прием иной раз вносит путанницу в код проекта, многие видят его смысл лишь в том, что бы отдать вывод в ob_gzhandler для сжатия, и считают его применение в иных случаях опасным. Но часто без управления выводом просто не обойтись.

Особенно если не хочется копать вглубь.