Создание блога

firep91613

Новичок
Хоста с именем php нет. А какой есть?
php и есть.

Я сейчас убрал из докер-файла nginx строку WORKDIR /var/www/website/public. Запустилось, но 502 Bad Gateway выдает.
Dockerfile nginx:
Код:
FROM nginx:alpine
COPY nginx/default.conf /etc/nginx/conf.d/default.conf
COPY --chown=nginx public/ ./
Вот лог:
Код:
blog-nginx-1  | 2024/08/01 17:26:08 [error] 29#29: *1 connect() failed (113: Host is unreachable) while connecting to upstream, client: 192.168.48.1, server: , request: "GET / HTTP/1.1", upstream: "fastcgi://192.168.48.3:9000", host: "localhost:8080"
Вот по поводу этого лога еще не нагуглил ничего.
 

firep91613

Новичок
У меня получилось запустить.
Код:
version: '3.9'

services:
  nginx:
    container_name: blog-nginx
    image: nginx:latest
    ports:
      - '8080:80'
    volumes:
      - ./:/var/www/website
      - ./default.conf:/etc/nginx/conf.d/default.conf
    depends_on:
      - php-fpm
      - postgres
    networks:
      - internal

  php-fpm:
    container_name: blog-php-fpm
    image: php:8.3-fpm
    build:
      context: .
      dockerfile: Dockerfile 
    volumes:
      - ./:/var/www/website
    networks:
      - internal

  postgres:
    container_name: blog-postgres
    image: postgres:latest
    restart: always
    environment:
      POSTGRES_PASSWORD: mysecretpassword
    volumes:
      - blog_postgres_data:/var/lib/postgresql/data
    networks:
      - internal

networks:
  internal:
    driver: bridge

volumes:
  blog_postgres_data:
    external: true
Код:
server {
    index index.php index.html;
    server_name phpfpm.local;
    error_log  /var/log/nginx/error.log;
    access_log /var/log/nginx/access.log;
    root /var/www/website/public;
    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass php-fpm:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
}

Но сборка этого добра проиходит очень долго. Вчера вечером ждал 3 часа. Сегодня урезал до мининума, но все равно долго.
Код:
RUN apt-get update \
    && apt-get install -y \
        libpq-dev \
    && docker-php-ext-install pdo pdo_pgsql
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
38.png
 

firep91613

Новичок
Скажите еще, есть ли смысл делать класс подключения к БД синглтоном? Просто я видел несколько мнений в гугле, что желательно. У меня сейчас создается экземпляр класса в точке входа, а дальше уже используется контроллерами.

Вот public/index.php:
PHP:
include __DIR__ . '/../vendor/autoload.php';
include __DIR__ . '/../config/config.php';
$db_config = include CONFIG . '/db_config.php';
$connection = new classes\DataBase($db_config);
include CORE . '/functions.php';
include CORE . '/router.php';
Класс подключения к БД пока что такой:
PHP:
namespace classes;
class DataBase {
    public $pdo;
    public function __construct(array $db_config) {
        try {
            $dsn = "pgsql:host={$db_config['host']};dbname={$db_config['dbname']}";
            $this->pdo = new \PDO($dsn, $db_config['user'], $db_config['password'], $db_config['options']);
        } catch (\PDOException $e) {
            error_log($e->getMessage());
        }
    }
    
    public function query(string $sql, ?array $args = null) : \PDOStatement {
        if (!$args) {
             return $this->pdo->query($sql);
        }
        $stmt = $this->pdo->prepare($sql);
        $stmt->execute($args);
        return $stmt;
    }
    public function __destruct() {
        $this->pdo = null;
    }
}
 

AmdY

Пью пиво
Команда форума
Если ты используешь DI, то в синглтоне нет смысла, так как создание и контроль инстансов происходит через DI.
Использование DI предпочтительнее, так легче следить за зависимостями, контролировать и рефакторить код, писать тесты.
 

miketomlin

Новичок
У меня сейчас создается экземпляр класса в точке входа, а дальше уже используется контроллерами.
Нормальный вариант. А как ты передаешь значение $connection в контроллер? Обычным параметром?

Ну, еще неплохо бы иметь спец. метод закрытия соединения. Хотя для PDOшки это и не принципиально, но для абстрактной обертки можно на всякий случай добавить.

P.S. И query'ями обычно зовут методы, не использующие подготовленные выражения. Для подготовленных – wquery и т.п. Для SELECT'а и т.п. может быть к примеру rquery.
 

AnrDaemon

Продвинутый новичок
Ну, еще неплохо бы иметь спец. метод закрытия соединения. Хотя для PDOшки это и не принципиально, но для абстрактной обертки можно на всякий случай добавить.
Просто в деструкторе закрывать соединение, если это принципиально.
 

AnrDaemon

Продвинутый новичок
Сделаю тогда пока что синглтон. С DI я еще не знаком.
Не надо так делать. Просто передавай объект подключения тем конструкторам, которым он нужен.
Либо положи в контейнер, и он сам достанет.
 

weregod

unserializer
Тема "Создание блога", какой нафиг закрывать соединение, скрипт отработал -- всё само по себе закроется )
А вот в контейнер грамотно положить надо, не открывать соединение до первого обращения к БД, то да.
 

firep91613

