понедельник, 21 января 2019 г.

21 ошибка программиста PHP, часть 1

21 ошибка программиста PHP, часть 1

Автор: Стерлинг Хьюз
Описываются 7 "детских" ошибок (21-15 в обратном порядке, в соответствии со степенью серьезности по нашей классификации). Такие ошибки не вызывают серьезных проблем, но приводят к уменьшению эффективности работы программы, а также выражаются в громоздком трудночитаемом коде, в который, к тому же, трудно вносить изменения.
Одна из наиболее сильных сторон PHP является, одновременно, и его слабой стороной: PHP очень прост в изучении. Это привлекает многих людей; однако, несмотря на его кажущуюся простоту, не так-то просто научиться использовать этот язык правильно и эффективно.
Как правило, дело в недостаточной практике программирования. Неопытные программисты становятся перед лицом необходимости создания сложных веб-приложений. Поэтому сплошь и рядом допускаются ошибки, которых избежал бы опытный программист, такие как необоснованное использование функции printf()или неправильное использование семантики PHP.
В этой серии из трех статей представлены наиболее, по нашему мнению, характерные ошибки. Эти ошибки можно классифицировать по нескольким категориям, от некритических до смертельных. Наряду с анализом этих ошибок, представлены способы их избежания, а также некоторые маленькие хитрости, накопленные за многие годы практики программирования.
Целевая аудитория
Эта серия статей предназначена для тех программистов на языке PHP, которые хотят избежать наиболее общих ошибок в написании кода. Читатель, как минимум, должен знать общий синтаксис PHP, а также весьма желателен некоторый опыт использования языка на практике.
Введение
Одна из наиболее сильных сторон PHP является, одновременно, и его слабой стороной: PHP очень прост в изучении. Это привлекает многих людей; однако, несмотря на его кажущуюся простоту, не так-то просто научиться использовать этот язык правильно и эффективно.
Как правило, дело в недостаточной практике программирования. Неопытные программисты становятся перед лицом необходимости создания сложных веб-приложений. Поэтому сплошь и рядом допускаются ошибки, которых избежал бы опытный программист, такие как необоснованное использование функции printf() или неправильное использование семантики PHP.
В этой серии из трех статей представлены наиболее, по нашему мнению, характерные ошибки. Эти ошибки можно классифицировать по нескольким категориям, от "некритических" до "смертельных". Наряду с анализом этих ошибок представлены способы их избежания, а также некоторые "маленькие хитрости", накопленные за многие годы практики программирования.
Часть 1: Описываются 7 "детских" ошибок (21-15 в обратном порядке, в соответствии со степенью серьезности по нашей классификации). Такие ошибки не вызывают серьезных проблем, но приводят к уменьшению эффективности работы программы, а также выражаются в громоздком трудночитаемом коде, в который, к тому же, трудно вносить изменения.
Часть 2: Следующие 7 ошибок (14-8) относятся к "серьезным". Они ведут к еще более значительному уменьшению скорости выполнения кода, уменьшению безопасности скриптов; код становится еще более запутанным.
Часть 3: Описания семи последних, "смертельных" ошибок. Эти ошибки концептуальны по своей природе и являются причиной появления ошибок, описанных в 1-ой и 2-ой частях статьи. Они включают и такие ошибки, как недостаточное внимание, уделенное как проекту в целом, так и коду программы, в частности.
21. Неоправданное использование функции printf()
Функция printf() предназначена для вывода форматированных данных.
Например, ее следует использовать при необходимости вывода переменной в формате с плавающей запятой с определенной точностью, либо в любом другом случае, когда возникает необходимость изменения формата выводимых данных.
Ниже приведен пример обоснованного применения функции printf(). В данном случае она используется для форматированного вывода числа "пи":
<?php

printf ("Число Пи: %2f\n<br>\n", M_PI);
printf ("Это тоже число Пи: %3f\n<br>\n", M_PI);
printf ("И это Пи: %4f\n<br>\n", M_PI);

?>
Примечание: Наблюдаются случаи патологической боязни функции printf(), когда люди пишут свои функции форматированного вывода, порой по 30-40 строк, хотя все проблемы мог бы решить один-единственный вызов функции printf().
Многие программисты используют функцию printf() для вывода переменных, результатов вызова функций, а иногда даже обычных текстовых данных. Наиболее часто это происходит в следующих двух случаях:
  • когда следовало бы использовать функцию print();
  • при выводе результатов, возвращаемых функциями.
Когда следует использовать print()
Вызов функции printf() зачастую используется там, где следовало бы использовать print(). В следующем примере функция printf() используется для вывода четырех переменных:
<?php

  $name     = 'Sterling Hughes';
  $job      = 'Senior Engineer';
  $company  = 'DesignMultimedia';
  $email    = 'shughes@designmultimedia.com';

  printf ( "Меня зовут %s\n<br>\n
            Я работаю %s, %s\n<br>\n
            Мой адрес E-mail:%s\n<br>\n",
            $name, $job, $company, $email );
?>
В данном случае возможно (и желательно!) применение print():
  print "Меня зовут $name\n<br>\n
         Я работаю в $company, $job\n<br>\n
         Мой адрес E-mail: $email\n<br>\n";
Использование print() вместо printf() в случаях, когда выводятся неформатированные данные, как в данном примере, дает следующие выгоды:
  • Увеличение производительности: Функция printf() форматирует свои аргументы перед выводом. Таким образом, время ее выполнения больше, чем для функций print() или echo().
  • Более ясный код: Все-таки надо признать, что использование функции printf() затрудняет чтение кода (имеющих достаточный опыт программирования на C это, конечно, касается в меньшей степени). Чтобы функция printf() не повела себя самым неожиданным для вас образом, требуется как знание синтаксиса данной функции, (т.е. %sопределяет строковый формат вывода, тогда как %d - десятичный), так и знание типов переменных.
Использование функции printf() для вывода значения, возвращаемого функцией
Еще одна характерная ошибка использования функции printf() - вывод значения, возвращаемого функцией, как в следующем примере:
<?php

  printf ("Найдено %d вхождений строки %s", count ($result), $search_term);

?>
Наряду с функцией print() при использовании ее в тех же целях, следует использовать оператор "." В данном случае этот оператор добавляет текст к результату вызова функции:
<?php

  print "Найдено " .
         count ($result) .
       " вхождений строки $search_term";

?>
Использование оператора . в паре с функцией print() позволяет избежать использования более медленной функции printf().
20. Неверное применение семантики языка
Многие программисты используют в своей работе PHP, фактически не понимая тонкостей этого языка. Одна из тонкостей - разница между синтаксисом и семантикой PHP.
  • Синтаксис PHP: Представляет собой набор правил для определения элементов языка. Например, как мы определяем переменную? Ставим знак $ перед ее именем. Как определяем функцию? В общем случае, используя скобки, аргументы и т.п.
  • Семантика PHP: Представляет собой набор правил для применения синтаксиса. Например, возьмем функцию с двумя аргументами, что определяется ее синтаксисом. Причем в качестве аргументов ей следует передавать переменные строкового типа  - это определяется семантикой.
