Новости

Как добавить новость на сайт 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>

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

Источник

Статьи по теме

Добавить комментарий

Ваш адрес email не будет опубликован.

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.

Back to top button