Уважаемые пользователи Голос!
Сайт доступен в режиме «чтение» до сентября 2020 года. Операции с токенами Golos, Cyber можно проводить, используя альтернативные клиенты или через эксплорер Cyberway. Подробности здесь: https://golos.io/@goloscore/operacii-s-tokenami-golos-cyber-1594822432061
С уважением, команда “Голос”
GOLOS
RU
EN
UA
rusldv
8 лет назад

PHP - Урок 13. Введение в базы данных и SQL. СУБД MySQL. Подключаемся к БД из нашего приложения.

SQL и СУБД MySQL



Изображение

Предыдущие уроки:



Программируем на PHP - Введение

PHP - Запросы от браузера к серверу

PHP - Как работает сервер

PHP - Урок 4. PHP - интерпретатор

PHP - Урок 5. Переменные сервера и глобальные переменные

PHP - Урок 6. Конструкции print и echo. Кавычки одинарные и двойные и конкатенация строк

PHP - Урок 7. Переменные, константы и условия

PHP - Урок 8. Точка входа в приложение. Настройка mod_rewrite и файл .htaccess

PHP - Урок 9. Массивы и switch. Кодим основной каркас

PHP - Урок 10. COOKIE

PHP - Урок 11. Функции. Добавляем ядро системы core.php

PHP - Урок 12. Обзор модели MVC. Добавляем шаблоны страниц в наше приложение


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

В большинстве случаев запросы передаваемые приложению от браузеров пользователей будут необходимы для работы с базой данных. Необходимо внимательно относиться к тому, что мы получаем, и производить множество проверок, чтобы пользователь не смог в таких запросах внедрить вредоносный код к нам на сервер и ни чего не испортить. Вот код функций, которые я написал для этих целей. Я их поместил в начале файла sys/core.php
// Обработка текста
    function clearInt($num){
        return abs((int)$num);
    }

    function clearStr($str){
        return trim(strip_tags($str));
    }

    function clearHTML($html){
        return trim(htmlspecialchars($html));
    }

Первая функция нужна для приема чисел. Если число не число - то она вернет 0.
Вторая проверяет текст - если в нем HTML-код передадут, то она его оттуда удалит.
Третья не удаляет HTML но экранизирует его. Таким образом передаются теги, но они не вызывают форматирование переданного текста, а отображаются как были написаны.

Мы будем использовать эти функции, при приеме данных из HTML-форм нашим приложением.
А пока разберемся с базами данных, без которых нам никак не обойтись :)

Введение в базы данных


Начну как обычно с теории. Когда говорят "База данных" обычно подразумневают систему управления базами данных (СУБД).
На самом деле База Данных - это то где данные структуризировано хранятся. Базой данных может быть обычный файл или каталог с файлами.
От других файов, в которых хранятся иные структуры, отличается множеством особенностей.
Основные из них это то, что такие файлы хранят в своем начале (заголовке) структуру (описание полей) своих записей (в обычных файлах структура определяется на уровне программного кода).
А также во всех порядочных базах данных есть специальные файы - индексные (на самом деле не всегда они являются отдельными файлами. Например движек InnoDB по умолчанию все сохраняет в одном файле).
Индексы - это просто отсортированные идентификаторы записей в основной базе данных. Просто это ускоряет во много раз поиск нужной записи. Так как алгоритмы поиска умеют работать только с отсартированными значениями.

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

Программы такие делятся на две части (точнее говоря в состав системы управления входят две программы) - сервер и клиент базы данных.
Например mysqld - это сервер баз данных.
А mysql - это клиент. Он позволяет обращаться к серверу для выполнения определенных манипуляций с базой данных по средством SQL-запросов.
На самом деле клиентом не обязательно должна быть программа mysql. Можно использовать любую программу которая умеет подключаться к серверу БД (понимает протокол).

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

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

Как мы помним, стандартный веб-сервер по умолчанию работает на 80-м порту. Так вот. Сервер mysqld как правило имеет порт либо 3306 либо 3307. Таким образом если мы знаем, что по этому порту ждет процесс, мы можем передавать туда запросы.
Однако mysqld всегда проверяет с какого хоста к нему приходит запрос.
Запрос может быть локальный (localhost) или с любого другого компьютера в интернете. Либо только с конкретных хостов (например относящихся к определенной сети) или одного хоста.