Заметьте: "следует". В языках с четким разделением типов (таких как Java или C) нет понятия "следует" (в общем случае, хотя бывают и исключения). В таком случае компилятор вынудит использовать переменные строго определенного типа.
Языки, в которых отсутствует само определение типов переменных, предоставляют больше гибкости в написании кода. Но, как бы то ни было, в случае неправильного использования семантики для большинства функций PHP следует ожидать появления сообщения об ошибке.
Возьмем кусок кода, который открывает файл и выводит его построчно:
<?php

$fp = @fopen ( 'somefile.txt', 'r' )
        or die ( 'Не могу открыть файл somefile.txt' );

  while ($line = @fgets ( "$fp", 1024)) // Здесь ошибка!
  {
    print $line;
  }

@fclose ("$fp") // И здесь тоже color
  or die( 'Не могу закрыть файл somefile.txt' );

?>
В данном случае появится сообщение об ошибке типа:
"Warning: Supplied argument is not a valid File-Handle resource in tst.php on line 4"("Внимание: аргумент не может являться дескриптором файла")
Это вызвано тем, что переменная $fp заключена в двойные кавычки, что однозначно определяет ее как строку, тогда как функция fgets() ожидает в качестве первого аргумента дескриптор, но не строку. Соответственно, вам следует использовать переменную, которая может содержать дескриптор.
Примечание: В данном случае строковый тип допустим синтаксически.
Для решения проблемы следует просто убрать двойные кавычки:
<?php
  $fp = @fopen ( 'somefile.txt', 'r' )
          or die ( 'Не могу открыть файл somefile.txt' );

  while ( $line = @fgets ($fp, 1024) )
  {
    print $line;
  }

  @fclose ($fp)
    or die ( 'Не могу закрыть файл somefile.txt' );
?>
Как избежать неправильного приложения семантики?
В приведенном примере генерируется сообщение об ошибке. Но PHP предоставляет программисту больше свободы, чем другие, традиционные языки программирования. Это позволяет получать интересные результаты. Как минимум, теоретически возможно написать корректный код, неправильно используя семантику языка.
Но будьте осторожны, заигрывая с семантикой языка! Возможно появление трудноуловимых ошибок в программах. Если же вы все-таки решили поэкспериментировать, вам следует понимать три ключевых момента:
  • Типы: В PHP каждая переменная в любой момент времени относится к определенному типу. И это несмотря на тот факт, что ее тип можно свободно изменять. Другими словами, в языке PHP переменная не может существовать, при этом не относясь к определенному типу (и, соответственно, не обладая характеристиками, присущими этому типу). В PHP есть 7 основных типов переменных: Booleanresourceintegerdoublestringarray и object.
  • Область видимости: В PHP переменные имеют область видимости, которая определяет то, откуда она может быть доступна и насколько долго будет существовать. Недопонимание концепции "области видимости" может проявляться в виде различного рода "плавающих" ошибок.
  • php.ini: При написании кода следует понимать, что не все пользователи имеют такую же конфигурацию программно-аппаратных средств, как и вы. Таким образом, совершенно необходимо лишний раз убедиться, сохраняется ли работоспособность вашего кода в той конфигурации, в которой программа должна работать, а не в той, в которой разрабатывалась.
19. Недостаточно либо излишне комментированный текст
Плохо документированный текст программы является признаком эгоистичного программиста. Результатом попытки анализа вашей программы с целью внесения улучшений будет только головная боль. Причем все программисты считают самодокументированный код хорошим тоном, но сами крайне редко пишут комментарии.
Следует также избегать избыточных комментариев. Это тоже встречается очень редко, и, опять же, создает трудно читаемый исходный код. Следующий пример это иллюстрирует:
<?php // Начало кода

$age = 18; // Возраст равен 18
$age++; // Увеличим $age на один год

// Напечатаем приветствие
print "Вам сейчас 19 лет, и это значит, что Вам уже было:";
print "\n<br>\n<br>\n";

// Цикл "для" чтобы вывести все
// предыдущие значения возраста
for ($idx = 0; $idx < $age; $idx++)
  {
    // Напечатаем каждое значение возраста
    print "$idx лет\n<br>\n";
  }
// Конец кода
?>
И все-таки: где золотая середина?
Итак, какой же объем комментариев следует помещать в скрипт?! Это зависит от многого: от времени, которым вы располагаете, от политики компании, сложности проекта и т.д. Тем не менее, запомните несколько основных принципов, которым надо следовать при написании программ вне зависимости от вашего решения:
  • Перед телом функции всегда помещайте комментарий - назначение функции.
  • Добавляйте комментарии в сомнительных участках кода, когда нет уверенности, что он будет работать как надо.
  • Если назначение кода неочевидно, внесите информацию о предназначении этого участка. Вы же потом воспользуетесь этим комментарием.
  • Избегайте комментарии вида # - используйте только /* */ либо //.
Следующий пример иллюстрирует хороший стиль комментариев:
<?php
  // Random_Numbers.lib
  // Генерация случайных чисел различного типа

  mt_srand((double)microtime()*1000000);

  //
  // mixed random_element(array $elements[, array weights]) 
  // Возвращает случайный элемент массива-аргумента
  // Массив weights содержит относительные вероятности
  // выборки элементов
  //

  function random_element ($elements, $weights = array())
  {

    // Для корректного функционирования этого алгоритма
    // количество элементов массива должно быть равным
    // количеству элементов массива относительных вероятностей

    if (count ($weights) == count ($elements)) {
      foreach ($elements as $element) {
        foreach ($weights as $idx) {

          // Примечание: мы не используем $idx, потому что
          // нам не нужен доступ к отдельным элементам
          // массива weights

          $randomAr[] = $element;
        }
      }
    }
    else {
      $randomAr = $elements;
    }

    $random_element = mt_rand (0, count ($randomAr) - 1);
    return $randomAr [$random_element];
  }
?>
18. Слишком много переменных - слишком большое время выполнения
Некоторые прямо-таки страдают навязчивой идеей вводить временные переменные где надо и где не надо. Совершенно невозможно понять, чем руководствовался человек, написавший такой код:
<?php
  $tmp = date ("F d, h:i a"); // т.е. формат даты February 23, 2:30 pm
  print $tmp;
?>
Для чего здесь использована временная переменная?! Она просто не нужна:
<?php
  print date ("F d, h:i a");
?>
К сожалению, многие программисты никак не могут избавиться от этой дурной привычки. Использование временных переменных замедляет выполнение программы. Для увеличения скорости кода, где это возможно, лучше воспользоваться вложением функций. Использование временных переменных зачастую увеличивают время выполнения скриптов почти на четверть.
Еще одна причина, по которой следует избегать использования излишнего количества временных переменных, это ухудшение читаемости кода. Сравните два приведенных примера. Какой из них выглядит более элегантно - с использованием временной переменной или без? Какой код проще прочесть? Использование лишних временных переменных ведет к написанию менее читаемого и ясного кода.
Плюсы использования временных переменных
Введение временных переменных позволяет упростить некоторые сложные выражения или вызовы функций. Еще они приносят пользу, когда позволяют избежать многократного вызова функции с одними и теми же аргументами.
Вот пример, в котором не используется лишних переменных:
<?php

// string reverse_characters (string str)
// Переворачивает строку символов

function  reverse_characters ($str)
{
    return implode ("", array_reverse (preg_split ("//", $str)));
}