Новичок
А как ты передаешь значение $connection в контроллер?
Ну это глобальная переменная. Там же роутер инклюдит контроллеры.
При условии что твои контроллеры или фронт без БД жить не могут. Иначе может получиться, что ты часто инициализируешь этот объект/выполняешь подключение к БД впустую.
Ну да, как-то не вразуметильно еще. Контроллер about.php не использует подключение к БД.
Не надо так делать. Просто передавай объект подключения тем конструкторам, которым он нужен.
Либо положи в контейнер, и он сам достанет.
А вот в контейнер грамотно положить надо, не открывать соединение до первого обращения к БД, то да.
Ок. Я почитаю об этом.
 

miketomlin

Новичок
Ну, ОК. Называй, как хочешь. Но иметь в классе метод с подготовленными выражениями и не иметь без – это такое себе. Так понятнее?

firep91613, конечно, можно самому (не полагаясь на PDO, который тоже может это сделать) в одном методе в зависимости от наличия параметров, подставляемых в запрос, выполнять либо обычный запрос, либо подготовленный. Но так ты не сможешь сделать обычный с параметрами.
 
Последнее редактирование:

miketomlin

Новичок
Ну это глобальная переменная.
Ща тебя тапками закидают 😂 Хотя глобальные переменные как раз и предназначены для передачи подобных параметров. Но тогда остается только один норм. вариант – передавать из фронта, а то получится, что в контексте контроллера этот параметр может быть где-то доступен, а где-то нет (до инициализации).

Контроллер about.php не использует подключение к БД.
Вообще современный тренд – полностью отделять контент от кода. Т.е. если даже у этой страницы будет какая-то изысканная верстка с уник. шаблоном, выбираемые из конфига сайта данные, то все равно наверняка есть, что подтянуть из БД. Конечно, можно для простоты весь контент загнать в шаблон, но все же лучше загнать в БД контент, насыщенный более сложными тегами. В идеале конечно лучше подтягивать из БД мелкодробленный контент в соотв. шаблон. Мелкое дробление можно сделать при помощи JSON и т.п., либо спец. таблицы с одной записью и кучей полей или записями вида ключ-значение.
 
Последнее редактирование:

ksnk

прохожий
Ну это глобальная переменная.
Постараюсь объяснить, почему тапки полетят (если полетят. Тут уже контингент не такой буйный, как бывалоча) Есть технология разработки - TDD, когда каждый новый класс ты пишешь и проектируешь вместе с тестами на него. В реальности - это значит , что ты затрачиваешь дополнительное время, пока пишешь код, но зато основательно экономишь на вылавливании багов. Это сейчас, фактически, основная технология разработки ПО и если ты не понимаешь что это такое и не умеешь в ТДД, то тебя скорее всего не возьмут в команду. Но это лирика, раньше люди жили както жеж и трава была зеленее, не смотря ни на что... Однако та самая технология рекомендует, чтобы класс содержал в себе все зависимости. Ну вот вплоть до драйвера баз данных. Ничего личного. никакой обязаловки, но так его проще окружать тестами. Возникает проблема Dependency Injection, и разные ее решения. Отсюда растут ноги страшненьких и уродливых, по моему скромному мнению, ларавельных конструкторов. Но это тоже лирика, разговор то был про глобальные переменные. Так вот глобальные переменные серьезно мешают проводить тестирование в TDD. Не, есть конечно, разные техники, ходы и способы тестирования, в конце концов старую кодовую базу никто переписывать не собирается, но теперь ты, возможно, не только знаешь, что глобальные переменные - это плохо, но и кто в этом виноват :)
 

firep91613

Новичок
firep91613, конечно, можно самому (не полагаясь на PDO, который тоже может это сделать) в одном методе в зависимости от наличия параметров, подставляемых в запрос, выполнять либо обычный запрос, либо подготовленный. Но так ты не сможешь сделать обычный с параметрами.
Не могли бы вы показать свой класс?

Постараюсь объяснить, почему тапки полетят (если полетят. Тут уже контингент не такой буйный, как бывалоча) Есть технология разработки - TDD, когда каждый новый класс ты пишешь и проектируешь вместе с тестами на него. В реальности - это значит , что ты затрачиваешь дополнительное время, пока пишешь код, но зато основательно экономишь на вылавливании багов. Это сейчас, фактически, основная технология разработки ПО и если ты не понимаешь что это такое и не умеешь в ТДД, то тебя скорее всего не возьмут в команду. Но это лирика, раньше люди жили както жеж и трава была зеленее, не смотря ни на что... Однако та самая технология рекомендует, чтобы класс содержал в себе все зависимости. Ну вот вплоть до драйвера баз данных. Ничего личного. никакой обязаловки, но так его проще окружать тестами. Возникает проблема Dependency Injection, и разные ее решения. Отсюда растут ноги страшненьких и уродливых, по моему скромному мнению, ларавельных конструкторов. Но это тоже лирика, разговор то был про глобальные переменные. Так вот глобальные переменные серьезно мешают проводить тестирование в TDD. Не, есть конечно, разные техники, ходы и способы тестирования, в конце концов старую кодовую базу никто переписывать не собирается, но теперь ты, возможно, не только знаешь, что глобальные переменные - это плохо, но и кто в этом виноват :)
Ок. Я понял. Я ознакомился с DI и Service Container. Сегодня вот напишу контейнер и глобальных переменных не будет. Роутер я тоже сделал классом.
 

WMix

герр M:)ller
Партнер клуба
Я так накидаю,
Конечно в продакшине, надо папку со скриптами загонять в контейнер ( то что у тебя COPY в докерфайле) доя разработки это не удобно, после изменения перезапускать сервер, просто монтируй папку через docker-compose.
 
Сверху