Чтобы определить с какого хоста можно будет получить доступ к серверу баз данных, нужно указать определенное значение при создании пользователя, от имени которого будут производиться запросы.
Указав например знак процента - мы разрешим доступ со всех компьютеров в интернете. Указав конкретный IP - только с данного айпи-адреса.
А если введем значение localhost то только с того же компьютера где работает наш mysqld. Это самый безопасный вариант. Поэтому будем пользоваться им.
Внешний доступ можно включать только на время технических работ для удобства.

Так как наш PHP-интерпретатор со своим mysql-модулем находятся на том же компьютере что и сервер баз данных mesqld - то из наших скриптов мы вполне сможем подключаться, указывая в функциях для работы с БД значение localhost.

После того как мы подключаемся к серверу БД, мы выбираем какую-нибудь базу данных. В нее будут отправляться запросы, если мы явно не вводим имя нужной базы данных при запросе.
Затем мы отправляем запросы, которые в основном выполняют одно из следующих. Настройка параметров соединения, создание и удаление и изменение объектов баз данных.
Основных объекта там 3 - Собственно сами базы данных, таблицы и записи. Они так по порядку в друг друга и вкладываются.
(Ну естественно есть всякие вспомогательные объекты - временные таблицы, виды, индексы, триггеры, события, процедуры и т.д)
Например в MyISAM:

  1. База данных - это каталог в файловой системе.

  2. Таблица - это файл в таком каталоге (с расширением .tbl) и в начале он содержит структуру записей, которые в нем должны быть.

  3. Запись - это строка определенной структуры которая помещается в файл таблицы.

Теперь рассмотрим что такое SQL и попутно я кратко расскажу принципы работы СУБД.

Введение в SQL

Это такой язык, разработанный специально для работы с базами данных. Их через клиент отправляют серверу БД, а он в ответ что-то делает со своими базами данных.
По большей части SQL-запросы делятся на 3 категории.

  1. Управление структурой самой БД (создание и изменение таблиц).

  2. Манипуляция с данными (вставка, обновление и удаление записей в таблицах).

  3. Ну и конечно выборка данных (когда мы вытаскиваем нужные нам записи из таблиц).

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

phpMyAdmin


Это тоже приложение, написанное на РНР. Оно есть в нашем денвере.
Чтобы увидеть его нужно запустить денвер, набрать localhost и найти соответствующий пункт. либо набрать прямую ссылку http://localhost/Tools/phpMyAdmin/
И так, мы открыли phpMyAdmin и теперь приступим к подключению к базе данных.
Поскольку у меня своя методика обучения мы будем делать все задом наперед :).

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

Чтобы подключаться к базе данных я предпочитаю использовать класс PDO.
Мы конечно сейчас кодим в процедурном стиле программирования, а курс по ООП я планирую отдельный. Но использовать функции для подключения к БД я считаю не удобным. Поэтому воспольщуемся фишками php5.

Однако мы упакуем создание нашего объекта в функцию. Итак в файл sys/core.php добавим следующее определение функции:

// Соединение с БД
    function init(){
        $config = parse_ini_file(ROOT.'/sys/config.ini');
    $dsn = "{$config['driver']}:host={$config['host']};dbname={$config['schema']}";
    return new PDO($dsn, $config['user'], $config['password']);
    }

Здесь следует внести ясность.

Во первых первым делом в функции мы пишем такую строку

$config = parse_ini_file(ROOT.'/sys/config.ini');

На свете есть такие файлы, с расширением .ini - в них удобно удобно хранить различные настройки и конфигурации. Самый известный пример - файл php.ini.
Так вот у нас будет свой такой файл в который мы будем записывать конфигурации нашего php-приложения.
В таких файлах записи хранятся разделяясь знаком равенства: name=value каждая такая пара должна находиться на новой строке на новой строке.
Давайте создадим файл config.ini в папке sys нашего сайта (который мы собственно и парсим в функции).
А вот его содержимое у меня будет такое:

[database]
driver = mysql
host = localhost
schema = thesite
user = thesite
password = thesite

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

// Соединение с БД
function init(){
    $config = parse_ini_file(ROOT.'/sys/config.ini');
    print_r($config);
    //$dsn = "{$config['driver']}:host={$config['host']};dbname={$config['schema']}";
    //return new PDO($dsn, $config['user'], $config['password']);
}

Чтобы код данной функции исполнился мы должны ее вызвать. Сделаем это в файле index.php где нибудь перед switch-ом поместив такой вызов init();
Сохраняем и обновляем (переходим на) наш сайт thesite.loc
У меня вывод в месте вызова функции таков