?>
Вызову функции implode() в качестве одного из параметров передается результат выполнения вложенных функций, поэтому такой код трудно прочесть. В данном случае нам может здорово помочь использование временной переменной:
<?php

// string reverse_characters (string str)
// Переворачивает строку символов

function reverse_characters ($str)
{
    $characters = preg_split ("//", $str);
    $characters = array_reverse ($characters);
    return implode (""$characters);
}

?>
Золотое правило
Если вы думаете, ввести или нет еще одну временную переменную, задайте себе два вопроса:
  • Будет ли эта переменная использована хотя бы дважды?
  • Значительно ли улучшится с ее введением читаемость кода?
Если на любой из этих вопросов вы ответили "да", тогда введите временную переменную. Иначе комбинируйте вызовы функций (если это необходимо) и обойдитесь без ее использования.
17. Переписываем стандартные функции
Кое-кто рекомендует переименовывать стандартные функции для того, чтобы программистам на Visual Basic"е проще было перейти к использованию языка PHP:
<?php
  function len ($str) {
    return strlen ($str);
  }
?>
Встречаются также рекомендации приступая к программированию на PHP, первым делом заменять имена встроенных функций более привычными.
Существует, как минимум, две причины этого не делать. Во-первых, и прежде всего, мы получаем менее читаемый код. Люди, читающие ваш код, увидят массу очевидно ненужных функций и будут сильно удивлены, почему же вами не использовались стандартные функции PHP.
Ну и, наконец, это замедляет программу. Дело не только в необходимости обработки большего объема кода, но и в том, что для вызова такой пользовательской функции, требуется больше времени, чем для прямого вызова стандартной функции.
Используйте стандартные функций языка!
Иногда так трудно устоять! Ведь программист редко знает сразу весь набор функций - у него обычно нет времени запомнить их все. Почему бы просто не переименовать функцию? Но, повторимся, этого не следует делать в силу изложенных выше причин.
Хорошо бы иметь под рукой справочник по функциям PHP (удобно использовать индексированную версию в формате PDF). И перед тем как написать какую-либо функцию, внимательно посмотреть - не существует ли она уже в списке стандартных функций.
Но следует заметить, что в кодах программ можно встретить пользовательские функции, написанные еще до их введения в качестве стандартных (например, функции сравнения двух массивов). Это не означает, что вы обязательно должны переписать код и заменять их стандартными функциями.
16. Клиентская часть программы не отделяется от серверной части
Многие программисты рекомендуют объединять код HTML (интерпретируемый на стороне клиента) и код PHP (выполняемый сервером) в один большой файл.
Для маленьких сайтов это, возможно, неплохо. Но, когда ваш сайт начнет расти, вы можете столкнуться с проблемами при необходимости добавить какие-либо новые функции. Такой стиль программирования приводит к очень "непослушному" и громоздкому коду.
API функций
Если вы собрались отделить код PHP от HTML кода, у вас есть два варианта. Один способ - - создать функции динамического формирования вывода и поместить их в нужное место на веб-странице.
Например, так:
index.php - код страницы

<?php include_once ("site.lib"); ?>
<html>
<head>
    <title><?php print_header (); ?></title>
</head>
<body>
    <h1><?php print_header (); ?></h1>
    <table border="0" cellpadding="0" cellspacing="0"> 
        <tr>
            <td width="25%">
                <?php print_links (); ?>
            </td>
            <td>
                <?php print_body (); ?>
            </td>
        </tr>
    </table>
</body>
</html>

site.lib - Сам код программы

<?php

$dbh = mysql_connect ("localhost""sh", "pass")
  or die (sprintf ("Не могу открыть соединение с MySQL [%s]: %s",
                   mysql_errno (), mysql_error ()));

@mysql_select_db ("MainSite")
  or die (sprintf ("Не могу выбрать базу данных [%s]: %s",
                   mysql_errno (), mysql_error ()));

$sth = @mysql_query ("SELECT * FROM site", $dbh)
  or die (sprintf ("Не могу выполнить запрос [%s]: %s",
                   mysql_errno (), mysql_error ()));

$site_info = mysql_fetch_object ($sth);

function print_header ()
{
    global $site_info;
    print $site_info->header;
}

function print_body ()
{
    global $site_info;
    print nl2br ($site_info->body);
}

function print_links ()
{
    global $site_info;

    $links = explode ("\n", $site_info->links);
    $names = explode ("\n", $site_info->link_names);

    for ($i = 0; $i < count ($links); $i++)
    {
        print "\t\t\t
               <a href=\"$links[$i]\">$names[$i]</a>
               \n<br>\n";
    }
}
?>
Очевидно, такой код лучше читаем. Еще одно преимущество использования этой концепции - возможность изменения дизайна без модификации самого кода программы.

Плюсы использования API функций

  • Относительно чистый, ясный код
  • Быстрый код

Минусы использования API функций

  • Не настолько наглядно как система шаблонов
  • Все-таки для модификации дизайна требуется некоторое знание PHP
Система шаблонов
Второй способ, используемый для разделения PHP и HTML кода, - использование шаблонов. В данном случае некоторые элементы дизайна заменяются пользовательскими тегами, а сама программа сканирует файл на предмет их наличия и заменяет их необходимой информацией.
Пример использования шаблонов:
<html>

  <head>
    <title>%%PAGE_TITLE%%</title>
  </head>

  <body %%BODY_PROPERTIES%%>
    <h1>%%PAGE_TITLE%%</h1>
    <table border="0" cellpadding="0" cellspacing="0">
      <tr>
        <td width="25%">%%PAGE_LINKS%%</td>
        <td>%%PAGE_CONTENT%%</td>
      </tr>
    </table>
  </body>

</html>
Затем пишем программу, просматривающую код шаблона и при выводе заменяющую тэги вида %%SOME%% нужной информацией.
Примечание: неплохой класс для использования его в системе шаблонов - FastTemplate, его можно скачать с http://www.thewebmasters.net/.

Плюсы использования шаблонов:

  • Предельно просто и ясно
  • Для изменения шаблонов не требуется знание PHP

Минусы использования шаблонов:

  • Более медленный способ - ведь надо сканировать весь шаблон и лишь потом выводить данные
  • Сложнее внедрить на практике
15. Использование устаревшего синтаксиса и функций
Некоторые программисты вновь и вновь используют старые библиотеки и старые наработки. Например, код, написанный еще под PHP 2, до сих пор используется с PHP4, хотя уже начиная с версии PHP3 были добавлены стандартные функции, реализующие то же самое.
Использование устаревших функций и синтаксиса могут снизить скорость выполнения кода и, к тому же, сделать его нечитаемым. Другие программисты могут быть незнакомы со старыми функциями. Но тем не менее, если вы встретили участок старого кода, не обязательно его переписывать с учетом новых правил языка. Просто не надо его использовать при написании новых программ.
Пример использования старых языковых конструкций:
<?php

  // Старый стиль

  while (1):
    print "5";
    if ( $idx++ == 5 ):
      break;
    endif;
  endwhile;

  // Лучше написать так
  // (впрочем, код можно оптимизировать)

  while (1)
  {
    print "5";
    if ( $idx++ == 5 ) {
      break;
    }
  }

