Как добавить новость на сайт c помощью PHP. Часть 2

Как добавить новость на сайт c помощью PHP. Часть 2

Как добавить новость на сайт c помощью PHP. Часть 2

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

Проект будет реализован в процедурном стиле для простоты, но при необходимости его можно
перевести в объектно-ориентированный вариант.

Итак, начнем рассматривать файлы проекта, но для начала вспомним структуру проекта:

.
├── css
│   ├── bootstrap.min.css
│   └── style.css
├── images
│   └── php-add-news-on-site.jpg
├── models
│   └── news_model.php
├── templates
│   ├── form.phtml
│   └── index.phtml
├── config.php
├── core.php
├── index.php
├── news.php
└── news_table.sql

config.php

Содержит конфигурацию для доступа к базе данных. Поэтому перед тем как запускать
проект надо создать базу и таблицу (news_table.sql).


<?php

return [
    'host' => '127.0.0.1',
    'db' => 'posts_dbs',
    'user' => 'user',
    'pass' => 'password',
    'charset' => 'utf8'
];

core.php

Файл с основными функциями, необходимыми для работы проекта


<?php

/**
 * Создает PDO подключение к базе данных
 * 
 * @param array $connectionConfig
 * @return PDO
 * 
 */
function getDBConnection(array $connectionConfig): PDO
{
    $host = $connectionConfig['host'];
    $db = $connectionConfig['db'];
    $charset = $connectionConfig['charset'];
    $pass = $connectionConfig['pass'];
    $user = $connectionConfig['user'];

    $dsn = "mysql:host=$host;dbname=$db;charset=$charset";
    $opts = [
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        PDO::ATTR_EMULATE_PREPARES => false,
    ];

    // подключение к базе
    return new PDO($dsn, $user, $pass, $opts);
}

/**
 * Берет файл шаблона из папки templates и возвращает его 
 * с подставленными значениями переменных из массива $vars.
 * 
 * @param string $template
 * @param array $vars
 * @return false|string
 */
function render(string $template, array $vars = [])
{
    $vars = sanitize_html($vars);
    ob_start();
    extract($vars);
    include sprintf("%s/templates/%s.phtml", __DIR__, $template);
    return ob_get_clean();
}

/**
 * Преобразует все элементы массива заменяя html-теги на их html-сущности
 * 
 * @param array $values
 * @return array
 */
function sanitize_html(array $values): array
{
    $resultArray = [];
    foreach ($values as $key => $value) {
        if(is_array($value)) {
            $resultArray[$key] = sanitize_html($value);
        }
        else {
            $resultArray[$key] = htmlentities($value, ENT_QUOTES);
        }
    }
    return $resultArray;
}

/**
 * Просто преобразует строку с датой в требуемый формат
 * 
 * @param string $datetime
 * @param string $format
 * @return string
 */
function format_datetime(string $datetime, string $format = 'd M Y H:m:s'): string
{
    try {
        $datetimeObj = new DateTime($datetime);
    } catch (Exception $e) {
        return $e->getMessage();
    }
    return $datetimeObj->format($format);
}

файл models/news_model.php

Модель для работы с данными новостей — добавления, вывода


<?php

require_once __DIR__ . '/../core.php';

/**
 * Добавляет статью в базу
 * 
 * @param PDO $connection
 * @param string $title
 * @param string $content
 * @return bool
 */
function news_add(PDO $connection, string $title, string $content): bool
{
    $sql = 'INSERT INTO news (title, content) VALUES (:title, :content)';
    $statement = $connection->prepare($sql);
    $data = [':title' => $title, ':content' => $content];

    return $statement->execute($data);
}

/**
 * Получает статью из базы по ее идентификатору
 * 
 * @param PDO $connection
 * @param int $id
 * @return array
 */
function news_getById(PDO $connection, int $id): array
{
    $sql = 'SELECT * FROM news WHERE id = :id';
    $statement = $connection->prepare($sql);

    return  $statement->execute([':id' => $id]) ? $statement->fetch() : [];
}

/**
 * Возвращает список из всех новостей
 * 
 * @param PDO $connection
 * @return void[]
 * @throws Exception
 */
function news_getAll(PDO $connection): array
{
    $sql = 'SELECT * FROM news ORDER BY created_at DESC';
    $statement = $connection->query($sql);
    $news = $statement->fetchAll();

    return array_map(function (array $item) {
        $item['created_at'] = format_datetime($item['created_at']);
        return $item;
    }, $news);
}

const NEWS_MODEL_OK = 1001;
const NEWS_MODEL_FAILED = 1002;

/**
 * Вызывает при запросе пользователя. Добавляет статью в базу
 * 
 * @param array $connectionConfig
 * @param string $title
 * @param string $content
 * @return int
 */
function news_add_action(array $connectionConfig, string $title, string $content): int
{
    $connection = getDBConnection($connectionConfig);
    $executeResult = news_add($connection, $title, $content);

    return $executeResult ? NEWS_MODEL_OK : NEWS_MODEL_FAILED;
}

файл post.phtml — шаблон для вывода одной новости


<?php
/**
 * @var string[] $post
 */
?>
<!doctype html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Новость</title>

    <link rel="stylesheet" href="../css/style.css">
</head>
<body>
<div class="container py-4">

    <nav aria-label="breadcrumb">
        <ol class="breadcrumb">
            <li class="breadcrumb-item"><a href="/">Все новости</a></li>
            <li class="breadcrumb-item active" aria-current="page">Новость</li>
        </ol>
    </nav>

    <h2><?php print $post['title']; ?></h2>

    <div><?php print $post['content']; ?></div>
</div>
</body>
</html>

Таким образом мы рассмотрели основную программную часть нашего проекта.
А в следующей заключительной статье мы соберем все вместе — в единую систему добавления статьи на сайт.

Источник

НЕТ КОММЕНТАРИЕВ

Оставить комментарий

тринадцать − три =