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

AnrDaemon

Продвинутый новичок

weregod

unserializer
Ссылки в том числе без протокола принято писать ("//assets/style.css"), браузер подхватит текущий протокол.
 

firep91613

Новичок
Что-то не получается у меня направить все запросы на public/index.php...
Код:
Dockerfile:
FROM php
RUN apt-get update \
    && apt-get install -y libpq-dev \
    && docker-php-ext-install pdo pdo_pgsql
WORKDIR /php-app
COPY . /php-app
CMD ["php", "-S", "0.0.0.0:4000", "-t", "public/index.php"]
PHP:
index.php:
define('ROOT', dirname(__DIR__));
define('PUB', ROOT . '/public');
define('CORE', ROOT . '/core');
define('APP', ROOT . '/app');
define('CONTROLLERS', APP . '/controllers');
define('VIEWS', APP . '/views');
define('PATH', 'http://localhost:4000');

include CORE . '/functions.php';

$uri = trim($_SERVER['REQUEST_URI'], '/');

if ($uri === '') {
    include CONTROLLERS . '/index.php';
} else if ($uri === 'about.php') {
    include CONTROLLERS . '/about.php';
} else {
    echo 'fasdfasdfasd';
}
Если сделать запрос http://localhost:4000/about.php - The requested resource /about.php was not found on this server.
Если http://localhost:4000/about - срабатывает else - fasdfasdfasd.

Что не так?
 

firep91613

Новичок
С этими всеми проблемами разобрался. Еще интересует, как статейки хранятся в БД? Используются ли теги? Просто когда я делал на файлах, то добавлял теги <p>. Так было удобно выводить :)
 

miketomlin

Новичок
Используются ли теги?
Пока ты исключительно сам добавляешь контент, вообще не парься по поводу перекодирования тегов форматирования. Храни все в готовом к выводу виде. Я про большие блоки текста (основной контент поста). Со всем прочим возможны варианты.

В первом вложении к этой статье есть дамп с контентом постов. Но там в таблице не только посты. Посты можно отличить по полю category!=0 или module='post'.
 

miketomlin

Новичок
P.S. Если ты хранишь в БД какой-то текст (без фортматирования) в исходном виде, то в шаблонах надо писать не <?= $page['title'] ?>, а <?= e($page['title']) ?>, где e() – твоя ф-ция HTML-кодирования.
 

AnrDaemon

Продвинутый новичок
Я же указал точку входа - директория public.
Каталог - это не точка входа, это корень структуры для поиска статики.
А точка входа, в случае единого роутера, это, НАПРИМЕР(!), index.php. Но на самом деле он может называться как угодно и лежать где угодно за пределами корня сайта.
 

AnrDaemon

Продвинутый новичок
Еще интересует, как статейки хранятся в БД? Используются ли теги?
В подавляющем большинстве случаев - да. В БД лежит готовый свёрстанный HTML код. Но возможны варианты (BBcode, Markdown, …).
В последнем случае нужна какая-то функция трансформации (например, `e()`) из БД в HTML.
 

firep91613

Новичок
Каталог - это не точка входа, это корень структуры для поиска статики.
А точка входа, в случае единого роутера, это, НАПРИМЕР(!), index.php. Но на самом деле он может называться как угодно и лежать где угодно за пределами корня сайта.
Да, спасибо. Я уже разобрался.
CMD ["php", "-S", "0.0.0.0:4000", "-t", "public", "public/index.php"]
Сам роутер:
PHP:
<?php
$requested_file = __DIR__ . parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);

if (file_exists($requested_file) && is_file($requested_file)) {
    return false;
}

include __DIR__ . '/../config/config.php';
include CORE . '/functions.php';
include CORE . '/router.php';
 

miketomlin

Новичок
parse_url не для роутинга предназначена 😉