Array ( [driver] => mysql [host] => localhost [schema] => thesite [user] => thesite [password] => thesite )

То есть наши настройки указанные в ини-файле благополучно запарсены в массив $config.
Мы можем раскомментировать закоментированные ранее строки. Там мы пользуясь нашим массивом создаем объект PDO, который обеспечивает соединение с сервером баз данных.
И этот объект мы возвращаем в качестве результата функции return new PDO(...); дабы использовать его в процедурном стиле.
А вот print_r($config); можно удалить или закомментировать, чтобы не мешал.

Если мы обновим страницу, исправив код, как описано выше, то мы увидим такую ошибку

Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[28000] [1045] Access denied for user 'thesite'@'localhost' (using password: YES)' in Z:\home\thesite.loc\www\sys\core.php:24 Stack trace: #0 Z:\home\thesite.loc\www\sys\core.php(24): PDO->__construct('mysql:host=loca...', 'thesite', 'thesite') #1 Z:\home\thesite.loc\www\index.php(12): init() #2 {main} thrown in Z:\home\thesite.loc\www\sys\core.php on line 24

Которая гласит что аккаунта thesite@localhost в системе не обнаружен. Следует его создать.
Для этого переходим в phpMyAdmin и там на вкладку "Пользователи".
Снизу списка кликаем "Добавить пользователя" и просто вводим то, что мы сохранили в config.ini
Имя пользователя: thesite
Хост: Локальный
Пароль: thesite
Подтверждение: thesite

В Пункте "База данных для пользователя" выбираем пункт "Создать базу данных с именем пользователя в названии и предоставить на нее полные привилегии" (чтобы не создавать ее отдельно вручную)
Привилегии для данного пользователя достаточно поставить SHOW, INSERT и UPDATE в целях безопасности это самый раз.
Нажимаем "Добавить пользователя". Готово. Пользователи и база данных появились в списках.

Теперь если мы обновим страницу наша ошибка пропадет.

И чтобы убедиться, что все работает - выведем список баз данных

$pdo = init();
$stmt = $pdo->query("SHOW DATABASES");
$dbs = $stmt->fetchAll(PDO::FETCH_ASSOC);
print_r($dbs);

Ну об этих функциях более подробно поговорим в следующих уроках.

Итак. Сегодняшние файлы:

index.php

<h1>Это мое PHP-приложение</h1>
<?php 
    define(ROOT, $_SERVER['DOCUMENT_ROOT']);
    require(ROOT.'/sys/core.php');

    $page = route(1);
    $ext = route(2);
    
    //echo 'Запрашиваемая страница: '.$page;
    //echo '<br />Дополнительные данные: '.$ext;

    $pdo = init();
    $stmt = $pdo->query("SHOW DATABASES");
    $dbs = $stmt->fetchAll(PDO::FETCH_ASSOC);
    print_r($dbs);
    
    switch($page){
        case 'login':
            echo '<h2>Страница авторизации</h2>';
            break;
        case 'logout':
            echo '<h2>Тут мы разлогиваемся</h2>';
            break;
        case 'register':
            echo '<h2>Страница регистрации</h2>';
            break;
        case 'user':
            echo '<h2>Профиль пользователя</h2>';
            break;
        case 'post':
            echo '<h2>Конкретный пост</h2>';
            break;
        case 'news':
            echo '<h2>Страница новостей</h2>';
            break;
        default:
            $title = "Страница по умолчанию";
            $tpl = "default";
    }

    include_once(ROOT.'/sys/templates/index.tpl.php');

sys/core.php

<?php
/* 
* This core functions for application
*/

// Обработка текста
function clearInt($num){
    return abs((int)$num);
}

function clearStr($str){
    return trim(strip_tags($str));
}

function clearHTML($html){
    return trim(htmlspecialchars($html));
}

// Соединение с БД
function init(){
    $config = parse_ini_file(ROOT.'/sys/config.ini');
    //print_r($config);
    $dsn = "{$config['driver']}:host={$config['host']};dbname={$config['schema']}";
    return new PDO($dsn, $config['user'], $config['password']);
}

/* Route functions */
function route($item = 1) {
    $request = explode("/", $_SERVER["REQUEST_URI"]);
    return $request[$item];
}

sys/config.ini

[database]
driver = mysql
host = localhost
schema = thesite
user = thesite
password = thesite

В следующем уроке мы сделаем регистрацию и авторизацию для пользователей.
142
1119.860 GOLOS
На Golos с November 2016
Комментарии (4)
Сортировать по:
Сначала старые