?>
Почему же следует следовать новым стандартам? Причины следующие:
  • Использование старых конструкций не очень распространено и, таким образом, новички в PHP будут в замешательстве, увидев два разных варианта синтаксиса.
  • Старый синтаксис отличается от синтаксиса других языков программирования, и, следовательно, при переходе с другого языка на PHP программисту будет сложнее понять и привыкнуть.
  • Но самое главное - в одной из новых версий, возможно, будет исключена поддержка старого синтаксиса, тем самым это заставит вас переписать код заново. Как бы то ни было, скобки всегда останутся частью языка PHP.
Подобные участки кода можно встретить во многих программах. Вам, как правило, следует руководствоваться правилами, приведенными в документации по PHP, большей частью обновленной - в ней отражается развитие языка. Периодически просматривайте документацию, ведь язык развивается, добавляются новые функции. Таким образом, вам никогда не придется писать пользовательские функции, выполняющие ту же работу, что и стандартные.
Резюме
В этой статье мы рассмотрели первые 7 из 21 наиболее общих ошибок PHP программиста. Как правило, они не нарушают работоспособности программ, но, тем не менее, их следует избегать:
  • Необоснованное применение функции printf(): Ее следует использовать только для вывода форматированных данных.
  • Неправильное применение семантики языка: Многие программисты не имеют достаточно времени, чтобы разобраться во всех тонкостях языка, что впоследствии выражается в ошибочном коде.
  • Плохо комментированный код: Всегда пишите комментарии! Перед каждой функцией указывайте, что делает данная функция, и какие аргументы она требует. Также комментируйте сложные участки кода и внесенные изменения.
  • Слишком много временных переменных: Временные переменные хорошо использовать для предотвращения повторного вызова функций или последовательностей функций.
  • Изобретаем велосипед - переписываем стандартную функцию: Сначала загляните в руководство по PHP - не описана ли там функция, которую вы собираетесь написать для, казалось бы, расширения набора стандартных функций PHP.
  • Смешан PHP и HTML код: Попробуйте сделать код как можно более модульным. Потом вам (и другим тоже) можно будет сменить дизайн страницы без изменения кода PHP.
  • Используются старые языковые конструкции и устаревшие функции: То, что вы можете сделать, не всегда следуетделать. Загляните в документацию и литературу по PHP как писать правильно. Отличные книги - "Разработка веб-приложений с использованием PHP (Web Application Development with PHP)" и "Профессиональный программист PHP (Professional PHP)". (Эх, где бы их еще найти! ;)) - прим. переводчика)
Об авторе
Стерлинг Хьюз (Sterling Hughes) - независимый разработчик веб-сайтов, занимается созданием динамических веб-приложений для некоторых крупнейших мировых компаний. Участвовал в создании cURL and SWF расширений PHP с открытым исходным кодом. Его книга, "Настольная книга программиста PHP" (The PHP Developer's Cookbook), была издана в октябре 2000 года издательством "Sams publishing".
О переводчике
Дмитрий Короленко. Ну что о нем много говорить? ;)) Благодаря ему люди, не знающие английского, или знающие, но не очень ;)), смогут прочесть весьма познавательную статью Стерлинга Хьюза. О замеченных недостатках перевода просьба сообщать на мыло: lkx2@mail.ru Сразу хочется пояснить, что дословный перевод не был самоцелью, но, тем не менее, стиль и смысл оригинальной статьи по возможности ;)) сохранялись. Все замечания и пожелания приветствуются и будут учтены, ибо готовится перевод второй части этой статьи. Только просьба ногами не пинать ;)) Все же я надеюсь, что если вы до этого места дочитали, то не все так плохо ;))
Продолжение (Часть 2) >

воскресенье, 20 января 2019 г.

MySQL для начинающих

MySQL для начинающих

Автор: Марк Ильин
Как только мы задумываемся о каком-либо упорядоченном архивировании информации, мы неизбежно приходим к мысли о создании базы данных. Создав её, напрмер, в Microsoft Access, мы, облегчённо вздыхаем и на какое-то время успокаиваемся. Но это спокойствие длится не долго. И вот на нашем горизонте уже маячит следующая задача, продиктованная жизненной необходимостью, - нужно обеспечить доступ к этим данным через internet с рабочих станций, на которых, вполне возможно установлены, различные ОС. Естественно не мы первые, кому необходимо разрешить задачу подобного рода. Опыта других людей и средств для разрешению этой проблемы довольно много. Но хватит лирических отступлений. Мы воспользуемся языком , который позволяет пользователям, знающим один набор команд, использовать их, чтобы создавать, отыскивать, изменять, и передавать информацию, независимо от того, работают ли они на персональном компьютере, сетевой рабочей станции, или на универсальной ЭВМ.
SQL ( Обычно произносимая как "СЭКВЭЛ") символизирует собой Структурированный Язык Запросов. Это - язык, который дает вам возможность создавать и работать в реляционных базах данных, которые являются наборами связанной информации сохраняемой в таблицах.
Что такое - реляционная база данных?
Реляционная база данных - это тело связанной информации, сохраняемой в двухмерных таблицах. Напоминает адресную или телефонную книгу.
В книге имеется большое количество входов, каждый из которых соответствует определенной особенности. Для каждой такой особенности, может быть несколько независимых фрагментов данных, например имя, телефонный номер, и адрес. Предположим, что мы должны сформатировать эту адресную книгу в виде таблицы со строками и столбцами. Каждая строка (называемая также записью) будет соответствовать определенной особенности; каждый столбец будет содержать значение для каждого типа данных - имени, телефонного номера, и адреса представляемого в каждой строке. Адресная книга могла бы выглядеть следующим образом:
Имя
Телефон
Адрес
Petrov
3232323
Адрес 1
Ivanov
3636666
Адрес 2
Sidoroff
3434342
Address3
То, что вы получили, является основой реляционной базы данных, как и было определено в начале этого обсуждения - а именно, двухмерной (строка и столбец) таблицей информации.
Однако реляционные базы данных редко состоят из одной таблицы. Такая таблица меньше, чем файловая система. Создав несколько таблиц взаимосвязанной информации, вы сможете выполнить более сложные и мощные операции с вашими данными. Мощность базы данных зависит от связи, которую вы можете создать между фрагментами информации, а не от самого фрагмента информации.
Связывание одной таблицы с другой
Предположим, что персонажи в нашей первой таблице ( адресной книги ) - это пациенты больницы. В другой таблице, мы могли бы запомнить дополнительную информацию об этих пациентах. Столбцы второй таблицы могли бы быть помечены как Пациент, Доктор, Страховка, и Баланс.
Пациент
Доктор
Страховка
Баланс
Ivanov
Vostrikovr
B.C./B.S.
$272.99
PetrovVostrikovr
Никто
$44.76
барсук
Perepelkin
Здоровье, Inc
$977.47
Много мощных функций можно выполнить, извлекая информацию из этих таблиц согласно указанным параметрам, особенно когда эти параметры включают в себя фрагменты информации связанные в различных таблицах друг с другом. Например, возьмем - докторов. Предположим, доктор Perepelkin захотел получить номера телефонов всех своих пациентов. Чтобы извлечь эту информацию, он мог бы связать таблицу с номерами телефонов пациентов (по адресной книге) с таблицей которая бы указывала, какой из пациентов - его. Хотя, в этом простом примере, он мог бы держать это в голове и сразу получать номера телефонов пациентов, эти таблицы могут быть слишком большими и слишком сложными. Программы реляционной базы данных разрабатывались для того чтобы обрабатывать большие и сложные совокупности данных такого типа, что, очевидно, является более универсальным методом в деловом мире. Даже если бы база данных больницы содержала сотни или тысячи имен - как это вероятно и бывает на практике - одна команда SQL могла бы выдать доктору информацию, в которой он нуждался, почти немедленно.
Язык SQL достаточно сложен и многогранен. При работе же небольшой фирмы, или базы данных в сети internet круг задач ограничен. Поэтому была создана небольшая, но очень быстрая и функциональная реляционная СУБД MySQL. Тоесть, как вы уже догадались в MySQL задействован не весь язык SQL, а только необходимая его часть. Но не нужно переживать относительно урезанности.
Перечислю основные приятные стороны пакета MySQL -это многопоточность, поддержка нескольких одновременных запросов, оптимизация связей с присоединением многих данных за один проход, записи фиксированной и переменной длины, ODBC драйвер в комплекте с исходником, гибкая система привилегий и паролей, до 16 ключей в таблице, каждый ключ может иметь до 15 полей. Также есть поддержка ключевых полей и специальных полей в операторе CREATE, поддержка чисел длинной от 1 до 4, строк переменной длины и меток времени, интерфейс с языками C и perl. Основанная на потоках, быстрая система памяти, утилита проверки и ремонта таблицы, все данные хранятся в формате ISO8859_1. Все операции работы со строками не обращают внимания на регистр символов в обрабатываемых строках, псевдонимы применимы как к таблицам, так и к отдельным колонкам в таблице, все поля имеют значение по умолчанию. INSERT можно использовать на любом подмножестве полей. Легкость управления таблицей, включая добавление и удаление ключей и полей.
Можно выполнять команды SQL непосредственно из командной строки системы unix или из интерактивного режима MySQL. СУБД MySQL имеет библиотеку C API. Ее можно использовать для запросов к базе данных, вставки данных, создания таблиц и т.п.
C API поддерживает все функции MySQL. Язык perl поддерживается сразу двумя способами:
  • Портирован интерфейс с perl из mini-SQL, разработанный Андреасом Коенигом.
  • Есть модуль perl DBD