Пример выделения пути из наших движков:
Код:
list($p) = explode('?', $p, 2);
В древних Web-серверах и прокси- в REQUEST_URI может быть полный URL, но это ведь не ваш случай 😉
if (file_exists($requested_file) && is_file($requested_file))
Считается небезопасным при роутинге. Используйте какой-то белый список 😉
 

miketomlin

Новичок
Вообще использовать имя файла контроллера (или что это за файл?), содержащее полный путь из URL, – не айс! Ведь в пути могут передаваться и др. параметры. Как вариант можно использовать первый компонент пути. Также совершенно разные пути могут ссылаться на один и тот же контроллер, поэтому в роуте нужно иметь возможность хранить имя контроллера. Поле module из таблицы, которую я упоминал в теме, предназначено именно для этого.
 

firep91613

Новичок
@miketomlin, я просто не знаю, как во встроенном сервере сделать, чтобы подгружались стили, скрипты и картинки. В апаче или энджинксе есть правила, а во встроенном вроде нет. Поэтому сделал так:
PHP:
$requested_file = __DIR__ . parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);

if (file_exists($requested_file) && is_file($requested_file)) {
return false;
}
Также совершенно разные пути могут ссылаться на один и тот же контроллер, поэтому в роуте нужно иметь возможность хранить имя контроллера.
У меня для это есть массив:
PHP:
$routes = [
    '' => 'index.php',
    'about' => 'about.php',
    'article' => 'article.php',
    'article/create' => 'article-create.php'
];
 

miketomlin

Новичок
Поэтому сделал так
А понятно. Это заглушка для встроенного сервера. Но в роутере вы же наверное тоже используете выделенный путь из URL. И мое замечание насчет parse_url в любом случае остается в силе.

И в чем проблема использовать норм. Web-сервер. Встроенный – это так, поиграться.
 

firep91613

Новичок
Но в роутере вы же наверное тоже используете выделенный путь из URL. И мое замечание насчет parse_url в любом случае остается в силе.
Ну да, пока что у меня такой роутер.
PHP:
<?php
include CONFIG . '/routes.php';

$uri = trim(parse_url($_SERVER['REQUEST_URI'])['path'], '/');

if (array_key_exists($uri, $routes)) {
    include CONTROLLERS . "/{$routes[$uri]}";
} else {
    abort();
}
И в чем проблема использовать норм. Web-сервер. Встроенный – это так, поиграться.
Это мне надо в докер PHP с Apache ставить? FROM php:8.2-apache?
Расширение .php в значениях выглядит лишним. Как вариант: https://phpforum.su/index.php?showtopic=94970#entry3152033
Ок, спасибо.
 

firep91613

Новичок
Подскажите, я что-то поплыл уже... Создал папку blog. В корне docker-compose.yml и две папки - nginx и php.
Содержимое docker-compose.yml:
Код:
version: "3"
services:
  nginx:
    build:
      context: .
      dockerfile: nginx/Dockerfile
    ports: 
      - "8080:80"
    networks:
      - internal
  php:
    build:
      context: .
      dockerfile: php/Dockerfile
    networks:
      - internal
  db:
    image: postgres:latest
    restart: always
    environment:
      POSTGRES_PASSWORD: mysecretpassword
    volumes:
      - postgres_data:/var/lib/postgresql/data
    networks:
      - internal

networks:
  internal:
    driver: bridge

volumes:
  blog_postgres_data:
    external: true
Содержимое nginx/Dockerfile:
Код:
FROM nginx:alpine
COPY nginx/default.conf /etc/nginx/conf.d
COPY ./ /var/www/html/
Содержимое php/Dockerfile:
Код:
FROM php:alpine
RUN apk update && apk add --no-cache libpq \
    && docker-php-ext-install pdo pdo_pgsql
WORKDIR /var/www/html
COPY ./ /var/www/html/
Содержимое nginx/default.conf:
Код:
server {
    listen 0.0.0.0:80;
    root /var/www/html/public;
    index index.php index.html;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        include fastcgi_params;
        fastcgi_pass php:9000;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
}
 
Сверху