"Мы все писали понемногу, чего нибудь и как-нибудь..."
Или "учимся писать код грамотно".
Ни для кого из тех, кто хоть немного писал на PHP, не секрет, что код vBulletin очень легко читается.
И если есть желание перенять хорошую практику написания кода - предлагаю прочитать мой вольный перевод соответствующего раздела из документации vBulletin.
Итак поехали...
vBulletin Стандарты написания кода
В этом документе дается краткие рекомендации для тех, кто пишет программный код для интеграции с vBulletin.
(прим. PGP: на самом деле хорошо бы, если бы вообще некоторые из тех, кто программирует вняли эти рекомендациям, а то бывает откроешь чей-нибудь код, а та-а-м.....)
Легенда выделения кода цветом:
Code:
$code = red_code($var); Красным будет показано как кодить НЕ надо!
$code = normal_code($var); А обычным цветом будет показано как кодить надо ;)
Фигурные скобки
Фигурные скобки должны ставиться на следующей строки в любом случае.
Code:
if ($condition_one)
{
// do something
}
else if ($condition_two)
{
// do something else
}
else
{
// don't do anything
}
Всегда используйте фигурные скобки, даже для циклов или условий, содержащих всего одну строку кода.
Code:
if ($condition_one)
// do something
else
if ($condition_two)
// do something else
else
// don't do anything
if ($condition_one)
{
// do something
}
else
{
if ($condition_two)
{
// do something else
}
else
{
// don't do anything
}
}
Отступы
Всегда используйте
одну табуляцию для следующего отступа.
Code:
function construct_something($var)
{
global $vboptions;
if ($vboptions['somevar'])
{
if ($var == 'something')
{
return true;
}
else
{
return false;
}
}
else
{
return true;
}
}
Циклы и условия
Команды циклов и условий (включая foreach) всегда должны отделяться одним пробелом от открывающей скобки дальнейшего условия.
Code:
for ($i = 0; $i < 10; $i++)
{
// do something
}
while ($result = $db->fetch_array($results))
{
// do something
}
if ($condition != 'something')
{
// do something
}
foreach ($array AS $key => $val)
{
// do something
}
Запись 'else if' должна использоваться вместо неудобочитаемой 'elseif'.
Code:
if ($condition)
{
// do something
}
else if ($condition_two)
{
// do something else
}
Использование пробелов
Операторы всегда должны быть окружены пробелами. За исключением ++ и --.
Code:
$a = 1;
$b += $a;
$c = $a . $b;
$d = $b . 'something' . $c;
$e = $d * $b;
$f = $e / $a;
$g = ($f + $e) * $b;
$h++;
$i--;
Вызовы функций и определения не должны иметь пробел перед открывающей скобкой.
Code:
$x = htmlspecialchars($y);
$item = $DB_site->fetch_array($items);
Аргументы функций всегда должны иметь пробел после каждой запятой.
Code:
$x = fetch_something($a, $b, $c);
$i = construct_something(strtoupper('something') . ' ' . substr($var, 0, $b));
Ненужные пробелы около скобок не должны использоваться.
Code:
$var = addslashes( $var );
$str = fetch_something( strlen( $var ), strpos( $x , $y ) );
$x = construct_x(substr($string, 0, strlen($bla)) . '/' . ucfirst($string));
if ($x == 1 AND ($y == 2 OR $z == 3) AND ($a = fetch_x($x, $y) OR $a == 'bla'))
Использование кавычек в строках (Квотирование)
Строки должны быть заключены в одинарные кавычки, если они не содержат переменных, иначе должны использоваться двойные кавычки.
Code:
$flat_string = 'Hello, this is a string';
$dynamic_one = "Hello,\nthis is a string.";
$dynamic_two = "Hello $username,\n this is a string.";
Вы сами вольны сделать выбор между методом "выполнения" строки, или конкатенации строки, в зависимости от обстоятельств.
Code:
$string_one = "The time is $timenow and the date is $datenow.";
$string_two = 'The time is ' . time() . ' and the date is ' . $datenow . '.';
SQL запросы всегда должны бы заключены в двойные скобки.
Code:
$results = $DB_site->query("SELECT field FROM " . TABLE_PREFIX . "table AS table");
Переменные не должны заключаться в кавычки, если этого не требуется.
Code:
$var = "$x";
$result = strtoupper("$string");
$var = $x;
$result = strtoupper($string);
$string = fetch_something("something$var");
Вызовы Eval() по возможности должны использовать одинарные кавычки, дабы избежать излишней маскировки спецсимволов.
Code:
eval("\$template = \"" . fetch_template('template') . "\";");
eval('$template = "' . fetch_template('template') . '";');
Использование кавычек в ключах массивов
Ключи массивов должны заключаться в кавычки, если они являются строками или переменными, даже если вы знаете, что переменная является целым числом. Квотирование должно осуществляться по тем же правилам, которые описаны для строк. Обратите внимание что $var = $array[$key]; вызовет ошибку парсинга если $key не заключено в кавычки и является по сути отрицательным целым числом, и вызовет уведомление, если $key по сути строка и не заключена в кавычки.
Code:
$a = $userinfo[12];
$b = $userinfo['username'];
$c = $userinfo["$field"];
Составные ключи массивов должны квотироваться самой "внешней" переменной.
Code:
$a = $userinfo["$var[12]"];
$b = $userinfo["$var[username]"];
$c = $userinfo["$var[$field]"];
Составные массивы по возможности рекомендуется выделять из строк с помощью оператора-точки (режим конкатенации строк). Если же все таки не удается этого избежать, то используйте {...} синтаксис записи.
Code:
$a = "Hello my name is $userinfo[12], how do you do?";
$b = "Hello my name is $userinfo[username], how do you do?";
$c = "Hello my name is $userinfo[$field], how do you do?";
$d = 'Hello my name is ' . $userinfo["$var[field]"] . ', how do you do?';
$e = "Hello my name is {$userinfo[$var[username]]}, how do you do?";
$_GET / $_POST / $_REQUEST
Для уверенности в том, что данные находятся в том формате, в котором они ожидаются, следующие суперглобальные переменные PHP недоступны напрямую в большинстве ситуаций:
- $_GET
- $_POST
- $_REQUEST
- $_COOKIE
- $_FILES
Единственная возможность прямого доступа к этим переменным - с ключом 'do': $_POST['do'] and $_GET['do'], которая используется как контрольная переменная для решения какой ветви скрипта необходимо быть выполненной. Также могут быть другие весьма специфичные ситуации, когда прямой доступ к этим переменным необходим, но все же этого нужно избегать совсем. Не используйте $_GET / $_POST / $_REQUEST и пр. переменные в шаблонах.
clean_gpc() и
clean_array_gpc(), функции классов vBulletin для обработки всех поступающих от пользователя данных.
Валидные типы данных:
- TYPE_BOOL - булев (логический)
- TYPE_INT - целое число
- TYPE_UINT - модуль целого числа
- TYPE_NUM - число с плавающей запятой
- TYPE_UNUM - модуль числа с плавающей запятой
- TYPE_UNIXTIME - Отметка времени Unix (модуль целого числа)
- TYPE_STR - Обрезанная строка (нет начальных и конечных пробелов)
- TYPE_NOTRIM - Строка
- TYPE_NOHTML - Обрезанная строка отправленная через функцию htmlspecialchars_uni()
- TYPE_ARRAY - Массив
- TYPE_FILE - Файл
- TYPE_NOCLEAN - Не проверяется
Каждый тип данных кроме TYPE_NOCLEAN, также имеет соответствующий тип данных массива, который обрабатывает данные в массив заданного типа, например TYPE_ARRAY_BOOL.
Обработанные (санированные) значения доступны через массив $vbulletin->GPC, используя имя переменной как индекс массива, например $vbulletin->GPC['field1']. Вы можете быть уверены, что значение в массиве $vbulletin->GPC будет именно того типа, который вы указали при обработке. Вне зависимости от того, какого типа они были изначально определены в суперглобальных массивах. Например, если Вы указали тип данных TYPE_NOHTML, Вы можете отображать переменную напрямую в HTML, без боязни за то, чтобы она была HTML безопасна.
Первый параметр в обоих clean_gpc() и clean_array_gpc(), это первая буква суперглобального массива, из которого Вы собираетесь получить очищенные данные. Одним вызовом clean_array_gpc() или clean_gpc() вы можете очистить значения только из одного суперглобального массива. Одним вызовом просанировать значения из массивов $_COOKIE и $_POST не удастся, нужно будет инициировать несколько вызовов процедур очистки. В итоге же, все значения все равно будут в одном массиве $vbulletin->GPC, поэтому удостоверьтесь, что имена переменных не пересекаются.
Примечание:
Code:
Значения массива $_COOKIE должны использоваться с префиксом COOKIE_PREFIX:
$vbulletin->input->clean_gpc('c', COOKIE_PREFIX . 'forum_view', TYPE_STR);
$foo = $vbulletin->GPC[COOKIE_PREFIX . 'forum_view'];
Code:
$db->query_write("
UPDATE " . TABLE_PREFIX . "table SET
field_one = '" . $db->escape_string(trim($_POST['field_one'])) . "',
field_two = '" . $db->escape_string(htmlspecialchars_uni(trim($_POST['field_two']))) . "'
WHERE key_field = " . intval($_POST['key_field') . "
");
$vbulletin->input->clean_array_gpc('p', array(
'field_one' => TYPE_STR,
'field_two' => TYPE_NOHTML,
'key_field' => TYPE_INT
));
/* This value can be accessed either by $cleanedvar or $vbulletin->GPC['field_one'] */
$cleanedvar =& $vbulletin->input->clean_gpc('p', 'field_one', TYPE_STR);
$db->query_write("
UPDATE " . TABLE_PREFIX . "table SET
field_one = '" . $db->escape_string($vbulletin->GPC['field_one']) . "',
field_two = '" . $db->escape_string($vbulletin->GPC['field_two']) . "',
WHERE key_field = " . $vbulletin->GPC['key_field'] . "
");
Результаты вызова булевых (логических) функций
Не очень хорошая практика использовать в ответе 1/0. Используйте true/false как результат выполнения функций.
Code:
function is_three($var)
{
if ($var == 3)
{
return 1;
}
else
{
return 0;
}
}
function is_three($var)
{
if ($var == 3)
{
return true;
}
else
{
return false;
}
}
Используйте true/false в нижнем регистре вместо верхнего TRUE/FALSE. Оставьте верхний регистр константам.
Code:
if ($var === TRUE)
if ($var === true)
AND/and/&& OR/or/|| и т.д.
Используйте 'AND' вместо 'and' или '&&', и 'OR' вместо 'or' или '||'.
Code:
if ($var1 && $var2 || $var3)
if ($var1 and $var2 or $var3)
if ($var1 AND $var2 OR $var3)
Записывайте заглавными буквами 'AS' в foreach выражениях.
Code:
foreach($array AS $key => $val)
{
// do something
}
Комментирование кода
Используйте тип комментирования // для коротких, в одну строку комментариев. И /* .... */ синтаксис для больших блоков комментариев.
Code:
// this is a single line comment
// this is a short comment that tells
// you something about the following code
/*
this is a long comment
and it
goes on
for several
lines...
*/
Комментарии должны идти
до кода, который они описывают, а не после.
Code:
$var = 0; // initialize $var
if ($var) // check $var
// initialize $var
$var = 0;
// check $var
if ($var)
Когда комментируете циклы или ветви, можно помещать комментарий внутрь фигурных скобок.
Code:
if ($var)
{
// $var is true so do the following code
echo $var;
}
Отделяйте 'do' ветви и важные блоки кода строкой комментария, показанной ниже. Предлагаю вам скопировать эту строку и добавить ее как вставляемый сниппет в ваш редактор PHP. Если вы хотите добавить короткое описание, что именно выполняет данный 'do' код, добавьте его сразу же после разделительной строки комментария.
Code:
require_once('./global.php');
// #############################################################################
if (empty($_REQUEST['do']))
{
$_REQUEST['do'] = 'modify';
}
// #############################################################################
if ($_REQUEST['do'] == 'edit')
{
// do edit code
}
// #############################################################################
// lists items in a table
if ($_REQUEST['do'] == 'modify')
{
// do modify code
}
Описания функций вначале описывайте строкой комментария, показанной ниже. Опять же, добавьте ее как сниппет.
Code:
// ###################### Start is_something ######################
function is_something($var)
{
return iif($var, true, false);
}
// ###################### Start fetch_uppercase ######################
function fetch_uppercase($var)
{
return strtoupper($var);
}
Сравнение переменных и т.д.
Следующие стандарты должны соблюдаться:
Code:
if (empty($array)) // false если в $array есть элементы
if ($string == '') // true если $string не имеет контента
if ($integer) // true если $integer не 0
if (!$integer) // true если $integer - 0
if ($boolean) // true если $boolean - true
if (!$boolean) // true если $boolean не false
Если проверка данных критична и важна, используйте === и !==.
Code:
if ($boolean === true) // true если $boolean - 'true', false если $boolean - 1 (целое число)
if ($integer !== 0) // true если $integer не 0, false если $integer - 'true'
Обратите внимание на следующее:
Code:
$integer = 0;
if ($integer == '') // возвратит true
$string = '';
if ($string == 0) // возвратит true
$string = '0';
if ($string == '') // возвратит false
Синтаксис SQL запросов
Всегда используйте двойные кавычки для SQL запросов, даже если в них нет динамических данных.
Code:
$db->query_read('SELECT field FROM ' . TABLE_PREFIX . 'table ORDER BY field');
$db->query_read("SELECT field FROM " . TABLE_PREFIX . "table ORDER BY field");
Вызовы SQL функций не должны сопровождаться пробелами после названия функции.
Code:
$db->query_read("SELECT COUNT(*) AS records, SUM(field_one) AS total FROM " . TABLE_PREFIX . "table");
Если строка запроса длинная и лучше было бы записать ее в несколько строк - перенесите запрос полностью с новой строки, помещая ключевые слова условия одно под другим. Следующим образом: двойные кавычки, новая строка, отступ, [строка запроса], новая строка, возврат отступа, двойные кавычки.
Code:
$results = $db->query_read("SELECT field_one, field_two, field_three,
IF(field_four = 'Yes', 1, 0) AS field_four,
FROM " . TABLE_PREFIX . "table_one AS table_one
LEFT JOIN " . TABLE_PREFIX . "table_two As table_two USING(field_one)
WHERE table_one.field_two IN('bla bla bla', 'moo moo moo')
ORDER BY table_one.field_one DESC
LIMIT 5,10");
$results = $db->query_read("
SELECT field_one, field_two, field_three,
IF(field_four = 'Yes', 1, 0) AS field_four,
FROM " . TABLE_PREFIX . "table_one AS table_one
LEFT JOIN " . TABLE_PREFIX . "table_two As table_two USING(field_one)
WHERE table_one.field_two IN('bla bla bla', 'moo moo moo')
ORDER BY table_one.field_one DESC
LIMIT 5,10
");
Дополнительные 'AND' для условия 'WHERE' должны иметь еще один отступ, если запрос написан в несколько строк.
Code:
$results = $db->query_read("
SELECT field_one, field_two
FROM " . TABLE_PREFIX . "table AS table
WHERE field_one IN(3,4,5)
AND field_two <> ''
AND field_three = 'something'
ORDER BY field_one
");
Не квотируйте числовые значения в SQL запросах, используйте intval() или $var += 0; чтобы быть уверенным что переменная в безопасности.
Code:
$db->query_first("SELECT something FROM table WHERE tableid = '$numericvar'");
$db->query_first("SELECT something FROM table WHERE tableid = '" . intval(numericvar) . "'");
$db->query_first("SELECT something FROM table WHERE tableid = " . intval($numericvar));
$numericvar = intval($numericvar);
$db->query_first("SELECT something FROM table WHERE tableid = $numericvar");
Не указывайте размер числовых полей, если вы не указали 'UNSIGNED ZEROFILL'.
Code:
$db->query_write("
ALTER TABLE " . TABLE_PREFIX . "table
ADD field_four SMALLINT(5) UNSIGNED NOT NULL,
ADD field_five INT(10) UNSIGNED NOT NULL
");
$db->query_write("
ALTER TABLE " . TABLE_PREFIX . "table
ADD field_four SMALLINT UNSIGNED NOT NULL,
ADD field_five INT UNSIGNED NOT NULL
");
Не используйте оператор 'AFTER' в выражениях 'ALTER'. Некоторые серверы имеют с этим проблемы, так что лучше этого избегать.
Code:
$db->query_write("
ALTER TABLE " . TABLE_PREFIX . "table
ADD field_six INT UNSIGNED NOT NULL AFTER field_five
");
$db->query_write("
ALTER TABLE " . TABLE_PREFIX . "table
ADD field_six INT UNSIGNED NOT NULL
");
Запросы INSERT / REPLACE пишите в такой манере:
Code:
$db->query_write("
INSERT INTO " . TABLE_PREFIX . "table
(field_one, field_two, field_three)
VALUES
(1, 2, 'moo'),
(1, 2, 'baa'),
(3, 5, 'quack')
");
Всегда используйте имена полей в запросах INSERT / REPLACE. Никогда не будьте уверены, что вставляете все поля в таблицу.
Code:
$db->query_write("
INSERT INTO " . TABLE_PREFIX . "table
VALUES
(1, 'one', 'some text')
");
$db->query_write("
INSERT INTO " . TABLE_PREFIX . "table
(field_one, field_two, field_three)
VALUES
(1, 'one', 'some text')
");
Если поле в запросе INSERT является AUTO_INCREMENT, не включайте его в запрос.
Code:
$db->query_write("
INSERT INTO " . TABLE_PREFIX . "table
(auto_increment_field, field_two)
VALUES
(NULL, 'texty bits')
");
$db->query_write("
INSERT INTO " . TABLE_PREFIX . "table
(field_two)
VALUES
('texty bits')
");
Именование веток 'Do'
Практически все скрипты vBulletin содержат ветки 'do'. Следующая манера написания кода должна для них соблюдаться.
Code:
if (empty($_REQUEST['do']))
{
// set default branch for this script
$_REQUEST['do'] = 'modify';
}
// #############################################################################
if ($_POST['do'] == 'kill')
{
// 'kill'
// run code to remove item in database
}
// #############################################################################
if ($_REQUEST['do'] == 'delete')
{
// 'delete'
// display delete confirmation message
}
// #############################################################################
if ($_POST['do'] == 'insert')
{
// 'insert'
// run code to insert new item into database
}
// #############################################################################
if ($_REQUEST['do'] == 'add')
{
// 'add'
// display form to add new item
}
// #############################################################################
if ($_POST['do'] == 'update')
{
// 'update'
// run code to update item in database
}
// #############################################################################
if ($_REQUEST['do'] == 'edit')
{
// 'edit'
// display form to edit item
}
// #############################################################################
if ($_REQUEST['do'] == 'modify')
{
// 'modify'
// show default branch for this script
}
Если возможно, сохраняйте именно такую последовательность ветвей, которая приведена выше, когда 'modify' (действие по умолчанию) находится в самом низу скрипта.
Если же скрипт содержит в себе действия для редактирования/добавления/удаления (edit/add/delete) больше чем одного типа элементов (например так template.php содержит ветви для редактирования стилей и шаблонов), тогда используйте суффикс, состоящий из названия элемента.
Code:
if ($_REQUEST['do'] == 'edittemplate')
{
// show form to edit a template
}
// #############################################################################
if ($_REQUEST['do'] == 'editstyle')
{
// show form to edit a style
}
Если функционал ветви 'do' не ограничивается только edit, update, add, insert, delete или kill, тогда дайте ей имя, которое суммарно будет отображать действия, которые эта ветвь выполняет.
Code:
if ($_REQUEST['do'] == 'rebuildstylecache')
{
// rebuild style cache
}
// #############################################################################
if ($_REQUEST['do'] == 'updatetemplateparentlists')
{
// update template parent lists
}
Держите группы, которые взаимодействуют с каким то одним типом элемента, рядом в скрипте.
Code:
// if (empty($_REQUEST['do']))
// if ($_REQUEST['do'] == 'rebuildstylecache')
// if ($_POST['do'] == 'killstyle')
// if ($_REQUEST['do'] == 'deletestyle')
// if ($_POST['do'] == 'insertstyle')
// if ($_REQUEST['do'] == 'addstyle')
// if ($_POST['do'] == 'updatestyle')
// if ($_REQUEST['do'] == 'editstyle')
// if ($_REQUEST['do'] == 'updatetemplateparentlists')
// if ($_POST['do'] == 'killtemplate')
// if ($_REQUEST['do'] == 'deletetemplate')
// if ($_POST['do'] == 'inserttemplate')
// if ($_REQUEST['do'] == 'addtemplate')
// if ($_POST['do'] == 'updatetemplate')
// if ($_REQUEST['do'] == 'edittemplate')
// if ($_REQUEST['do'] == 'modify')
Именование функций
Имена функций должны настолько точно, насколько это возможно описывать функционал, который они выполняют. Для того, чтобы тот человек, который будет читать ваш код, понимал как ее использовать и чего от нее ожидать только взглянув на ее имя.
Имена функций должны быть записаны в нижнем регистре и для разделения слов использовать символ подчеркивания.
Code:
$var2 = issomething($var1);
$var2 = isSomething($var2);
$var2 = is_something($var1);
Пользовательские имена функций должны соответствовать следующим стандартам.
- Префикс:
- Описание:
- Пример:
- print_
- Функции, которые напрямую выводят код в браузер или буфер вывода через выражения echo или print.
- print_input_row, print_standard_error, print_cp_header
- construct_
- Функции, которые возвращают переменные содержащие HTML для дальнейшего вывода.
- construct_edit_toolbar, construct_forum_jump
- is_, contains_
- Логические функции, возвращающие true/false в зависимости от условий.
- is_valid_email, is_wysiwyg_compatible, contains_bbcode_img_tags
- can_
- Логические функции, возвращающие true/false в зависимости от прав доступа.
- can_moderate, can_administer, can_announce
- verify_
- Функции, которые проверяют условие и напрямую выкидывают сообщение об ошибке, если условие выполняется.
- verify_ip_ban, verify_post_errors, verify_word_allowed
- convert_
- Функции, конвертирующие входную переменную из одного формата в другой.
- convert_kb_to_mb, convert_html_to_bbcode, convert_bits_to_array
- cache_
- Функции, читающие данные из БД (обычно) и создающие кеш для облегчения нагрузки на SQL.
- cache_templates, cache_forums, cache_birthdays
- fetch_
- Функции, которые возвращают массивы / строки / числа и пр. Если возвращаемый тип данных не читается явно из названия функции (например fetch_template, fetch_userinfo и пр.), тогда укажите типа данных в названии, например fetch_template_update_sql, fetch_replaced_session_url, fetch_reminders_array и др.
- fetch_template, fetch_user_search_sql, fetch_user_location_array
- process_
- Функции выполняющие какие то действия с массивом, чтобы приготовить его для дальнейшей работы.
- process_thread_array, process_post_preview, process_online_location
- build_
- Функции, которые сохраняют данные в БД для дальнейшего к ним обращения. Так например, кеширование дней рождения в datastore, перестроение стилей и др.
- build_bbcode_cache, build_new_post, build_attachment
- delete_
- Функции, которые удаляют что либо из БД.
- delete_thread, delete_post_index, delete_user_pms
- undelete_
- Функции, отменяющие мягкое удаление.
- undelete_thread, undelete_post
- import_
- Функции из системы bbimport, которые на вход получают массив данных и вставляют его в запись сообщения, темы и др. в БД.
- import_thread, import_post, import_user
- sanitize_
- Функции, выполняющие действия над входными параметрами для того чтобы сделать их безопасными для дальнейшей с ними работы. Например удаление лишних символов, проверка данных на валидность типа и др.
- sanitize_perpage, sanitize_url, sanitize_reminder_date
- parse_
- Функции, которые обеспечивают парсинг bbcode каким то образом.
- parse_bbcode, parse_usernote_bbcode, parse_pm_bbcode
- handle_
- Функции, которые вызываются парсером bb-кода для обработки соответствующего типа bb-кода.
- handle_bbcode_img, handle_bbcode_list, handle_bbcode_parameter
- file_
- Функции, напрямую взаимодействующие с файловой системой.
- file_read, file_download, file_append
- log_
- Функции, пишущие в логи vBulletin.
- log_admin_action, log_vbulletin_error, log_upgrade_step
- exec_
- Функции, которые выполняют определенные действия (зачастую без возврата какого то определенного результата).
- exec_shutdown, exec_queries, exec_cron
- sort_
- Функции сортирующие данные.
- sort_search_items, sort_threaded_posts
- strip_
- Функции обрезающие элементы в строковых данных.
- strip_bbcode, strip_blank_ascii, strip_empty_bbcode
- xml_
- Функции, которые читают или выводят XML.
- xml_import_style, xml_parse_language_otag, xml_escape_cdata
- vb_, vb
- Функции, которые заменяют встроенные в PHP функции с заменами, призванными увеличить функциональность или изменить поведение встроенных функций. Если оригинальное имя функции содержит подчеркивания, то префикс 'vb_', иначе префикс 'vb'.
- vbmail, vb_number_format, vbsetcookie
- js_
- Javascript функции определенные в PHP коде, а не в одном из js файлов.
- js_dots, js_confirm_clear_db, js_forum_jump
В заключении пожелаю всем, кто пишет или "кодит" или "программирует" или еще как то, творческих успехов, побольше состояний "поперло" и поменьше "втупляю" и давайте писать красивый, понятный код, который потом не стыдно будет показать и представить на суд общественности