Перейти к содержимому

17. Prepared Statements

Prepared Statements - важная тема в PHP разработке. В этом разделе мы детально разберем все аспекты работы с prepared statements.

  • Решение реальных задач в веб-разработке
  • Повышение безопасности приложений
  • Улучшение производительности кода
  • Соответствие best practices

В современной PHP разработке prepared statements используется повсеместно:

  • Веб-приложения
  • API сервисы
  • Content Management Systems (WordPress, Drupal)
  • E-commerce платформы
  • Корпоративные системы

В этом уроке мы изучим prepared statements. Это важная тема для понимания PHP и разработки динамических веб-приложений.

  • Основы работы с prepared statements
  • Практические примеры использования
  • Применение в WordPress
  • Best practices и рекомендации

Подробная информация о prepared statements и практические примеры использования в PHP.

<?php
// Примеры кода для Prepared Statements
echo "Prepared Statements в PHP";
?>
```text
## Примеры кода
### Пример 1: Базовое использование
```php
<?php
// Простой пример
echo "Пример кода";
?>
```text
### Пример 2: Практическое применение
```php
<?php
// Более сложный пример
function example() {
return "Результат";
}
?>
```text
### Пример 3: Реальная задача
```php
<?php
// Решение реальной проблемы
// TODO: Добавить конкретный пример
?>
```text
## WordPress контекст
Prepared Statements активно используется в WordPress для различных задач.
```php
<?php
// Пример использования в WordPress
// TODO: Добавить конкретный WordPress пример для prepared-statements
?>
```text
## Расширенные примеры
### Пример 1: Базовое использование
```php
<?php
// Простой пример для начинающих
echo "Пример кода";
// Пошаговое объяснение:
// 1. Создаем переменную
// 2. Обрабатываем данные
// 3. Выводим результат
?>
```text
### Пример 2: Промежуточный уровень
```php
<?php
// Более сложный пример с реальной логикой
function processData($data) {
// Валидация
if (empty($data)) {
return false;
}
// Обработка
$result = [];
foreach ($data as $item) {
$result[] = transformItem($item);
}
return $result;
}
function transformItem($item) {
// Трансформация элемента
return strtoupper($item);
}
// Использование
$input = ['apple', 'banana', 'orange'];
$output = processData($input);
print_r($output);
?>
```text
### Пример 3: Продвинутый уровень
```php
<?php
// Реальный production-ready код
class DataProcessor {
private $data;
private $filters = [];
public function __construct(array $data) {
$this->data = $data;
}
public function addFilter(callable $filter) {
$this->filters[] = $filter;
return $this;
}
public function process() {
$result = $this->data;
foreach ($this->filters as $filter) {
$result = array_filter($result, $filter);
}
return $result;
}
}
// Использование
$processor = new DataProcessor([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
$processor
->addFilter(function($n) { return $n % 2 == 0; }) // Только четные
->addFilter(function($n) { return $n > 5; }); // Больше 5
$result = $processor->process();
print_r($result); // [6, 8, 10]
?>
```text
## Best Practices и рекомендации
### Что нужно делать ✅
1. **Использовать строгую типизацию**
```php
<?php
declare(strict_types=1);
function calculate(int $a, int $b): int {
return $a + $b;
}
?>
  1. Валидировать входные данные

    <?php
    $email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
    if ($email === false) {
    die("Некорректный email");
    }
    ?>
  2. Обрабатывать ошибки

    <?php
    try {
    // Опасная операция
    $result = riskyOperation();
    } catch (Exception $e) {
    // Логирование ошибки
    error_log($e->getMessage());
    // Показываем пользователю
    echo "Произошла ошибка";
    }
    ?>
  3. Использовать prepared statements для БД

    <?php
    $stmt = $pdo->prepare("SELECT * FROM users WHERE email = ?");
    $stmt->execute([$email]);
    ?>
  4. Экранировать вывод

    <?php
    echo htmlspecialchars($user_input, ENT_QUOTES, 'UTF-8');
    ?>
  1. Не использовать устаревшие функции

    <?php
    // ❌ Плохо
    mysql_connect(); // Deprecated
    // ✅ Хорошо
    $pdo = new PDO($dsn, $user, $pass);
    ?>
  2. Не игнорировать ошибки

    <?php
    // ❌ Плохо
    @file_get_contents($url); // @ скрывает ошибки!
    // ✅ Хорошо
    $content = file_get_contents($url);
    if ($content === false) {
    // Обработка ошибки
    }
    ?>
  3. Не хранить пароли в plain text

    <?php
    // ❌ Плохо
    $password = $_POST['password'];
    // ✅ Хорошо
    $hash = password_hash($_POST['password'], PASSWORD_DEFAULT);
    ?>

Prepared Statements широко используется в WordPress разработке.

functions.php
<?php
// Регистрация кастомных возможностей
function theme_setup() {
add_theme_support('post-thumbnails');
add_theme_support('title-tag');
add_theme_support('custom-logo');
register_nav_menus([
'primary' => 'Primary Menu',
'footer' => 'Footer Menu'
]);
}
add_action('after_setup_theme', 'theme_setup');
// Загрузка стилей и скриптов
function enqueue_assets() {
wp_enqueue_style('main', get_stylesheet_uri(), [], '1.0.0');
wp_enqueue_script('main-js', get_template_directory_uri() . '/js/main.js', ['jquery'], '1.0.0', true);
}
add_action('wp_enqueue_scripts', 'enqueue_assets');
?>
```text
#### В плагинах
```php
<?php
/**
* Plugin Name: My Custom Plugin
* Description: Example plugin demonstrating Prepared Statements
* Version: 1.0.0
*/
// Активация плагина
function my_plugin_activate() {
// Создание таблиц, настройка опций
global $wpdb;
$table_name = $wpdb->prefix . 'my_table';
$charset_collate = $wpdb->get_charset_collate();
$sql = "CREATE TABLE $table_name (
id mediumint(9) NOT NULL AUTO_INCREMENT,
name varchar(255) NOT NULL,
email varchar(255) NOT NULL,
PRIMARY KEY (id)
) $charset_collate;";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql);
}
register_activation_hook(__FILE__, 'my_plugin_activate');
// Деактивация плагина
function my_plugin_deactivate() {
// Очистка, удаление cron jobs
wp_clear_scheduled_hook('my_plugin_cron');
}
register_deactivation_hook(__FILE__, 'my_plugin_deactivate');
?>
```text
#### Кастомные типы постов и таксономии
```php
<?php
function register_custom_post_types() {
// Кастомный тип поста
register_post_type('portfolio', [
'labels' => [
'name' => 'Portfolio',
'singular_name' => 'Portfolio Item'
],
'public' => true,
'has_archive' => true,
'supports' => ['title', 'editor', 'thumbnail'],
'menu_icon' => 'dashicons-portfolio'
]);
// Таксономия
register_taxonomy('portfolio_category', 'portfolio', [
'labels' => [
'name' => 'Categories',
'singular_name' => 'Category'
],
'hierarchical' => true,
'show_admin_column' => true
]);
}
add_action('init', 'register_custom_post_types');
?>
```text
## Решение типичных проблем
### Проблема 1: Не работает код
**Симптомы:**
- Пустая белая страница
- Ошибка 500
**Решение:**
```php
<?php
// Включите отображение ошибок для отладки
ini_set('display_errors', 1);
error_reporting(E_ALL);
// Проверьте логи ошибок
// Linux: /var/log/apache2/error.log
// XAMPP: C:\xampp\apache\logs\error.log
?>
```text
### Проблема 2: Данные не сохраняются
**Симптомы:**
- Форма не работает
- Данные теряются
**Решение:**
```php
<?php
// Проверьте метод отправки
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Проверьте наличие данных
var_dump($_POST);
// Проверьте валидацию
if (empty($_POST['name'])) {
die("Name is required");
}
}
?>
```text
### Проблема 3: Проблемы с кодировкой
**Симптомы:**
- Кракозябры вместо русских букв
**Решение:**
```php
<?php
// Установите кодировку
header('Content-Type: text/html; charset=utf-8');
// В БД используйте utf8mb4
$pdo = new PDO($dsn, $user, $pass, [
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8mb4"
]);
?>
```text
## Продвинутые темы
### Оптимизация производительности
```php
<?php
// Кеширование результатов
function get_expensive_data() {
static $cache = null;
if ($cache === null) {
// Дорогая операция выполняется только раз
$cache = heavy_computation();
}
return $cache;
}
// Использование опкода кеша (OPcache)
// Уже включено в современных версиях PHP
// Проверка: php -i | grep opcache
?>
```text
### Паттерны проектирования
```php
<?php
// Singleton pattern
class Database {
private static $instance = null;
private $connection;
private function __construct() {
$this->connection = new PDO($dsn, $user, $pass);
}
public static function getInstance() {
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}
public function getConnection() {
return $this->connection;
}
}
// Использование
$db = Database::getInstance()->getConnection();
?>
```text
### Тестирование
```php
<?php
// PHPUnit test example
use PHPUnit\Framework\TestCase;
class CalculatorTest extends TestCase {
public function testAdd() {
$calc = new Calculator();
$result = $calc->add(2, 3);
$this->assertEquals(5, $result);
}
public function testDivideByZero() {
$this->expectException(DivisionByZeroError::class);
$calc = new Calculator();
$calc->divide(10, 0);
}
}
?>
```text
## Практика
### Задание 1: Базовое
Создайте простой пример использования prepared statements.
### Задание 2: Промежуточное
Реализуйте более сложную задачу с применением prepared statements.
### Задание 3: Продвинутое
Создайте реальное приложение используя изученный материал.
### Задание 4: WordPress
Примените знания prepared statements в контексте WordPress.
### Задание 5: Проект
Разработайте небольшой проект, демонстрирующий практическое применение темы.
## Онлайн-редакторы
Тестируйте примеры из этого урока:
- **PHPSandbox** (https://phpsandbox.io/) — полноценная PHP-среда в браузере
- **3v4l** (https://3v4l.org/) — тестирование кода на разных версиях PHP
## Итоги
В этом уроке вы изучили:
✅ Основные концепции
✅ Практические примеры
✅ Применение в WordPress
✅ Best practices
✅ Типичные ошибки и их решения
### Следующий шаг
Переходите к следующему уроку для углубления знаний PHP.
### Ключевые моменты
1. Понимание основ — залог успеха
2. Практика важнее теории
3. Используйте примеры из реальной разработки
4. Изучайте код других разработчиков
5. Не бойтесь экспериментировать
**Совет:** Практикуйтесь с примерами из урока — это лучший способ запомнить материал!
---
**Готовы двигаться дальше?** Продолжайте изучение PHP!