Также доступен 32-битный ODBC драйвер для MySQL. Он позволяет запрашивать и получать данные из других источников с поддержкой ODBC.
Кроме технических подробностей можно добавить, что MySQL работает как на Unix, так и на платформе Windows, он очень прост и удобен в работе.
И чтобы подвести итог, хотелось бы рассказать одну историю. Одной небольшой фирме потребовалось сделать на сайте базу данных по товарам. Человек, которому поручили сделать базу данных, создал её на Delphi. Так вот, когда пришло время размещать базу в сети, обнаружился очень неприятный факт. Все ISP работают на Unix, соответственно для размещения подобной базы нужно ставить у провайдера свой компьютер и платить, в среднем, около 50 у.е. за хостинг. В случае же если СУБД сделана под MySQL, то платить придется лишь за мегабайты.
MySQL - это удобно и практично. А скорость работы просто завораживает. Так что не теряйте время зря, за этой технологией - будущее.

Пишем PHP код, устойчивый к ошибкам

Пишем PHP код, устойчивый к ошибкам

Автор: Александр Неткачев
Предисловие
Ошибки - это бич любой программы. Чем больше проект, тем труднее исправлять и находить ошибки. Но наиболее важным в процессе работы с программой является квалификация программиста и его желание написать правильный и аккуратный код, содержащий минимальное количество ошибок.
В этой статье я постараюсь собрать техники и приемы, позволяющие минимизировать количество ошибок в программе, написанной на PHP. Но некоторые из представленных методов могут пригодится если вы пишите на любом языке программирования.
Знание - половина успеха
Узнаем, о чем сообщает PHP
В любом языке существует множество потенциально опасных ситуаций, которые чреваты неявными ошибками. При разборе транслятором исходного кода программы он может сообщать разработчику об этих ситуациях. Для этого надо лишь включить соответствующую опцию, которая очень часто по умолчанию выключена по некоторым соображениям.
В PHP контроль вывода сообщений транслятора определяется функцией error_reporting и значением директивы error_reporting в php.ini. Рекомендуемое её значение E_ALL - т.е. выводить сообщения о всех потенциально опасных ситуациях. К ним в PHP относятся, например, использование неинициализированной переменной, обращение к несуществующему элементу массива и т.д.
Для включения максимально подробного вывода сообщений транслятора поставьте в начале программы вызов функции error_reporting:
// Для PHP4 error_reporting(E_ALL);
или поставьте значение error_reporting = E_ALL в php.ini.
С более подробном описании возможных уровней reporting можно знакомится в PHP документации - Error Handling and Logging Functions.
Для PHP5 введен уровень E_STRICT, который включает вывод сообщений о использовании в коде устаревших методов программирования (например, используется var для описания внутренних переменных класса). Он не входит в E_ALL, поэтому для PHP5 рекомендуемый уровень сообщений E_ALL | E_STRICT (т.е. E_ALL и E_STRICT). Соответственно, для задания вывода всех сообщений от транслятора надо вызвать error_reporting с таким параметром:
// Для PHP5 error_reporting(E_ALL E_STRICT);
Если ни о чем не сообщает
Если Вы установили вывод ошибок и ошибки по не выводятся, то возможно вывод ошибок в script output отключен. Проверьте значение опции ini файла display_errors (она включает вывод ошибок непосрественно в script output) и, если она выключена, включите её.
if (ini_get('display_errors') != 1) { // проверяет значение опции display_errors
    
ini_set('display_errors'1); // включает вывод ошибок вместе с результатом работы скрипта }
Если вдруг сообщит
Крайне редко удается протестировать программу полностью до выпуска и в то-же время лучше не показывать пользователю сообщения об ошибках ибо его реакция на них непредсказуема. Лучше перенаправлять ошибки транслятора, которые произошли непосредственно во время работы программы, в log файл ошибок. Включить это перенаправление можно опцией log_errors в файле php.ini.
Полезно также поставить свой обработчик ошибок, если Вы хотите не только заносить ошибки в Log файл но и добавить некоторую дополнительную логику их обработки. Например, отправить письмо при сообщении транслятора или вывести некоторое специальное сообщение для пользователя. Подробнее об этом написано в статье Ловля ошибок в PHP, которую написал Антон Довгаль.
Сравниваем константу с переменной, а не наоборот
Сколько раз Вам приходилось выяснять, что ошибка в программе связанна с использованием оператора "=" вместо "=="? Что бы приходилось реже, используйте сравнения вида
if (10 == $i) {
    
// что-то делаем }
В случае использования "=" вместо "==" транслятор выдаст ошибку "Parse error: parse error in ... on line ...". Таким образом ошибка обнаруживается значительно быстрее.
Не используем значение дважды
Конечно, это преувеличение. Но если в программе возникает необходимость использовать значение несколько раз, можно порекомендовать объявить константу и использовать её вместо значения.
Для PHP4 существует единственный способ объявить константу - использовать функцию define.
Например:
define ('BEFORE_RENDER', 'beforeRender');
Констант в классах объявлять нельзя.
Расширение PHP 5 для определения констант сходно с тем, которое было осуществлено при расширении от C до C++ - используется ключевое слово const. Но константы таким образом можно создавать только внутри классов.
Например:
class ControlEvents {
    const 
BEFORE_RENDER 'beforeRender';
}
print 
ControlEvents::BEFORE_RENDER;
Но для обращения к такой константе необходимо знать имя класса.
Константы могут быть также добавлены непосредственно в класс. Но PHP не поддерживает такой метод. Поэтому придется объявить их как обычные переменные:
class Control {

    var 
$BEFORE_RENDER 'beforeRender';
    function 
render() {
        
$eventFunction $this->BEFORE_RENDER;
        
$this->$eventFunction();
    }
}
Проверка параметров функции
В PHP параметром в функцию можно передать любую переменную. Но вот алгоритму функции может быть вовсе не все равно, что за переменную ему передали. Поэтому в начале функции полезно проверять её входные параметры на необходимый тип и диапазон значений.
Для проверки типа используются следующие функции:
  • gettype(Mixed $var) - возвращает тип переменной. Наиболее часто используемые типы: "boolean", "integer", "double", "string", "array", "object", "resource", "NULL".
  • Функции проверки на тип: is_bool(Mixed $var), is_integer(Mixed $var), is_double(Mixed $var), is_string(Mixed $var), is_array(Mixed $var), is_object(Mixed $var), is_resource(Mixed $var) - возвращают true или false.
  • Для определения класса объекта используются функции:
    • get_class(Object $obj) - возвращает имя класса, экземпляром которого является obj.
    • is_a(Object $obj, String $class) - проверяет, является ли obj экземпляром сласса class или класса, унаследованного от class.
Для PHP4 не существует автоматического способа проверки параметров функции. Все необходимые проверки необходимо делать самостоятельно.
Код функции, осуществляющей проверку аргументов, может быть примерно такой:
/**
* Функция showControl принимает один параметр $control,
* этот параметр должен являться классом и являться
* экземпляром класса HTMLControl либо классом,
* унаследованным от HTMLControl.
*/ 
function showControl(&$control) {
    
is_a($control'HTMLControl') or $control == null or exit('Type missmatch.');
    ...
}
Достоинство этого метода состоит в том, что можно управлять сообщениями об ошибках и использовать собственный обработчик ошибок. Например, Вы можете использовать следующие функции для проверки параметров:
function checkParameter(&$var$class) {
    if (!
is_a($var$class) && $var != null)
        
SFExit('Type missmatch.');
}

function 
SFExit(&$message) {
    print 
$message '<br>';
    
$backtrace debug_backtrace();
    for(
$i 0$i count($backtrace); $i++) {
        print 
$i ': ' $backtrace[$i]['file'] . '(' $backtrace[$i]['line'] . ')<br>';
    }
    exit();
}
Примечание: Функция debug_backtrace введена только в PHP 4.3.0.
Пример их применения:
function showControl(&$control) {
    
checkParameter($control'HTMLControl');
    ...
}
Для PHP5 некоторые проверки типов параметров можно задать непосредственно в описании функции. Предыдущий пример на PHP5 будет выглядеть следующим образом:
function showControl(HTMLControl $control) {
    ...
}
Asserts
Во время создания и отладки программы можно использовать встроенный механизм добавления проверок в код программы. Он называется asserts (или assert-проверки). Идея его состоит в том, что в код программы добавляются специальные проверочные конструкции, которые можно отключить для production сайта, но в любой момент включить при разработке.
Следующие фрагменты кода примерно аналогичны:
/* Использование Asserts */ assert_options (ASSERT_ACTIVE1);

function 
showControl(&$control) {
    
assert('is_a($var, \'HTMLControl\') || $var == null');
    ...
}
/* Использование if конструкций */ define('ASSERT_ACTIVE'1);
function 
showControl(&$control) {
    if (
ASSERT_ACTIVE && !(is_a($var'HTMLControl') || $var == null'))
        trigger_error('
Assertion failed', E_USER_ERROR);
    ...
}
С помощью таких проверок также можно проверять параметры функций, возвращаемые функциями значения и т.д. Нужно лишь учесть, что assert-проверки не должны быть включены в реально действующем сайте - если программа нормально работает и проходит все проверки, то их можно отключить.
Проверять значения параметров скрипта $_REQUEST, $_GET, $_POST, $_COOKIES.
PHP скрипт можно рассматривать как большую функцию, которая вызывается с неопределенным списком string параметров. Если предполагается, что некоторые параметры будут использоваться в некоторых вычислениях, или отправляться в базу данных, то их обязательно надо преобразовывать к требуемому типу и использовать только после явного приведения!
Все массивы REQUEST являются является обычными массивами, поэтому значения в них могут быть переопределены непосредственно.
Например:
if (isset($_GET['id']))
    
$_GET['id'] = (int)$_GET['id'];
else
    
$_GET['id'] = null;
Разделяй и властвуй
Известный со времен древнего Рима принцип "Разделяй и властвуй" вполне может пригодится при разработке программ на любом языке программирования. В том числе и на PHP. Для реализации этого принципа разделяйте программу на логические блоки. Для этого можно воспользоваться следующими методами:
  • Использование функций. Выносите структурные части алгоритма в функции. Проверяйте каждую часть отдельно и затем работу всего алгоритма в целом.
  • Использование классов. Организуйте программный код в виде объектов, взаимодействующих друг с другом. Выделяйте сущности и оформляйте их в виде объектов. Внимательно рассматривайте, как они взаимодействуют друг с другом. Используйте, где это разумно, лучшие шаблоны проектирования (design patterns).
  • Разделяйте логику и HTML. Для этого существует множество способов: темплейтные библиотеки, XML, XML/XSL. Подберите для себя наилучший и используйте.
  • Разделяйте логику самого приложения при помощи enterprise design patterns. Используйте разделение приложения на уровни (layering) и другие технологии, позволяющие структурно разделить проект на крупные блоки.
Заключение
Возможно, кому-то материал статьи покажется сбором прописных истин. Но я думаю, что большинству он все-таки пригодится, а для начинающих программистов последний раздел "Разделяй и властвуй" может оказаться особенно полезным, поскольку задает направление изучения программирования.
Если у Вас есть комментарии или собственные приемы работы, которые не упомянуты в этой статье, я буду рад услышать и обсудить их с Вами.
Также хочу выразить признательность участникам клуба phpclub.ru за помощь в написании статьи.

Введение в SQLite

Введение в SQLite

Автор: Леонид Лукин
SQLite – это библиотека, написанная на языке C, реализующая SQL механизм работы с данными, другими словами, движок баз данных.
SQLite не является клиентской библиотекой, позволяющей только подсоединять приложение к серверу баз данных, SQLite сама является сервером баз данных.
SQLite библиотека производит запись данных непосредственно в файл на диске, а также позволяет читать, обновлять и искать данные на основе языка запросов SQL, преимущественно ориентируясь на стандарт SQL 92.

Основные преимущества использования SQLite

Распространяется бесплатно.
Простота установки.
В PHP 5 поддержка SQLite встроена автоматически (SQLite 2.8.14).
Легкость администрирования.
А поскольку SQLite хранит данные в обычных файлах, то отпадает всякая необходимость в дополнительных средствах администрирования. Каждый пользователь имеет свои собственные базы данных (в любом количестве создаваемые самим пользователем!) и права доступа реализуются файловой системой сервера автоматически.
Простота использования.
В отличие от других баз данных SQLite является бестиповой базой. При создании таблицы необходимо только указать имена полей, но не их тип, так как все данные SQLite хранит в формате строки. Единственное отличие по типу актуально только в случае сортировки данных и это различие обыгрывается внутри самой SQLite.
Производительность.
Поскольку движок базы и интерфейс к ней реализованы как единое целое, огромный преимуществом SQLite является высокая производительность – для большинства типичных задач приложение, построенное на SQLite, работает быстрее, чем при использовании MySQL, в 2-3 раза и быстрее PostgreSQL в 10-20 раз! И это притом, что объем памяти сервера, который он выделяет для SQLite, очень и очень мал.
Сравнение скорости работы SQLite c MySQL и PostgreSQL
По данным тестирования - www.hwaci.com/sw/sqlite/speed.html
Легкая переносимость между платформами, веб-серверами и приложениями. 
Фалы баз данных совместимы с различными платформами (Windows, UNIX). Для переноса базы данных на веб-сервер нужно всего лишь перенести 1 файл. Резервное копирование данных также осуществляется копированием файла базы данных.
Объектно-ориентированный интерфейс.
Еще одним не менее важным преимуществом SQLite является возможность использования мощного объектно-ориентированного интерфейса к SQLite, что позволяет строить высокоэффективные, легко расширяемые приложения.
Возможность хранить данные в базе объемом до 2 терабайт.
SQLite позволяет сохранять строки и бинарные данные неограниченной длины.

Ограничения использования SQLite

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

суббота, 19 января 2019 г.

MySQL. Установка. Настройка. Использование

MySQL. Установка. Настройка. Использование

Автор: Алексей Литвинюк
На сегодняшний день СУБД MySQL является одной из самых известных, надежных и быстрых из всего семейства существующих СУБД. Почему именно она? Одной из причин являются правила ее распространения — за нее не надо платить деньги и распространяется она вместе со своими исходными текстами. Однако многие могут возразить, ведь есть же PostgreSql, почему не она? Да, действительно PostgreSql также распространяется под лицензией *GNU GPL, но она не получила столь широкого распространения. Одна из причин — это заметная медлительность. Сегодня MySQL особенно распространена на платформах Linux и Windows. Причем на последней встречается гораздо реже. В этой статье я хотел бы поделиться с читателем личным опытом установки, конфигурирования, администрирования и программирования СУБД MySQL (в дальнейшем для простоты будет упоминаться просто MySQL).
Для начало мне бы хотелось познакомить читателя с принципами работы СУБД, которые используют SQL в качестве командного языка. SQL — (Structured Query Language, язык структурированных запросов) сердце любой современной СУБД. Он используется для создания/удаления баз данных, таблиц, для пополнения таблиц данными, для осуществления выборки данных. Эта тема заслуживает отдельной статьи, но тем, кому это действительно необходимо, я бы посоветовал прочесть книгу Мартина Грубера "Понимание SQL". Исходя из этого, любая СУБД представляет собой программу-сервер, которая сидит в памяти компьютера и обслуживает TCP порт. В случае с MySQL, номером порта будет являться число 3306. А клиентская программа, будь то CGI-приложение на Perl либо полноценный программный продукт для предприятия на C, соединяется с СУБД по этому порту и посылает ему строчки на SQL. Тот в свою очередь их интерпретирует, выполняя необходимые действия, и отсылает результаты запроса обратно клиенту. Таким не хитрым способом происходит общение сервера баз данных с клиентскими программами. Теперь, имея некоторое понятие о том, каким образом работают серверы баз данных, перейдем непосредственно к установке MySQL.
Установка
MySQL написан под десятки видов операционных систем. Это и FreeBSD, OpenBSD, MacOS, OS/2, SunOS, Win9x/00/NT и Linux. Мною использовался дистрибутив Red Hat Linux 7.0. В силу своей простоты, данный дистрибутив не заставил мучаться с установкой и произвел ее самостоятельно на этапе установки самой ОС. Если вам аналогично повезло, то на этом этап установки для вас завершен, и вы можете смело переходить к настройке. Для многих встает вопрос, где взять дистрибутив MySQL. Он может находиться на диске с Linux в виде установочного модуля RPM либо в виде архива tgz(tar.gz). Если его там нет, то дистрибутив можно совершенно бесплатно скачать с официального сайта www.mysql.org. Для установки необходима версия ядра не ниже 2.0. Если вы скопировали архив *.tar.gz, то для установки скопируйте его в директорию, где вы хотите установить MySQL, и выполните следующие действия:
1) Распакуйте архив, выполнив следующую команду
gunzip <mysql-VERSION.tar.gz | tar xvf -
где, вместо VERSION, будет версия вашего дистрибутива (к примеру, у меня 3.23.22-beta). В результате будет создана директория mysql-3.23.22-beta, где находятся файлы дистрибутива.
2) Перейдите в эту директорию.
CD MySQL - 3.23.22 - бета
3) Подготовка к установке.
./configure --prefix = / usr / local / mysql
делать
В данном случае MySQL будет установлен в директорию /usr/local/mysql. В случае фатального завершения следующих команд необходимо внимательно ознакомиться с выведенными ошибками. В случае чего можно обратиться к документации.
4) Непосредственно установка.
сделать установку
5) Теперь необходимо создать так называемые grant таблицы. Для этого необходимо выполнить следующий скрипт:
сценарии / mysql_install_db
Теперь можно удалить директорию, в которую вы распаковывали архив дистрибутива, после чего можете удостовериться, что MySQL был проинсталлирован в указанную директорию (в нашем случае — это /usr/local/mysql). Для того чтобы запустить сервер СУБД MySQL, следует выполнить скрип_f2 safe_mysqld, который находится в директории /usr/ local/mysql/bin.
На этом процесс инсталляции из архива tgz(tar.gz) можно считать выполненным.
В случае если вы устанавливаете MySQL из установочного пакета RPM, то процесс инсталляции оказывается намного проще. Для установки пакетов RPM существует утилита rpm. Чтобы установить пакет, вам достаточно набрать следующую команду:
rpm -i mysql-3.23.22-beta.rpm
Теперь, когда вы выполнили эту команду, вы можете смело запускать safe_mysqld для первого старта MySQL.
После того, как мы установили непосредственно MySQL, необходимо установить также модули Perl, чтобы Perl мог работать с базами данных посредством технологии DBI/DBD. Об этой технологии будет рассказано чуть позже. Вам лишь необходимо скачать установочный пакет DBI с сайта www.cpan.org, а также установочный пакет драйвера DBD с сайта www.mysql.org и установить их таким же образом, как мы устанавливали MySQL.
После установки всех вышеперечисленных пакетов смело можно переходить к настройке.
Настройка
Если установка была произведена корректно, то на данном этапе вы уже можете использовать MySQL в своих целях. На пятом этапе, когда вы запускали скрипт scripts/mysql_install_db, у вас появилась новая база данных 'mysql'. В ней скрипт создал шесть таблиц: 'user', 'db', 'host', 'tables_priv', 'columns_priv' и 'func'. Эта база данных необходима для установления привилегий пользователям. По умолчанию сервер MySQL использует номер порта 3306. Если данный порт у вас чем-то занят, то необходимо переопределить переменную MYSQL_TCP_PORT. Например, вот так:
MYSQL_TCP_PORT = 3307
экспорт MYSQL_TCP_PORT
Также можно поменять и другие параметры. В этом может помочь скрипт mysql_config. С его помощью можно менять, к примеру, директорию, где хранятся файлы баз данных, имя UNIX сокета, директорию временных файлов и пр. Чтобы проверить, правильно ли вы все сделали, запустите MySQL, перейдя в директорию, где находятся исполняемые файлы, и выполните команду:
./safe_mysqld &
Теперь наберите './mysqlshow mysql'. Вы должны увидеть что-то похожее:
База данных: MySQL
таблицы
columns_priv db func host tables_priv пользователь
Если не было выдано никаких ошибок, то можете смело набирать './mysql' и по полученному приглашению набирать команды SQL и не забывать ставить ";" после каждой команды.
Для примера выполните следующие команды последовательно:
СОЗДАТЬ БАЗУ ГРЯДКИ;
CREATE TABLE MAIN (a00 INTEGER, a01 CHAR (10));
ВСТАВЬТЕ В ОСНОВНЫЕ ЦЕННОСТИ (1, «Привет, мир!»);
ВЫБРАТЬ * ИЗ ГЛАВНОЙ;
После ввода последней строки вы должны увидеть таблицу:
а00 а01
1 Привет, мир!
Если так и произошло, то поздравляю, вы создали свою первую базу данных GRYADKA в СУБД MySQL. В этой базе данных существует единственная таблица с именем MAIN, которая, в свою очередь, содержит единственную запись. Настало время приступить к написанию программ, которые будут работать с установленной и настроенной вами СУБД MySQL. Если по каким-либо причинам сервер MySQL не запускается, то вам следует обратиться за помощью к справочному руководству.
Использование
В этом разделе хотелось бы рассмотреть возможности языка Perl для работы с MySQL. Может быть, не честно обходить вниманием возможности языка C и его интерфейс взаимодействия с СУБД, однако сегодня MySQL более широкое распространение получил на Web-серверах. А Perl как нельзя лучше других языков подходит для написания CGI-приложений. Многие могут возразить, что приложения на C работают намного быстрее. И это факт. Но у Perl есть мощность, простота и кое-какая платформонезависимость. Ну, а его регулярные выражения и прочие синтаксические особенности несоизмеримо превозносят его над другими языками программирования.
Итак, на этапе установки мы установили все необходимое для того, чтобы приложения на Perl могли взаимодействовать с MySQL. Это взаимодействие можно изобразить на схеме:
Прикладные программы–>DBI –>DBD–>СУБД
Как уже упоминалось выше, DBI обеспечивает единый интерфейс взаимодействия с различными системами управления базами данных. А DBD связывает этот интерфейс непосредственно с конкретной СУБД. В нашем случае это mysql. Исходя из этого, понятно, что для того, чтобы наша программа могла общаться и работать с базой данных, необходимо подключить модуль DBI и драйвер DBD. Это выполняется следующими операторами:
использовать DBI;
использовать DBD :: mysql;
Для того чтобы мы могли выполнять SQL запросы к нашей базе данных, нам нужно установить логическое соединение с MySQL. Это мы выполняем при помощи метода объекта DBI. При этом он возвращает объект (дескриптор) соединения, который мы будем использовать для непосредственного общения с базой данных.
$ dbh = DBI-> connect ('dbi: mysql: dbname = GRYADKA; хост = 127.0.0.1; порт = 3306', '', '', 0);
Вызывая метод connect, мы передаем ему некоторые параметры. Первый параметр определяет свойства соединения. Эта строка имеет следующую структуру:
"dbi:<имя DBD>:dbname= <имя базы данных>;host=<имя хоста>;port=<номер порта>"
Далее в методе connect определяются имя пользователя, пароль и флаги соединения. В нашем случае имя пользователя и пароль указывать нет необходимости, т.к. мы не создавали пользователей. Флаги передаются анонимным хэшем и в целом необходимости в них нет. Чтобы получить более подробную информацию, смотрите 'man DBI'. Существует два способа работы с базами данных MySQL. Первый — так называемый механизм курсоров, а второй, соответственно, без использования таковых. Для начала рассмотрим механизм курсоров. Курсоры — это объекты Perl, которые обеспечивают последовательный доступ к результатам запросов. Каждый курсор отвечает за закрепленный за ним запрос.
$ cur = $ dbh-> prepare ('select * from MAIN;');
$cur — это курсор, который для начала следует выполнить, используя метод execute:
$ Сила тока> выполнить;
Теперь, после выполнения запроса, чтобы получить результат запроса, используем метод fetchrow_array. Он поочередно возвращает массив полей результативной виртуальной таблицы. К примеру, чтобы вывести на экран все данные, воспользуемся циклом while:
while (($ a00, $ a01) = $ cur-> fetchrow_array)
{
$i++;
print "Запись \ # $ i: a00 = $ a00, a01 = $ a01. \ n";
}
Очень часто бывает необходимо подготовить запрос и после, при его выполнении, передавать ему различные данные. Это довольно просто решается при помощи механизма placeholders:
$ cur = $ dbh-> prepare ('вставить в значения MAIN (?,?)')
где вопросительные знаки следует заменить на значения переменных, переданных в качестве параметров метода execute:
$ a00 = 2;
$ a01 = 'вторая запись';
$ cur-> execute ($ a00, $ a01);
Для того чтобы закрыть курсор, необходимо выполнить метод finish.
$ Сила тока> отделка;
Курсоры очень удобный момент в технологии DBI. Однако можно обойтись и без них. Существует множество методов, которые вполне неплохо заменяют курсоры:
  • selectrow_array — возвращает одну строку запроса в виде массива;
  • selectall_arrayref — возвращает весь ответ сервера в виде массива, ссылка на массивы;
  • do — выполняет запрос, ничего не возвращая (очень удобно при работе с insert, update и пр.)
Например:
($ a01) = $ dbh-> selectrow_ar-ray ('выберите a01 из MAIN, где a00 = 1;');
# получаем значение $a01 равное 'Hello world!'
$ dbh-> do ('update set a01 =' hello world ', где a00 = 1;');
# изменяем значения поля a01 на 'hello world', там где a00=1
И, наконец, для того чтобы разорвать соединение с MySQL, необходимо выполнить метод disconnect.
$ Dbh-> разъединение;
Этого, пожалуй, хватит, чтобы писать довольно сложные программы для работы с базами данных.
И виртуальный магазин, и сервер знакомств, и всевозможные сайты, предоставляющие платные услуги, — все нуждаются в возможности обрабатывать и хранить большие объемы информации. MySQL предоставляет всем эту возможность совершенно бесплатно. Это действительно одна из самых мощных, быстрых и надежных СУБД.
С вопросами и предложениями пишите мне. Постараюсь по мере сил и возможностей ответить.