Этот урок набрал набрал достаточно большое количество комментариев и дальнейшее его комментирование отключено. Если вы хотели убедиться в правильности выполнения ДЗ или у вас возник вопрос по уроку, посмотрите ранее добавленные комментарии, кликнув по кнопке ниже. Скорее всего вы найдете там то, что искали. Если это не помогло - задайте вопрос в чате в телеграме - https://t.me/php_zone
tomsonst 04.09.2018 в 21:01

Долго провозился с использованием переменной в запросе

public function view(int $articleId)
{
    $result = $this->db->query(
        'SELECT * FROM `articles` WHERE id = :id;',
        [':id' => $articleId]
    );
    $author =  $this->db->query('SELECT nickname FROM users WHERE id = "'.$result[0][1].'"');

    if ($result === []) {
        $this->view->renderHtml('errors/404.php');
        return;
    }

    $this->view->renderHtml('articles/view.php', ['article' => $result[0], 'author' =>$author[0][0]]);
}
ivashkevich 05.09.2018 в 23:44

Автора стоит получать только после того, как проверили что массив не пустой.

stokato 07.11.2018 в 14:20

В экшне ArticlesController::view() после получения статьи, добавьте ещё один запрос на получение автора этой статьи из таблицы users. Выведите nickname автора в шаблоне.

С помощью Join соединил две таблички и без лишних обращений к базе забрал себе пользователей, дополнительно в списке статей тоже вывел авторов. Курс по БД прошел не зря=)

//MainController.php
public function main()
    {
        $articles = $this->db->query('SELECT * FROM `articles` a JOIN `users` u ON a.author_id = u.id');
        $this->view->renderHtml('main/main.php', ['articles' => $articles]);
    }
//main.php
<?php include __DIR__ . '/../main/header.php'; ?>
<?php foreach ($articles as $article): ?>
    <h2><a href="/articles/<?= $article['id'] ?>"><?= $article['name'] ?></a></h2>
    <p><?= $article['text'] ?></p>
    <p>Автор: <i><?= $article['nickname'] ?></i></p>
    <hr>
<?php endforeach; ?>
<?php include __DIR__ . '/../main/footer.php'; ?>
//ArticlesController.php
public function view(int $articleId)
    {
        $result = $this->db->query('SELECT * FROM `articles` a JOIN `users` u ON a.author_id = u.id WHERE a.id = :id;',[':id' => $articleId]);

        if ($result === []) {
            $this->view->renderHtml('errors/404.php',[],404);
            return;
        }

        $this->view->renderHtml('articles/view.php', ['article' => $result[0]]);
    }
//view.php
<?php include __DIR__ . '/../main/header.php'; ?>
    <h1><?= $article['name'] ?></h1>
    <p><?= $article['text'] ?></p>
    <p>Автор: <i><?= $article['nickname'] ?></i></p>
<?php include __DIR__ . '/../main/footer.php'; ?>
ivashkevich 08.11.2018 в 10:39

Хорошо, так тоже можно)

[email protected] 03.12.2020 в 18:29

Хороший пример!

[email protected] 18.04.2021 в 15:46

Явно не зря, еще в селекте нужные столбцы прописать, чтобы алиас для никнейма сделать, типа такого:

SELECT a.name, a.text, u.nickname as author FROM `articles` a INNER JOIN `users` u ON a.author_id=u.id WHERE a.id = :id;

Чтобы в шаблоне статьи можно было выводить $article['author'], для лучшей понятности. И вообще идеальное решение задачи

computerix 08.11.2018 в 14:03
public function view(int $articleId)
    {
        $result = $this->db->query(
            'SELECT * FROM `articles` left join `users` on articles.author_id = users.id where articles.id = :id;' ,
            [':id' => $articleId]
        );
        if ($result === []) {
            $this->view->renderHtml('errors/404.php', [], 404);
            return;
        }

        $this->view->renderHtml('articles/view.php', ['article' => $result[0]]);
    }
}
ivashkevich 08.11.2018 в 23:33

А почему использовали LEFT JOIN?

computerix 09.11.2018 в 05:11

Да как-то так придумалось) Неверно?

ivashkevich 09.11.2018 в 09:05

Нужно понимать разницу между разными типами JOIN-ов - прочитайте о них. Конкретно здесь должен быть INNER JOIN.

computerix 09.11.2018 в 10:15
public function view(int $articleId)
    {
        $result = $this->db->query(
            'SELECT * FROM `articles` inner join `users` on articles.author_id = users.id where articles.id = :id;' ,
            [':id' => $articleId]
        );
        if ($result === []) {
            $this->view->renderHtml('errors/404.php', [], 404);
            return;
        }

        $this->view->renderHtml('articles/view.php', ['article' => $result[0]]);
    }
}
ivashkevich 12.11.2018 в 01:46

Хорошо!

Todd 09.11.2018 в 01:56

ArticlesController

    public function view(int $articleId)
    {
        $result = $this->db->query(
            'SELECT * FROM `articles` WHERE id = :id',
            [':id' => $articleId]
        );

        if ($result === []) {
            $this->view->renderHtml('errors/404.php', [], 404);
            return;
        }

        $result_user = $this->db->query(
            'SELECT `nickname` FROM `users` WHERE id = :id',
            [':id' => $result[0]['author_id']]
        );

        if ($result_user === []) {
            $result_user[0]['nickname'] = 'не известно';
        }

        $this->view->renderHtml('articles/view.php', ['article' => $result[0], 'nickname' => $result_user[0]['nickname']]);
    }

view

<?php include __DIR__ . '/../header.php'; ?>
    <h1><?= $article['name'] ?></h1>
    <p><?= $article['text'] ?></p>
    <p>Имя автора: <?= $nickname ?></p>
<?php include __DIR__ . '/../footer.php'; ?>
ivashkevich 09.11.2018 в 09:02

Отлично!

AxLT 09.11.2018 в 22:38
public function view(int $articleId)
{
    $result = $this->db->query(
        'SELECT * FROM `articles` WHERE id = :id;',
        [':id' => $articleId]
    );

    if ($result === []) {
        $this->view->renderHtml('errors/404.php');
        return;
    }

    $this->view->renderHtml('articles/view.php', ['article' => $result[0]]);
}

на участке:

 if ($result === []) {
        $this->view->renderHtml('errors/404.php');
        return;

renderHtml должен принимать на вход два аргумента, и при таком коде у меня ошибка, исправил на:

 $this->view->renderHtml('errors/404.php', []);

Вопрос почему у вас работает иначе)?

Todd 10.11.2018 в 02:35

А можно увидеть функцию renderHtml ? второй аргумент должен иметь дефолтное значение, ощущение что у Вас он не задан, но могу ошибаться)

ivashkevich 12.11.2018 в 01:48

Привет! Вот код:

public function renderHtml(string $templateName, array $vars = [], int $code = 200)
    {
        http_response_code($code);

        extract($this->extraVars);
        extract($vars);

        ob_start();
        include $this->templatesPath . '/' . $templateName;
        $buffer = ob_get_contents();
        ob_end_clean();

        echo $buffer;
    }

Второй аргумент по умолчанию равен пустому массиву.

AxLT 12.11.2018 в 23:17

Да действительно упустил
Спасибо

AxLT 12.11.2018 в 23:05

Сделал так

 public function view(int $articleId)
    {
        $result = $this->db->query(
            'SELECT * FROM `articles` WHERE id = :id;',
            [':id' => $articleId]
        );

        if ($result === []) {
            $this->view->renderHtml('errors/404.php', 404);
            return;
        }

        $author = $this->db->query(
            'SELECT nickname FROM users WHERE id = :id',
            [':id' => $result[0][1]]
        );            
        $this->view->renderHtml('articles/view.php', ['article' => $result[0], 'author' => $author[0][0]]);
    }

И есть один вопрос, View на вход принимает $articleId, так вот мне не совсем понятно каким образом эта переменная задается ив какой именно момент она получает свои значения "1" "2"

ivashkevich 12.11.2018 в 23:16

Норм сделал. То что и нужно было.

AxLT 13.11.2018 в 00:03

Там снизу еще вопрос есть)

ivashkevich 13.11.2018 в 21:55

Не понял вопроса. Напиши по нему лучше в личку в телеге.

andreskrip 27.01.2020 в 18:35

Я тоже задался этим же вопросом и возможно мы такие не одни)
Через дебаггер все встало на свои места:

Значения "1" или "2" или любое другое View получает благодаря нашей настройке роутинга.
В route.php мы прописываем роуты в формате "паттерн" => "класс контроллера, экшн", а затем уже в index.php мы foreach-ем перебираем паттерны для определения подходящего.

Т.к. паттерн для статей у нас был с маской (\d+), то в массив совпадений $matches после проверки, помимо полного совпадения по паттерну (нулевой элемент), еще попадет значение маски, т.е. всё то, что идет после 'articles/' в адресной строке (собственно в нашем случае "1" или "2" или любое другое).

Ну и в конце index.php мы удаляли ненужный 0 элемент из массива $matches, определяли название контроллера и название экшна, которые необходимо вызвать по данному роуту, и собственно подходим к главному:

$controller = new $controllerName();
$controller->$actionName(...$matches);

Определив нужный контроллер (в нашем случае ArticlesController), мы создаем его экземпляр и вызываем необходимый экшн (в нашем случае view) и аргументом передаем оставшийся элемент массива $matches, значение маски (1, 2 и т.д.)

А переменная $articleId задается внутри метода view (грубо говоря, какой аргумент в метод придет - тот и будет называться $articleId).

Надеюсь кому-то моя простыня поможет, если что исправьте)

ivashkevich 28.01.2020 в 18:53

Отличная простыня)

bildep 18.11.2018 в 19:30

ArticlesController.php

<?php
namespace MyProject\Controllers;

use MyProject\Services\Db;
use MyProject\View\View;

class ArticlesController
{
    /** @var View */
    private $view;

    /** @var Db */
    private $db;

    public function __construct()
    {
        $this->view = new View(__DIR__ . '/../../../templates');
        $this->db = new Db();
    }

    public function view(int $articleId)
    {
        $result = $this->db->query(
            'SELECT * FROM `articles` WHERE id = :id;',
            [':id' => $articleId]
        );

        if ($result === []) {
            $this->view->renderHtml('errors/404.php', [], 404);
            return;
        }

        $author = $this->db->query(
            'SELECT * FROM `users` WHERE id = :id;',
            [':id' => $result[0]["author_id"]]
        );

        $result[0]['author'] = $author[0]["nickname"];

        $this->view->renderHtml('articles/view.php', ['article' => $result[0]]);
    }
}

view.php

<?php include __DIR__ . '/../header.php'; ?>
    <h1><?= $article['name'] ?></h1>
    <p><?= $article['text'] ?></p>
    <p>Автор: <?= $article['author'] ?></p>
<?php include __DIR__ . '/../footer.php'; ?>
ivashkevich 19.11.2018 в 22:02

Лучше не засовывать автора внутрь статьи. Пусть пробрасывается отдельной переменной.

alepawka 02.01.2019 в 13:55
$articles = $this->db->query('SELECT A.id,A.name,A.text,B.nickname FROM `articles` A INNER JOIN `users` B ON A.`author_id` = B.`id`;');/*Изменил запрос в MainController*/
public function view(int $articleId)
        {
            $result = $this->db->query(
                'SELECT A.id,A.name,A.text,B.nickname FROM `articles` A INNER JOIN `users` B ON A.`author_id` = B.`id` WHERE A.id = :id;',
                [':id' => $articleId]
            );/*так же в ActiveController*/
<p>Автор: <?= $article['nickname'] ?></p><!-- добавил автора в main.php и view.php -->
ivashkevich 02.01.2019 в 21:37

Ок)

virtual2018 02.01.2019 в 15:37

В предыдущих уроках header и footer лежали тут:

<?php include __DIR__ . '/../header.php'; ?>
<?php include __DIR__ . '/../footer.php'; ?>

а в этом переехали в

<?php include __DIR__ . '/../main/header.php'; ?>
<?php include __DIR__ . '/../main/footer.php'; ?>
virtual2018 02.01.2019 в 17:11

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

    public function view(int $articleId)
    {
        $result = $this->db->query(
            'SELECT a.author_id,a.name,a.text,u.nickname FROM `articles` a, `users` u WHERE a.author_id = u.id and a.id = :id;',
            [':id' => $articleId]
        );

        if ($result === []) {
            $this->view->renderHtml('errors/404.php', [], 404);
            return;
        }

        $result_users = $this->db->query(
            'SELECT email FROM `users` WHERE id = :id;',
            [':id' => $result[0]['author_id']]
        );

        $this->view->renderHtml('articles/view.php', ['article' => $result[0], 'mail_to' => $result_users[0]['email']]);
    }
<?php include __DIR__ . '/../header.php'; ?>
    <h1><?= $article['name'] ?></h1>
    <p><?= $article['text'] ?></p>
    <p><?= $article['nickname'] ?></p>
    <p><?= $mail_to?></p>
<?php include __DIR__ . '/../footer.php'; ?>
ivashkevich 02.01.2019 в 21:38

Отлично!

dnldcode 06.01.2019 в 00:39

ArticlesController.php

    public function view(int $articleId)
    {
        $result = $this->db->query('SELECT * FROM articles, users WHERE articles.id = :id AND articles.author_id = users.id;', [':id' => $articleId]);

        if ($result === []) {
            $this->view->renderHtml('errors/404.php', [], 404);
            return;
        }

        $this->view->renderHtml('articles/view.php', ['article' => $result[0]]);
    }

view.php

<?php include __DIR__ . '/../header.php'; ?>
    <h2><?= $article['name'] ?></h2>
    Автор: <?= $article['nickname'] ?>
    <p><?= $article['text'] ?></p>
<?php include __DIR__ . '/../footer.php'; ?>

Так можно решить?

ivashkevich 06.01.2019 в 10:41

Это не очень правильно, потому что у $article не должно быть nickname и других полей пользователя.

Bogdan 20.01.2019 в 13:00

Мы столько учили классы и наследования, можем ли мы тут их применить, как это к примеру сделал я?

<?php

namespace MyProject\Controllers;

class ArticlesController extends MainController
{

    public function view(int $articleId)
    {
        $result = $this->db->query(
            'SELECT * FROM `articles` WHERE id = :id;',
            [':id' => $articleId]
        );

        if ($result === []) {
            $this->view->renderHtml('errors/404.php');
            return;
        }

        $author = $this->db->query(
            'SELECT * FROM `users` WHERE id = :author_id;',
            [':author_id' => $result[0]['author_id']]);

        $this->view->renderHtml('articles/view.php', ['article' => $result[0], 'author' => $author[0]]);
    }
}

этим мы вроде как слегка оптимизировали код, убрали

use MyProject\Services\Db;
use MyProject\View\View;

    /** @var View */
    private $view;

    /** @var Db */
    private $db;

    public function __construct()
    {
        $this->view = new View(__DIR__ . '/../../../templates');
        $this->db = new Db();
    }

если будет много контроллеров, сделать абстрактный класс, со всеми этими VIew и подклечениями к бд, и от него уже наследоваться. Хотя я может просто бегу впереди паровоза))

ivashkevich 20.01.2019 в 13:19

Да. Отлично! Если уверен, что все контроллеры будут содержать этот код - то твой вариант правильный.

Bugaga159 05.02.2019 в 22:57

ArticlesController

...
$resultAuthor = $this->db->query(
            'SELECT `nickname` FROM `users` WHERE id = :id;',
            [':id'=> $result[0]['author_id']]
        );
        if ($resultAuthor === []){
            $resultAuthor[0]['nickname'] = 'Автор не известен';
        }

        $this->view->renderHtml('articles/view.php', ['article' => $result[0], 'nickname' => $resultAuthor[0]['nickname']] );

view

<?php include __DIR__ . '/../header.php'; ?>
    <h1><?= $article['name'] ?></h1>
    <p><?= $article['text'] ?></p>
    <p>Автор статьи: <?= $nickname; ?>.</p>
<?php include __DIR__ . '/../footer.php'; ?>
ivashkevich 07.02.2019 в 13:04
$resultAuthor[0]['nickname'] = ...

Не надо так. Можно просто завести переменную $nickname в самом начале метода со значением 'Автор не найден'. Если после запроса он есть, то переопределять эту переменную. И в renderHtml передавать её.

excent63 16.02.2019 в 22:07

С помощью комментариев получилось добиться рабочего кода, но где то я что недопонял видимо и теперь немного не понимаю как происходит вывод статей, попробую проходить дальше, если так же не будет доходить, придётся назад возвращаться и перечитывать по новой)

//ArticlesController.php
public function view(int $articleId)
    {
        $result = $this->db->query(
            'SELECT * FROM `articles` WHERE id = :id',
            [':id' => $articleId]
        );

        if ($result === []) {
            $this->view->renderHtml('errors/404.php', [], 404);
            return;
        }

        $user = $this->db->query(
            'SELECT `nickname` FROM `users` WHERE id = :id',
            [':id' => $result[0]['author_id']]
        );

        if ($user === []) {
            $user[0]['nickname'] = 'не известно';
        }

        $this->view->renderHtml('articles/view.php', ['article'=> $result[0], 'nickname' => $user[0]['nickname']],200);
    }
//view.php
<?php include __DIR__ . '/../header.php'; ?>
    <h1><?= $article['name'] ?></h1>
    <p><?= $article['text'] ?></p>
    <p>Имя автора: <?= $nickname ?></p>
<?php include __DIR__ . '/../footer.php'; ?>
ivashkevich 17.02.2019 в 22:09

Прочитайте мой ответ выше. Аналогичные пожелания.

Evgeny 24.03.2019 в 19:18

<?php

namespace MyProject\Controllers;

use MyProject\Services\Db;
use MyProject\View\View;

class ArticlesController
{
    private $view;
    private $db;

    public function __construct()
    {
        $this->view = new View(__DIR__ . '/../../../templates/');
        $this->db = new Db;
    }

    public function view(int $articleId)
    {
        $result = $this->db->query('SELECT * FROM articles WHERE id=:id', [':id' => $articleId]);

        if ([] === $result){
            $this->view->renderHtml('/error/404.php', [], 404);
            return;
        }
        $author = $this->db->query('SELECT nickname FROM users WHERE id=:id', [':id' => $result[0]['author_id']]);

        $this->view->renderHtml('/articles/view.php', ['article' => $result[0], 'author' => $author[0]]);
    }
}

view.php

<?php include __DIR__ . '/../header.php'; ?>
    <h1><?= $article['name'] ?></h1>
    <p><?= $article['text'] ?></p>
<p><b>Автор: <?= $author['nickname'] ?></b></p>
<?php include __DIR__ . '/../footer.php'; ?>
ivashkevich 25.03.2019 в 11:34

Отлично

Boodoo 15.04.2019 в 15:38

ArticlesController.php

.....
public function view(int $articleId)
        {
            $res = $this->db->query(
                'SELECT * FROM articles WHERE id = :id',
                [':id' => $articleId]
            );

            if($res === []) {
                $this->view->renderHtml('errors/404.php', [], 404);
                return;
            }

            $author_id = $res[0]['author_id'];
            $author = $this->db->query(
                'SELECT * FROM users WHERE id = :id',
                ['id' => $author_id]
            );

            $this->view->renderHtml('articles/view.php', ['article' => $res[0], 'author' => $author[0]]);
        }

view.php

<?php include __DIR__ . '/../header.php'; ?>

    <h1><?= $article['name'] ?></h1>
    <p><?= $article['text'] ?></p>
    <p><?= $author['nickname'] ?></p>

<?php include __DIR__ . '/../footer.php'; ?>
ivashkevich 15.04.2019 в 16:48

Отлично!

[email protected] 17.04.2019 в 17:02
<?php

namespace Controllers;

use Services\Db;
use View\View;

class ArticlesController
{

    /** @var View */
    private $view;

    /** @var Db */
    private $db;

    public function __construct()
    {
        $this->view = new View(__DIR__ . '/../Templates');
        $this->db = new Db();
    }

    public function view($articleId)
    {
        $result = $this->db->query(
            'SELECT * FROM `articles` WHERE id = :id;',
            [':id' => $articleId]
        );

        if ($result === []) {
            $this->view->renderHtml('errors/404.php', [], 404);
            return;
        }
        $authorId = $result[0]['author_id'];
        $author = $this->db->query(
            'SELECT * FROM `users` WHERE id = :id;',
            [':id' => $authorId]
        );
        $this->view->renderHtml('articles/view.php', ['article' => $result[0], 'author' => $author[0]]);
    }

}

<?php include __DIR__ . '/../header.php'; ?>
<h1>Автор: <?= $author['nickname'] ?></h1>
<h1><?= $article['name'] ?></h1>
<p><?= $article['text'] ?></p>
<?php include __DIR__ . '/../footer.php'; ?>
<?php

?>
ivashkevich 17.04.2019 в 22:22

Отлично

Dram 15.05.2019 в 14:53
  public function view()
  {
    echo 'Здесь будет получение статьи и рендеринг шаблона';
  }

Все нормально по адресу http://localhost/articles/1 я вижу "Здесь будет получение статьи и рендеринг шаблона".
Стоит изменить эту функцию на

  public function view(int $articleId)
  {
    $result = $this->db->query(
      'SELECT * FROM `articles` WHERE id = :id;',
      [':id' => $articleId]
    );
    var_dump($result);
  }

И я снова получаю ту ошибку, о которой писал ранее:

( ! ) Fatal error: Uncaught ArgumentCountError: Too few arguments to function MyProject\Controllers\ArticlesController::view(), 0 passed in C:\OSPanel\domains\localhost\index.php on line 32 and exactly 1 expected in C:\OSPanel\domains\localhost\src\MyProject\Controllers\ArticlesController.php on line 22
( ! ) ArgumentCountError: Too few arguments to function MyProject\Controllers\ArticlesController::view(), 0 passed in C:\OSPanel\domains\localhost\index.php on line 32 and exactly 1 expected in C:\OSPanel\domains\localhost\src\MyProject\Controllers\ArticlesController.php on line 22

Вы говорили использовать дебаг, но в каком файле - теперь то их куча. Попробовал поставить красную точку в начале каждого файла и перезапускать страницу - ничего не дало.

P.S. и еще у меня проблема с обратными слешами. Приходиться извращаться например так чтобы все работало

  public function __construct()
  {
    $this->view = new View('C:\OSPanel\domains\localhost\src\templates');
    $this->db = new Db();
  }

и так

  public function renderHtml(string $templateName, array $vars = [])
  {
    extract($vars);

    ob_start();
    include $this->templatesPath . '\\' . $templateName;
    $buffer = ob_get_contents();
    ob_end_clean();

    echo $buffer;
  }
ivashkevich 16.05.2019 в 00:22

Проблема в парсинге регулярки ноута, скорее всего. Не приходит второй аргумент. Напишите в личные сообщения в ВК или телеграме. Что-то много у вас проблем для решения в комментариях.

Dram 16.05.2019 в 17:51

Решение №1, быдлокод :))) просто оно мне первое в голову пришло...

SELECT *
FROM `articles` as t1
INNER JOIN `users` as t2 
WHERE t1.id = :id and t1.author_id = t2.id;',

+ в view.php

    <p><?= $article['nickname'] ?></p>

Говнокод №2 :)) мне кажется опять не правильно... ну как неправильно - данные то выводит, но вероятно не по стандартам написано

   public function view(int $articleId)
  {
    $result = $this->db->query(
      'SELECT * FROM `articles` WHERE id = :id;',
      [':id' => $articleId]
    );

    $result2 = $this->db->query(
      'SELECT * FROM `users` WHERE id =' .$result[0]['author_id'].';',
      [$result2[0]['nickname'] = $nickname]
    );

    if ($result === []) {
      $this->view->renderHtml('errors\404.php', [], 404);
      return;
    }

    $this->view->renderHtml('articles\view.php', ['article' => $result[0], 'article2' =>$result2[0]['nickname']]);
  }

+ в view.php

<?= $article2 ?>

прошу критики...

ivashkevich 16.05.2019 в 20:41

Оба решения вполне годные. Я бы предпочел второй вариант.
Но только назовите не article2, а nickname. Имя переменной должно отражать суть значения, которое в ней лежит.

Dram 16.05.2019 в 20:54

Ух ты! Спасибо, не ожидал! Начинает получаться значит :))

ivashkevich 16.05.2019 в 20:58

Видимо)

ashfedor 14.06.2019 в 15:16

Проверять есть ли автор, если есть статья я думаю не стоит, если не прав поправьте
и подумал что стоит получить все данные автора. Вдруг мы захотим еще что либо выводить на странице поста.
Е еще я где то пропустил почему нужно писать $user[0] а не $user?
Это чтоб выбирать по первому ключу?

public function view(int $articleId)
    {
        $result = $this->db->query(
            'SELECT * FROM `articles` WHERE id = :id;',
            [':id' => $articleId]
        );
        if ($result=== []){
            $this->view->renderHtml('errors/404.php', [], 404);
            return ;
        }

        $user = $this->db->query(
        'SELECT * FROM `users` WHERE id = :id;',
        [':id' => $result[0]['author_id']]
    );

        $this->view->renderHtml('articles/view.php', [
            'article' => $result[0],
            'users' => $user[0]
        ]
        );
    }

 для вьюхи
<?php include __DIR__ . '/../header.php'; ?>
    <h1><?= $article['name'] ?></h1>
    <p><?= $article['text'] ?></p>
    <p><?= $users['nickname'] ?></p>
<?php include __DIR__ . '/../footer.php'; ?>
ivashkevich 15.06.2019 в 06:33

user[0] - потому что из query тебе вернётся массив записей.

p><?= $users['nickname'] ?></p>

Тут должен быть $user, потому что он там один.

А в остальном - всё супер.

ashfedor 15.06.2019 в 14:03

Спасибо, теперь понял!

Invo 12.07.2019 в 23:32

Controller:

public function view(int $articleId)
    {
        $result = $this->db->query("SELECT articles.name as 'name', articles.text as 'text', users.nickname as 'username'  FROM articles INNER JOIN users ON articles.author_id = users.id WHERE articles.id = :id",
                                    [':id' => $articleId]
                                  );
        var_dump($result);
        if($result === [])
        {
            $this->view->renderHtml('errors/404.php', [], 404);
            return;
        }
        $this->view->renderHtml('articles/view.php', ['article' => $result[0]]);
    }

VIEW:

<?php include __DIR__ . '/../header.php'; ?>
    <h1><?= $article['id'] ?></h1>
    <h2> Author : <?= $article['username'] ?>
    <p><?= $article['text'] ?></p>
<?php include __DIR__ . '/../footer.php'; ?>
ivashkevich 14.07.2019 в 06:45

Отлично

Moskva 18.07.2019 в 21:35

Долго мучался, но вроде разобрался)
ArticlesController.php

 public function view(int $articlesId){
        $result = $this->db->query(
            'SELECT * FROM `articles` WHERE id = :id;',
            [':id' => $articlesId]
        );

        if ($result === []){
            $this->view->renderHtml('errors/404.php' , [] , 404);
            return;
        }
        $author_id = $result[0]['author_id'];
        $author = $this->db->query(
            'SELECT nickname FROM `users` WHERE id = :id;',
            [':id' => $author_id]);

        $this->view->renderHtml('articles/view.php', ['article' => $result[0], 'nickname' => $author[0]['nickname']]);
    }

view.php

<?php include __DIR__ . '/../header.php'; ?>
<h1><?= $article['name'] ?></h1>
<p><?= $article['text'] ?></p>
<h4> Автор:  <?= $nickname ?></h4>
<?php include __DIR__ . '/../footer.php'; ?>
ivashkevich 19.07.2019 в 07:00

Отлично!

Metey 20.07.2019 в 20:01
public function view(int $articleId)
    {
        $result = $this->db->query(
            'SELECT * FROM `articles` WHERE id = :id;',
            [':id' => $articleId]
        );
        if ($result === []) {
            $this->view->renderHtml('errors/404.php', [], 404);
            return;
        }
        $result_nick = $this->db->query(
            'SELECT nickname FROM `users` WHERE id = :id;',
            [':id' => $articleId]
        );
        $this->view->renderHtml('articles/view.php', ['article' => $result[0], 'nickname' => $result_nick[0]['nickname']]);
    }

view.php

<?php include __DIR__ . '/../header.php'; ?>
    <h1><?= $article['name'] ?></h1>
    <p><?= $article['text'] ?></p>
    <p><?= $nickname ?></p>
<?php include __DIR__ . '/../footer.php'; ?>
ivashkevich 21.07.2019 в 05:31

Ошибка здесь:

$result_nick = $this->db->query(
            'SELECT nickname FROM `users` WHERE id = :id;',
            [':id' => $articleId]
        );

Сможете найти?

Metey 21.07.2019 в 23:16

не не нашел, а что здесь не так?

ivashkevich 22.07.2019 в 15:55

Ищете пользователя по id. Вместо id пользователя передаёте id статьи.

Iliusha99 21.07.2019 в 12:38
 public function view(int $articleId)
    {
        $result = $this->db->query(
            'SELECT * FROM `articles` WHERE id = :id;',
            [':id' => $articleId]
        );

        if ($result === []) {
            $this->view->renderHtml('errors/404.php', [], 404);
            return;
        }

//        $this->view->renderHtml('articles/view.php', ['article' => $result[0]]); чтобы не дубликовать запрос

        $query = $this->db->query('SELECT nickname FROM `users` 
                                        WHERE `id` IN ( SELECT author_id FROM `articles` WHERE id = :id );',
          [':id' => $articleId]
        );

        if ($query === []) {
            $this->view->renderHtml('errors/404.php', [], 404);
            return;
        }

        $this->view->renderHtml('articles/view.php', ['article' => $result[0] ,'author' => $query[0]]);

    }
=========================

<?php include __DIR__ . '/../header.php'; ?>
<h1><?= $article['name'] ?></h1>
<p><?= $article['text'] ?></p>
<p>Автор: <?= $author['nickname'] ?></p>
<?php include __DIR__ . '/../footer.php'; ?>

http://prntscr.com/ohyof0
http://prntscr.com/ohyojr
ivashkevich 21.07.2019 в 14:20
$query = $this->db->query('SELECT nickname FROM `users` 
                                        WHERE `id` IN ( SELECT author_id FROM `articles` WHERE id = :id );',
          [':id' => $articleId]
        );

Зачем второй раз делаете запрос статьи? У вас уже есть id пользователя в $result.

//        $this->view->renderHtml('articles/view.php',

Не присылайте бесполезные комментарии в ДЗ. В рабочем коде их быть не должно.

if ($query === []) {
            $this->view->renderHtml('errors/404.php', [], 404);
            return;
        }

То, что автор не найден, не означает, что на сайте нет статьи, и что нужно показывать 404 ошибку. Придумайте корректное поведение, которое позволит пользователям читать статьи на сайте, даже если автора найти не удалось.

Iliusha99 21.07.2019 в 14:33

Так я знаю что в articles есть id, и думал зачем ещё один запрос, но в ДЗ было написано чтобы сделать ещё один запрос для вывода автора. Проста из-за этого не так понял

ivashkevich 21.07.2019 в 14:43

Ну так запрос для получения пользователя всё равно нужен. Непонятно, зачем вы внутри него снова за статьей идёте.

artemship 11.08.2019 в 02:17

ArticlesController.php:

    public function view(int $articleId)
    {
        $result = $this->db->query(
            'SELECT * FROM `articles` WHERE id = :id;',
            [':id' => $articleId]
        );

        if ($result === []) {
            $this->view->renderHtml('errors/404.php', [], 404);
            return;
        }

        $author = $this->db->query(
            'SELECT * FROM `users` WHERE id = :id;',
            [':id' => $result[0]['author_id']]
        );

        $this->view->renderHtml(
            'articles/view.php',
            ['article' => $result[0], 'author' => $author[0]]
        );
    }

articles/view.php:

<?php include __DIR__ . '/../header.php'; ?>
    <h1><?= $article['name'] ?></h1>
    <p><?= $article['text'] ?></p>
    <i>Автор статьи: <?= $author['nickname'] ?? 'Неизвестен' ?></i>
<?php include __DIR__ . '/../footer.php'; ?>
ivashkevich 11.08.2019 в 06:41

Отлично! Образцовая домашка.

Reechniy 18.08.2019 в 17:43
ArticleController.php

<?php

namespace MyProject\Controllers;

use MyProject\Services\Db;
use MyProject\View\View;

class  ArticleController
{
    /** @var View */
    private $view;

    /** @var Db */
    private $db;

    public function __construct()
    {
        $this->view = new View(__DIR__ . '/../../../templates');
        $this->db = new Db();
    }

    public function view(int $articleId)
    {
        $result = $this->db->query(
            'SELECT * FROM `articles` WHERE id = :id',
            [':id'=> $articleId]
        );

        if ($result === []) {
           $this->view->renderHtml('errors/404.php', [], 404);
           return;
        }

        $author = $this->db->query('SELECT nickname FROM users WHERE id=:id', [':id'=> $result[0]['author_id']]);

        $this->view->renderHtml('articles/view.php', ['article' => $result[0], 'author'=>$author[0]]);
    }
 }

view.php

<?php include __DIR__ . '/../header.php'; ?>
    <h1><?= $article['name'] ?></h1>
    <p><?= $article['text'] ?></p>
    <p>Имя автора: <?= $author['nickname'] ?></p>
<?php include __DIR__ . '/../footer.php'; ?>
ivashkevich 18.08.2019 в 18:43

Отлично

khuurak 23.08.2019 в 19:09

ArticlesController.php

public function view(int $articleId)
    {
        $result = $this->db->query(
            'SELECT articles.id, name, text, articles.created_at, users.id, nickname 
                FROM `articles` 
                    INNER JOIN `users` ON articles.author_id = users.id 
                        WHERE articles.id = :id;',
            [':id' => $articleId]
        );

        if ($result === []) {
            $this->view->renderHtml('errors/404.php', [], 404);
            return;
        }

        $this->view->renderHtml('articles/view.php', ['article' => $result]);
    }

templates/articles/view.php

            <?php foreach ($article as $value): ?>
                <h2><?=$value['name']?></h2>
                <em>Автор: <?=$value['nickname']?>. Дата публикации: <?=$value['created_at']?></em>
                <p><?=$value['text']?></p>
                <hr>
            <?php endforeach; ?>
ivashkevich 25.08.2019 в 13:41

Отлично

Blook 27.08.2019 в 18:54
    public function view(int $articleId)
    {
        $result = $this->db->query('SELECT * FROM `articles` WHERE id = :id;', 
        [':id' => $articleId]);

        if ($result == []) {
            $this->view->renderHtml('errors/404.php', [], 404);
            return;
        }

        $author = $this->db->query('SELECT `nickname` FROM `users` WHERE id = :authorId',
        [':authorId' => $result[0]['author_id']]);

        $this->view->renderHtml('articles/view.php', ['article' => $result[0], 'author' => $author[0][0]]);
    }
ivashkevich 28.08.2019 в 05:58

Отлично!

Pro100Bah 28.09.2019 в 13:10
public function view(int $articleId)
    {
        $result = $this->db->query(
            'SELECT * FROM `articles` WHERE id = :id;', [':id' => $articleId]
        );

        if ($result === []) {
            $this->view->renderHtml('errors/404.php', [], 404);  // Здесь обрабатываем ошибку
            return;
        }

        $resultAuthor = $this->db->query(
            'SELECT `nickname` FROM `users` WHERE id = :id',
            [':id' => $result[0]['author_id']]
        );

        $this->view->renderHtml('articles/view.php', ['article' => $result[0], 'author' => $resultAuthor[0]]);    //homework17
    }
<?php include __DIR__ . '/../header.php'; ?>
    <h1><?= $article['name'] ?></h1>
    <p><?= $article['text'] ?></p>
    <p><i>Автор: <?= $author['nickname'] ?></i></p>      <!-- Homework 17 -->
<?php include __DIR__ . '/../footer.php'; ?>

Рабочий получилось сделать, но немного с логикой запутался. Поправьте , если мыслю не совсем верно.

  1. Создаем переменную $resultAuthor. Аргументы у нас на входе запрос($sql) и массив(params=[]).

  2. Дальше не понимаю , что происходит((( .

  3. Потом идет подключение шаблона за счет класса View c методом renderHtml. Как он(renderHtml) работает я понял.
  4. Потом выводим данные в шаблон.
ivashkevich 29.09.2019 в 12:08

Не понял вопроса. Говоришь, что с запросом всё понятно. Что с передачей в шаблон всё понятно. Непонятно только что происходит после запроса. Но после запроса идёт передача в шаблон и между ними ничего нет. И вообще код отличный. В чем проблема?)

[email protected] 07.10.2019 в 23:11

Не полностью осилил задание,сам запрос я написал нормально,только вот смотрю,как люди делают,и немного не понимаю вот эту часть [':id' => $result[0]['author_id']] мы этой частью как-бы передаём в массиве номер автора,по которому отправляем запрос, например автор 1- admin,автор 2-user?

[email protected] 07.10.2019 в 23:15

Всё,разобрался,что-то я тупанул,как запрос будет знать,какой id из массива мы запрашиваем,если мы этого не указываем) под вечер уже мозги кипят.

ivashkevich 07.10.2019 в 23:36

Бывает)

dliashchenko 26.10.2019 в 00:59

view.php

<?php include __DIR__ . '/../header.php'; ?>
    <h1><?= $article['name'] ?></h1>
    <p><?= $article['text'] ?></p>
    <p>Автор статьи: <?= $nickname ?></p>
<?php include __DIR__ . '/../footer.php'; ?>

ArticlesController.php

        $result_nickname = $this->db->query(
            'SELECT `nickname` FROM `users` WHERE id = :id;',
            [':id' => $result[0]['author_id']]
        );
        if ($result_nickname === []) {
            $result_nickname[0]['nickname'] = 'без автора';
            return;
        }
        $this->view->renderHtml('articles/view.php', ['article' => $result[0],
            'nickname' => $result_nickname[0]['nickname']]);
ivashkevich 26.10.2019 в 07:48

Отлично

[email protected] 26.10.2019 в 14:46
SELECT * FROM articles,users WHERE articles.author_id=users.id;

А если я сделал запрос такого вида,как мне подставить нужный параметр в users.id ?

ivashkevich 26.10.2019 в 18:49

Запрос некорректный в принципе.

XXX 06.01.2020 в 16:45

ArticlesController.php

$result = $this->db->query(
            'SELECT a.*, u.nickname FROM `articles` a INNER JOIN `users` u ON a.author_id = u.user_id WHERE a.article_id = :id;',
            [':id' => $articleId]
        );

View.php

<?php include __DIR__ . '/../header.php'; ?>
<h1><?= $article['name'] ?></h1>
<p><?= nl2br($article['text']) ?></p>
<p>Автор <?= ($article['nickname']) ?></p>
<?php include __DIR__ . '/../footer.php'; ?>
ivashkevich 11.01.2020 в 10:33

nl2br - статья по идее уже с тегами должна быть. В остальном ок.

XXX 11.01.2020 в 16:33

Должна, но выводится без тегов. Хотя раньше все ок было. МОжет опять же проблема из-за дебагера который отключен и текст выводится как есть, а не с разметкой.

ivashkevich 12.01.2020 в 15:33

Дебаггер тут не при чём. Разбирайтесь в какой момент пропадают теги.

EugeneGrigoryev 21.01.2020 в 21:31

src/MyProject/Controllers/ArticlesController.php

    public function view(int $articleId)
    {
        $result = $this->db->query(
            'SELECT * FROM `articles` WHERE `id` = :id;',
            [':id' => $articleId]
        );
        if ($result === []) {
            $this->view->renderHtml('errors/404.php', [], 404);
            return;
        }
        $author = $this->db->query(
            'SELECT * FROM `users` WHERE `id` = :id;',
            [':id' => $result[0]['author_id']]
        );
        $this->view->renderHtml('articles/view.php', ['article' => $result[0], 'author' => $author[0]]);
    }

templates/articles/view.php

<?php include __DIR__ . '/../header.php'; ?>
    <h1><?= $article['name'] ?></h1>
    <p>Автор: <?= $author['nickname'] ?></p>
    <p><?= $article['text'] ?></p>
<?php include __DIR__ . '/../footer.php'; ?>

Вопрос: Зачем мы пишем ':id' с ':', если без него 'id' тоже работает

ivashkevich 24.01.2020 в 08:04

Отлично. Мы пишем с двоеточием, потому что именно так говорится в документации. Почему работает без него - не знаю.

andreskrip 27.01.2020 в 21:22

Спасибо за урок! Пришлось плотно засесть, чтобы во всём разобраться, но мне понравилось)
ArticlesController.php:

$author = $this->db->query(
            'SELECT nickname FROM `users` WHERE id=:id;', [':id' => $result[0]['author_id']]
        );
        $this->view->renderHtml('articles/view.php', ['article' => $result[0], 'author' => $author[0]]);

templates/articles/view.php:

<?php include __DIR__ . '/../header.php'; ?>
<h1><?= $article['name'] ?></h1>
<h2>Автор: <?= $author['nickname'] ?></h2>
<p><?= $article['text'] ?></p>
<?php include __DIR__ . '/../footer.php'; ?>

А также вопрос: не вызовет ли путаницы в будущем тот факт, что у нас и файл класса View называется View.php и шаблон для статей тоже называется view.php?

ivashkevich 28.01.2020 в 18:54

Отлично. Нет, не вызовет)

Dimitry 03.04.2020 в 16:16
//ArticlesController
<?php

namespace MyProject\Controllers;

use MyProject\Services\Db;
use MyProject\View\View;

class ArticlesController
{
    /** @var View */
    private $view;

    /** @var Db */
    private $db;

    public function __construct()
    {
        $this->view = new View(__DIR__ . '/../../../templates');
        $this->db = new Db();
    }

    public function view(int $articleId)
    {
        $result = $this->db->query(
            'SELECT * FROM `articles` WHERE id = :id;',
            [':id' => $articleId]
        );
        if ($result === []) {
            $this->view->renderHtml('errors/404.php', [], 404);
            return;
        }
        $authorId= $result[0]['author_id'];

        $author = $this->db->query(
            'SELECT * FROM `users` WHERE id = :id;',
            [':id' => $authorId]
        );
        $author=$author[0]['nickname'];

        $this->view->renderHtml('articles/view.php', ['article' => $result[0], 'author'=>$author]);
    }

}

//view.php

<?php include __DIR__ . '/../header.php'; ?>
    <h1><?= $article['name'] ?></h1>
    <h3>Автор: <?=$author?></h3>
    <p><?= $article['text'] ?></p>
<?php include __DIR__ . '/../footer.php'; ?>

Домашка

ivashkevich 03.04.2020 в 18:39

Отлично

Dmitry.Dudin 11.04.2020 в 23:59

view.php

<p>Автор статьи: <?= $nickname ?></p>

articleController.php

 $authorArticle=$this->db->query(
       'SELECT `nickname` FROM `users` WHERE id=:id',
       [':id'=>$result[0]['author_id']]
   );
   if($authorArticle === [])
   {
       $result_user[0]['nickname']='Имя автора неизвестно';
   }
   $this->view->renderHtml('articles/view.php',['article'=>$result[0],'nickname'=>$authorArticle[0]['nickname']]);

Пришлось повозиться конечно, чтоб извилинами шевельнуть. Это читается так просто, а как до дела доходит, так время больше уходит гораздо)

ivashkevich 13.04.2020 в 12:53
$result_user[0]['nickname']='Имя автора неизвестно';

Так делать не стоит. Лучше заведи отдельную переменную $nickname и туда складывай либо это значение, либо результат из запроса.

Alexann 12.04.2020 в 17:31

Файл ArticlesController.php:

...
public function view(int $articleId)
    {
        $result = $this->db->query(
            'SELECT * FROM `articles` WHERE id = :id;',
            [':id' => $articleId]
        );
        if ($result === []) {
            $this->view->renderHtml('errors/404.php', [], 404);
            return;
        }
        $nick = $this->db->query(
            'SELECT `nickname` FROM `users` WHERE id = :id;',
            [':id' => $result[0]['author_id']]
        );

        $this->view->renderHtml('articles/view.php', ['article' => $result[0],
            'nick' => $nick[0]['nickname']]);
    }
    }

Файл view.php:

<?php include __DIR__ . '/../header.php'; ?>
<h1><?= $article['name'] ?></h1>
<p><?= $article['text'] ?></p>
<p><em>Автор: <?= $nick ?? '' ?></em></p>
<?php include __DIR__ . '/../footer.php'; ?>
ivashkevich 13.04.2020 в 14:43

Супер!

[email protected] 12.04.2020 в 23:15

ArticlesController.php

public function view(int $articleId)
  {
    $result = $this->db->query(
      'SELECT * FROM `articles` WHERE id = :id;',
      [':id' => $articleId]
    );

    $author = $this->db->query(
      'SELECT * FROM `users` WHERE id = :id;',
      [':id' => $result[0]['author_id']]
    );

    if($result === []) {
      $this->view->renderHtml('errors\404.php', [], 404);
      return;
    }
      $this->view->renderHtml('articles\view.php', ['article' => $result[0], 'author' => $author[0]['nickname']]);

  }

view.php

<?php include __DIR__ . '/../header.php';?>
  <h2><?= $article['name'] ?></h2>
  <p><?= $article['text'] ?></p>
  <hr>
  <p>Многоуважаемый автор: <a href='#' style="color: red;"> <?= $author ?></a></p>
<?php include __DIR__ . '/../footer.php';?>
ivashkevich 13.04.2020 в 14:49
errors\404.php

Слеши в другую сторону пишите, иначе потом будут проблемы на линуксе. В остальном всё отлично

Soib 15.04.2020 в 21:38
public function view(int $articleId)
    {
        $this->title = "Статья";
        $article = $this->getArticle($articleId);
        if ($article === [])
        {
            $this->view->renderHtml('errors/404.php',[],404);
            return;
        }
        $author = $this->getAuthor($article[0]['author_id']);

        $vars = [
            'title' => $this->title,
            'article' => $article[0],
            'author' => $author[0]
        ];

        $this->view->renderHtml('articles/article.php', $vars);
    }

    public function getArticle($articleId)
    {
        $article = $this->db->query("SELECT * FROM `articles` WHERE id = :id;", [':id' => $articleId]);
        return $article;
    }

    public function getAuthor($authorId)
    {
        $author = $this->db->query("SELECT `nickname` FROM `users` WHERE id = :id", [':id'=> $authorId]);
        return $author;
    }
ivashkevich 16.04.2020 в 06:51
$this->title = "Статья";

Зачем в $this это складывать?
Почему двойные кавычки?

$article = $this->db->query("SELECT * FROM `articles` WHERE id = :id;", [':id' => $articleId]);
        return $article;

и другое подобное пишется в одну строку:

        return $$this->db->query("SELECT * FROM `articles` WHERE id = :id;", [':id' => $articleId]);;

Нет смысла заводить для этого переменные.

Salexandr 16.04.2020 в 23:31

ArticlesController.php

 public function view(int $articleId)
    {
        $result = $this->db->query(
            'SELECT * FROM `articles` WHERE id = :id;',
            [':id' => $articleId]
        );

        if ($result === []) {
            $this->view->renderHtml('errors/404.php', [], 404);
            return;
        }

        $author = $this->db->query
        ('SELECT nickname FROM users WHERE id = :id;',
            [':id' => $result[0]['author_id']]
        );

        if ($author === []) {
            $author[0]['nickname'] = 'не указан';
        }

        $this->view->renderHtml('articles/view.php', ['article' => $result[0], 'nickname' => $author[0]['nickname']]);
    }

templates/articles/view.php

<?php include __DIR__ . '/../header.php'; ?>
    <h1><?= $article['name'] ?></h1>
    <p><?= $article['text'] ?></p>
    <p><i>Автор: <?= $nickname ?></i></p>
<?php include __DIR__ . '/../footer.php'; ?>
ivashkevich 17.04.2020 в 09:21
        $author = $this->db->query
        ('SELECT nickname FROM users WHERE id = :id;',
            [':id' => $result[0]['author_id']]
        );

        if ($author === []) {
            $author[0]['nickname'] = 'не указан';
        }

Лучше завести отдельную переменную nickname и писать имя автора в неё. Её же передавать в шаблон.

Salexandr 22.04.2020 в 21:36
 $author = $this->db->query
        ('SELECT nickname FROM users WHERE id = :id;',
            [':id' => $result[0]['author_id']]
        );

        $nickname = $author[0]['nickname'];

        if ($author === []) {
            $nickname = 'не указан';
        }

        $this->view->renderHtml('articles/view.php', ['article' => $result[0], 'nickname' => $nickname]);

Так, просто для читабельности?

ivashkevich 23.04.2020 в 10:35

Если автора не будет, то вот тут возникнет ошибка:

        $nickname = $author[0]['nickname'];
Salexandr 26.04.2020 в 18:50
$nickname = isset($author[0]['nickname']) ?? 'NULL';
ivashkevich 26.04.2020 в 19:42

Вы сможете объяснить, что тут написано? Прочитайте для начала об операторе ?? и конструкции isset.

Salexandr 27.04.2020 в 12:52
 $nickname = ($author[0]['nickname']) ?? '';

Если автора не будет (в $author[0]['nickname'] лежит NULL), то присвоим $nickname пустую строку ''. В противном случае присвоим содержимое $author[0]['nickname'].

Я думал, я помню эту конструкцию и смогу со смартфона, не влезая в phpstorm ответить, но увы...
Когда прочитал теорию и вроде разобрался, а потом, не закрепив на практике, попытался вспомнить:

if (isset($foo)) {
    $bar = $foo;
} else {
     // присваиваем $bar значение 'default' если $foo равен NULL
    $bar = 'default'; 
}
теперь можно: $bar = $foo ?? 'default'; 
ivashkevich 27.04.2020 в 20:02
($author[0]['nickname'])

А скобки зачем?

Salexandr 27.04.2020 в 20:18

так очевидней, что это не несколько разных элементов :) Пока изучаю, так легче воспринимается.

Fill 19.04.2020 в 17:36

/templates/articles/view.php

<?php include __DIR__ . '/../header.php'; ?>
<h1><?= $article['name'] ?></h1>
<p>Автор: <?= $article['nickname']?></p>
<p><?= $article['text'] ?></p>
<?php include __DIR__ . '/../footer.php'; ?>

src/MyProject/Controllers/ArticlesController.php

...

class ArticlesController
{
...
public function view(int $articlesId)
    {
        $result = $this->db->query(
            'SELECT * FROM `articles` INNER JOIN `users` ON articles.author_id = users.id WHERE articles.id = :id;',
            [':id' => $articlesId]
        );

        if ($result === []) {
            $this->view->renderHtml('errors/404.php', ['article' => $result[0]], 404);
            return;
        }

        $this->view->renderHtml('articles/view.php', ['article' => $result[0]]);

    }
}
ivashkevich 19.04.2020 в 18:45
$this->view->renderHtml('errors/404.php', ['article' => $result[0]], 404);

Зачем туда статью передавать?

Fill 19.04.2020 в 18:49

Конечно незачем, скопировал лишнего.

$this->view->renderHtml('errors/404.php', [], 404);
Timurik 28.04.2020 в 18:34

Возможно есть решение попроще, но я сделал так:
\src\MyProject\Controllers\ArticlesController.php

<?php

namespace MyProject\Controllers;

use MyProject\Services\Db;
use MyProject\View\View;

class ArticlesController
{
    /** @var View */
    private $view;

    /** @var Db */
    private $db;

    public function __construct()
    {
        $this->view = new View(__DIR__ . '/../../../templates');
        $this->db = new Db();
    }

    public function view(int $articleId)
    {
        $result = $this->db->query(
            'SELECT * FROM `articles` WHERE id = :id;',
            [':id' => $articleId]
        );

        if ($result === []) {
            //Здесь обрабатываем ошибку
            $this->view->renderHtml('errors/404.php', [], 404);
            return;
        }

        $resultAuthor = $this->db->query(
            'SELECT * FROM `users` WHERE users.id = :authorId;',
            [':authorId' => $result ['0'] ['author_id']]
        );

        $this->view->renderHtml('articles/view.php',['article' => $result[0], 'author' => $resultAuthor[0]]);
        //$this->view->renderHtml('articles/view.php',['author' => $resultAuthor[0]]);
        //var_dump($resultAuthor ['0'] ['nickname']);
        //var_dump($result);
        //echo 'Здесь будет получение статьи и рендеринг шаблона';
    }
}

\templates\articles\view.php

<?php include __DIR__ . '/../header.php'; ?>
    <h1><?= $article['name'] ?></h1>
    <p><?= $article['text'] ?></p>
    <p>Автор статьи:<?= $author['nickname'] ?></p>
<?php include __DIR__ . '/../footer.php'; ?>
ivashkevich 28.04.2020 в 19:32

Всё отлично, только вот здесь не нужны пробелы:

$result ['0'] ['author_id']
Timurik 28.04.2020 в 19:36

Спасибо, исправил

[':authorId' => $result['0']['author_id']]
ivashkevich 28.04.2020 в 19:56

Теперь норм!

studentDev 02.05.2020 в 15:45
//ArticleController.php
 public function view(int $articleId)
        {

            $result = $this->db->query(
                'SELECT * FROM `articles` WHERE id = :id;',
                [':id' => $articleId]);

            $resultUser = $this->db->query('SELECT * FROM `users` WHERE id = :id;',
                [':id' => $articleId]);

            if($result === []) {
                $this->view->renderHtml('/errors/404.php', [], 404);
                return;
            }
            $this->view->renderHtml('articles/view.php', ['article' => $result[0], 'user' => $resultUser[0]]);
        }
//view.php
<?php include __DIR__ . '/../header.php'; ?>
<h1><?= $article['name'] ?></h1>
<p><?= $article['text'] ?></p>
<p>Автор: <?= $user['nickname'] ?></p>
<?php include __DIR__ . '/../footer.php'; ?>

?

ivashkevich 02.05.2020 в 16:35
            $this->db->query('USE `my_project`;');

Как это оказалось в контроллере?

studentDev 03.05.2020 в 06:06

Мне пришлось прописывать данный запрос, так как у меня автоматически не подключалась БД.

Сегодня просмотрел код ещё раз...
В итоге решил проблему.

ivashkevich 03.05.2020 в 20:56

Как решил?

studentDev 04.05.2020 в 04:46

Эта ошибка была глупой, я написал имя ключа dbName за вместо dbname в классе Db. Итог просто ошибся регистром :D

ivashkevich 06.05.2020 в 13:07

Ок. А вообще такому коду самое место в классе Db, если вдруг решите его когда-то вновь написать.

studentDev 06.05.2020 в 13:32

Хорошо)

titelivus 08.05.2020 в 10:35

ArticlesController.php

...
    public function view(int $articleId)
    {
        $sql = 'SELECT * FROM `articles` AS a INNER JOIN `users` AS u ON a.author_id=u.id WHERE a.id = :id;';
        $result = $this->db->query($sql, [':id' => $articleId]);
...

View.php

<?php include __DIR__ . '/../header.php'; ?>
    <h1><?= $article['name'] ?></h1>
    <p><?= $article['text'] ?></p>
    <p>Автор: <?= $article['nickname'] ?></p>
<?php include __DIR__ . '/../footer.php'; ?>
ivashkevich 08.05.2020 в 20:22

Отлично

[email protected] 09.05.2020 в 22:36

Запрос автора статьи и передача никнейма в рендер

public function view(string $articleIdRoute)
    {
        preg_match('~\d+$~', $articleIdRoute, $matches);
        $articleId = $matches[0];
        $queryResult = $this->db->query('SELECT * from `articles` WHERE id=:id;', [':id' => $articleId]);
        $authorQueryResult = $this->db->query('SELECT * FROM `users` WHERE id=:id;', [':id' => $queryResult[0]['author_id']]);

        if($queryResult === [])
        {
            $this->view->renderHtml('errors/404.php', [], 400);
            return;
        }

        $this->view->renderHtml('articleView.php', ['article' => $queryResult[0], 'nickname' => $authorQueryResult[0]['nickname']]);
    }

Вывод никнейма в шаблоне

<?php include __DIR__ . '/header.php'; ?>
    <h1> <?= $article['name']; ?> </h1>
    <p> <?= $article['text']; ?> </p>
    <p> <?= $nickname ?> </p>
<?php include __DIR__ . '/footer.php'; ?>
ivashkevich 10.05.2020 в 09:11
        preg_match('~\d+$~', $articleIdRoute, $matches);
        $articleId = $matches[0];

Это что такое? Сделайте роутинг нормальный, как в предыдущих уроках.

[email protected] 11.05.2020 в 23:01

Вроде делал все как в уроке. Но получается так, что роут выглядит вот так

'~^articles/(\d+)$~' => [\MyProject\Controllers\ArticlesController::class, 'view'],

И эта регулярка формирует строку вида 'articles/2'(например), которая передается как параметр в функцию view. И приходится еще одной регуляркой выдергивать именно номер, т.к. в таком виде к корректному int она, по умолчанию, не преобразовывается. А вот здесь, для запроса к БД в функции view, нам нужен int.

 $result = $this->db->query(
            'SELECT * FROM `articles` WHERE id = :id;',
            [':id' => $articleId]
        );

Может я где-то что-то упустил, но что именно и где найти не могу.

ivashkevich 12.05.2020 в 08:19

Пересмотрите урок по роутингу. Там выдергиваются только группы из регулярки (то, что в скобочках)

[email protected] 12.05.2020 в 14:55

Разобрался. При изучении регулярок не до конца понял смысл скобок, в итоге сделал без них, оттуда ноги и растут. Спасибо.

ivashkevich 13.05.2020 в 07:18

Отлично, жду исправленное решение

[email protected] 13.05.2020 в 11:53
public function view(string $articleId)
    {
        $queryResult = $this->db->query('SELECT * from `articles` WHERE id=:id;', [':id' => $articleId]);
        $authorQueryResult = $this->db->query('SELECT * FROM `users` WHERE id=:id;', [':id' => $queryResult[0]['author_id']]);

        if($queryResult === [])
        {
            $this->view->renderHtml('errors/404.php', [], 400);
            return;
        }

        $this->view->renderHtml('articleView.php', ['article' => $queryResult[0], 'nickname' => $authorQueryResult[0]['nickname']]);
    }

Для шаблона ничего не изменилось

ivashkevich 14.05.2020 в 12:51
string $articleId

Упс)

$this->view->renderHtml('errors/404.php', [], 400);

почему 400?

ivashkevich 14.05.2020 в 12:53
        $authorQueryResult = $this->db->query('SELECT * FROM `users` WHERE id=:id;', [':id' => $queryResult[0]['author_id']]);

        if($queryResult === [])

Сначала взяли значение из массива queryResult и только потом проверили его на пустоту. Тут закралась ошибка

[email protected] 14.05.2020 в 13:06

Кажется все поправил.

public function view(int $articleId)
{
    $queryResult = $this->db->query('SELECT * from `articles` WHERE id=:id;', [':id' => $articleId]);

    if($queryResult === [])
    {
        $this->view->renderHtml('errors/404.php', [], 404);
        return;
    }

    $authorQueryResult = $this->db->query('SELECT * FROM `users` WHERE id=:id;', [':id' => $queryResult[0]['author_id']]);

    if($authorQueryResult === [])
    {
        $this->view->renderHtml('articleView.php', ['article' => $queryResult[0], 'nickname' => 'неизвестен');
        return;
    }

    $this->view->renderHtml('articleView.php', ['article' => $queryResult[0], 'nickname' => $authorQueryResult[0]['nickname']]);
}
ivashkevich 14.05.2020 в 15:13

Ок. Только проблема с форматированием. Делайте отступы как в уроках. Для этого в шторме можно нажать Ctrl+Alt+L

[email protected] 14.05.2020 в 15:43

Если вы про съехавшие фигурные скобки в функции, то похоже это происходит при копипасте текста почему-то, сам только внимание на это обратил. В IDE все нормально. А в остальном вроде с форматированием нормально(стандартный отступ в 4 пробела и пустые строки между логическими блоками). Или я чего то не замечаю? Alt+Ctrl+L пустые строки убирает, что мне не очень нравится.
Похоже понял о чем вы.

if(){
}

if()
{
}

Вы про это? Привычка из прошлого) Мне удобнее так, вложенность визуально более выделяется. Или стандарт строго не рекомендует так делать?

ivashkevich 15.05.2020 в 18:11

Да, есть стандарт PSR, которого все придерживаются

Deo 21.05.2021 в 23:11

А как решили проблему TypeError - у меня тоже id возвращает как string, а не как int...

paskelas 26.05.2020 в 14:00

Такой вариант имеет право на существование? (Публикую только метод, который поменялся)

    public function view ($articleId)
    {
         $result = $this->db->query(
           'SELECT * FROM `articles` WHERE id = :id;',
            [':id' => $articleId]);
         if ($result===[]) {
             $this->view->renderHtml('errors/404.php', 404);
            include __DIR__ .  '/../../../templates/errors/404.php';
            return;
         };

        $author = [['Не получилось найти автора']];

        $authorResult = $this->db->query(          
          'SELECT nickname FROM `users` WHERE id = :id ;', 
            [':id' => $result[0]['author_id']]);
    if ($authorResult!=[]) {
         $author = $authorResult;
    }

         $this->view->renderHtml ('articles/view.php', ['article' => $result[0], 'author'=>$author[0], 'title' =>'Статья блога']);

}

view.php

<?php include __DIR__ .  '/../header.php';?>
                <h2><?= $article['name'] ?></h2> 

                <p><?= $article['text'] ?></p>
             <h3>Автор статьи: <?= $author[0] ?></h3>

                <hr>

<?php include __DIR__ .  '/../footer.php'; ?>
ivashkevich 27.05.2020 в 17:49
        $author = [['Не получилось найти автора']];

Не надо вместо автора пихать текст ошибки. Обрабатывайте лучше в шаблоне отсутствие автора.

[email protected] 08.06.2020 в 15:05

ArticlesController.php:

public function view(int $articleId)
    {
        $result = $this->db->query(
            'SELECT * FROM `articles` WHERE id = :id;',
            [':id' => $articleId]
        );
        if ($result === []) {
            $this->view->renderHtml('errors/404.php', [], 404);
            return;
        }

        $author = $this->db->query(
            'SELECT `nickname` FROM `users` WHERE id = :id;',
            [':id' => $result[0]['author_id']]
        );

        $this->view->renderHtml('articles/view.php', ['article' => $result[0], 'nickname' => $author[0]['nickname']]);
    }

view.php

<?php include __DIR__ . '/../header.php'; ?>
<h1><?= $article['name'] ?></h1>
<p><?= $article['text'] ?></p>
<p>Автор: <?= $nickname ?></p>
<?php include __DIR__ . '/../footer.php'; ?>
ivashkevich 09.06.2020 в 12:43

Отлично

IePyton 09.06.2020 в 12:21

ArticlesController.php

<?php

namespace MyProject\Controllers;

use MyProject\Services\Db;
use MyProject\View\View;

class ArticlesController
{
    private $view;

    private $db;

    public function __construct()
    {
        $this->view = new View(__DIR__ . '/../../../templates');
        $this->db = new Db();
    }

    public function view(int $articleId)
    {
        $result = $this->db->query(
            'SELECT * FROM `articles` WHERE id = :id;',
            [':id' => $articleId]
        );

        $authorId = $result['0']['author_id'];
        $author = $this->db->query(
            'SELECT `nickname` FROM `users` WHERE id = :authorid;',
            [':authorid' => $authorId]
        );
        $result[0]['nickname'] = $author[0]['nickname'];

if ($result === []) {
$this->view->renderHtml('errors/404.php', [], 404);
return;
}
$this->view->renderHtml('articles/view.php', ['article' => $result[0]]);

}
}

view.php

<?php include __DIR__ . '/../header.php'; ?>
    <h1><?= $article['name'] ?></h1>
    <p><?= $article['text'] ?></p>
    <p>Автор статьи: <?= $article['nickname'] ?></p>

<?php include __DIR__ . '/../footer.php'; ?>
ivashkevich 09.06.2020 в 12:56

Что-то с отступами. Не могу прочитать даже из-за этого :) Как поправите - напишите ответ на этот коммент. Проверю.

IePyton 09.06.2020 в 14:55
<?php

namespace MyProject\Controllers;

use MyProject\Services\Db;
use MyProject\View\View;

class ArticlesController
{
    private $view;

    private $db;

    public function __construct()
    {
        $this->view = new View(__DIR__ . '/../../../templates');
        $this->db = new Db();
    }

    public function view(int $articleId)
    {
        $result = $this->db->query(
            'SELECT * FROM `articles` WHERE id = :id;',
            [':id' => $articleId]
        );

        $authorId = $result['0']['author_id'];
        $author = $this->db->query(
            'SELECT `nickname` FROM `users` WHERE id = :authorid;',
            [':authorid' => $authorId]
        );
        $result[0]['nickname'] = $author[0]['nickname'];

        if ($result === []) {
            $this->view->renderHtml('errors/404.php', [], 404);
            return;
        }
        $this->view->renderHtml('articles/view.php', ['article' => $result[0]]);

    }
}

view.php

<?php include __DIR__ . '/../header.php'; ?>
    <h1><?= $article['name'] ?></h1>
    <p><?= $article['text'] ?></p>
    <p>Автор статьи: <?= $article['nickname'] ?></p>

<?php include __DIR__ . '/../footer.php'; ?>
ivashkevich 10.06.2020 в 12:25

Проверка наличия статьи в базе происходит уже после того, как мы словили кучу ошибок

IePyton 10.06.2020 в 15:57

я уже убежал вперед, и код этого урока изменен, я правильно понял, что правильное решение вот такое?

<?php

namespace MyProject\Controllers;

use MyProject\Services\Db;
use MyProject\View\View;

class ArticlesController
{
    private $view;

    private $db;

    public function __construct()
    {
        $this->view = new View(__DIR__ . '/../../../templates');
        $this->db = new Db();
    }

    public function view(int $articleId)
    {
        $result = $this->db->query(
            'SELECT * FROM `articles` WHERE id = :id;',
            [':id' => $articleId]
        );

        if ($result === []) {
            $this->view->renderHtml('errors/404.php', [], 404);
            return;
        }

        $authorId = $result['0']['author_id'];
        $author = $this->db->query(
            'SELECT `nickname` FROM `users` WHERE id = :authorid;',
            [':authorid' => $authorId]
        );
        $result[0]['nickname'] = $author[0]['nickname'];

        $this->view->renderHtml('articles/view.php', ['article' => $result[0]]);

    }
}
ivashkevich 10.06.2020 в 19:22

Да

HardBass 25.06.2020 в 22:33

ArticlesController.php

    public function view(int $articleId)
    {
        $result = $this->db->query(
            'SELECT * FROM `articles` WHERE id = :id;',
            [':id' => $articleId]
        );

        $resultUser = $this->db->query(
            'SELECT * FROM `users` WHERE id = :id;',
            [':id' => $result[0]['author_id']]
        );

        if ($result === []) {
            $this->view->renderHtml('errors/404.php', [], 404);
            return;
        }

        if($resultUser === []){
            $resultUser['nickname'] = 'Аноним';
        }

        $this->view->renderHtml('articles/view.php', ['article' => $result[0], 'user' => $resultUser[0]]);

    }

view.php

<?php include __DIR__ . '/../main/header.php'; ?>
    <h1><?= $article['name'] ?></h1>
    <p><?= $article['text'] ?></p>
    <p><?= $user['nickname'] ?></p>
<?php include __DIR__ . '/../main/footer.php'; ?>
ivashkevich 26.06.2020 в 09:28

Если статьи не будет, произойдет необработанная ошибка

HardBass 26.06.2020 в 10:51

Я так понимаю, нужно сделать проверку на то, что статья найдена, до того момента, когда начинается передача данных в объект $resultUser

ArticlesController.php

public function view(int $articleId)
    {
        $result = $this->db->query(
            'SELECT * FROM `articles` WHERE id = :id;',
            [':id' => $articleId]
        );

        if ($result === []) {
            $this->view->renderHtml('errors/404.php', [], 404);
            return;
        }

        $resultUser = $this->db->query(
            'SELECT * FROM `users` WHERE id = :id;',
            [':id' => $result[0]['author_id']]
        );

        if($resultUser === []){
            $resultUser['nickname'] = 'Аноним';
        }

        $this->view->renderHtml('articles/view.php', ['article' => $result[0], 'user' => $resultUser[0]]);

    }
ivashkevich 26.06.2020 в 10:55

До того момента, как начинает использоваться несуществующий результат, если быть точнее.

[email protected] 12.07.2020 в 00:37

Привет!
ДЗ.
Контроллер:

  $result2 = $this->db->query(
            'SELECT users.nickname FROM `users` INNER JOIN `articles` ON articles.author_id = users.id WHERE articles.id = :id',
            [':id' => $articleId]
        );

view.php

<?php
include __DIR__ . '/../header.php'; ?>
    <h1><?= $article['name'] ?></h1>
    <p><?= $article['text'] ?></p>
    <p>Автор статьи: <?= $user['nickname'] ?></p>
<?php include __DIR__ . '/../footer.php'; ?>

Артем, подскажите, пожалуйста, у меня в файле main.php - ide сообщает, что $articles не определена.
Это странно, так как ошибок - нет и все уведомления включены, да и работает все.
Думаю, что так у всех, так как я шагал по урокам с вами.
Скажите, допустимо ли вообще, чтобы что-то было неопределено, т.е. можно ли на это закрыть глаза, если все работает?
Вот код:


            <?php include __DIR__ . '/../header.php' ?>
            <?php foreach ($articles  as $article):?>
            <h2><a href="/articles/<?=$article['id']?>"> <?= $article['name']?></a></h2>
            <p><?= $article['text']?></p>
            <hr>
            <?php endforeach; ?>
            <?php include __DIR__ . '/../footer.php'; ?>

Если написать в условии цикла:
$articles ?? null - то ошибка исчезает.

ivashkevich 12.07.2020 в 06:28

Привет. То, что IDE ругается - это нормально. Она же не знает что эта переменная прилетает в шаблон из другого места. Чтобы ей в этом помочь, можно добавить специальные аннотации phpDoc:

<?php
/**
 * @var array $articles
 */
?>
            <?php include __DIR__ . '/../header.php' ?>
            <?php foreach ($articles  as $article):?>
            ...
[email protected] 12.07.2020 в 09:19

Спасибо большое, двигаюсь дальше!

Hellbound 26.07.2020 в 19:02

ArticlesController

public function view(int $articleId)
    {
        $result = $this->db->query(
            'SELECT * FROM `articles` WHERE id = :id;',
            [':id' => $articleId]
        );

        if ($result === []) {
            $this->view->renderHtml('errors/404.php', [], 404);
            return;
        }

        $author_result = $this->db->query(
            'SELECT `nickname` FROM `users` WHERE id = :id;',
            [':id' => $result[0]['author_id']]
        );

        if ($author_result == []) {
            $author_result[0]['nickname'] = 'неизвестен';
        }

        $this->view->renderHtml('articles/view.php', ['article' => $result[0], 'author' => $author_result[0]]);
    }

view

<?php include __DIR__ . '/../header.php'; ?>
    <h1><?= $article['name'] ?></h1>
    <p><?= $article['text'] ?></p>
    <p>Автор <?= $author['nickname'] ?></p>
<?php include __DIR__ . '/../footer.php'; ?>
ivashkevich 27.07.2020 в 18:45
$author_result

Что мы в курсе для начинающих говорили про нейминг переменных? camelCase.
Для чего приписка _result?

        if ($author_result == []) {
            $author_result[0]['nickname'] = 'неизвестен';
        }

Так лучше не делать. Лучше завести отдельную переменную $nickname, и в случае если массив не пустой, положить в неё значение. И уже эту переменную прокидывать в шаблон для вывода.

VitaliyB 10.08.2020 в 10:12

MainControllers.php

 public function main()
    {
        $articles = $this->db->query('SELECT * FROM `articles`  JOIN `users` ON articles.author_id = users.id');
        $this->view->renderHtml('main/main.php', ['articles' => $articles]);
    }

ArticlesController.php

 public function view(int $articleId)
    {
        $result = $this->db->query('SELECT * FROM `articles` JOIN `users`  ON articles.author_id = users.id WHERE articles.id = :id;',[':id' => $articleId]);

        if ($result === []) {
            $this->view->renderHtml('errors/404.php', [], 404);
            return;
        }
        $this->view->renderHtml('articles/view.php', ['article' => $result[0]]);
    }

main.php

<p>Автор статьи: <?= $article['nickname'] ?></p>

templites/articles/views.php

<p>Автор статьи: <?= $article['nickname'] ?></p>
ivashkevich 11.08.2020 в 13:26

Отлично

Dram 18.08.2020 в 14:12

Добрый день, прошу пояснить запись вида

'SELECT * FROM `articles` WHERE id = :id;',
            [':id' => $articleId]

мне непонятен кусок - :id;',
[':id' => $articleId]
Что это? Даже не знаю как описать... и не переменная и не кусок массива, как понять такую запись?

Я в своем говнокоде привык писать так,

"SELECT * FROM `articles` WHERE id = '{$articleId}';"

Мне кажется в разы читабельнее, нет? Можно ли использовать мой код и если нет, то почему?

ivashkevich 19.08.2020 в 17:52

Это называется параметризованный запрос, и он автоматом защищает от SQL-injection.

https://www.php.net/manual/ru/pdo.prepare.php

Dram 19.08.2020 в 21:54

Спасибо, правильно я понял -

'SELECT * FROM `articles` WHERE id = :id;',
            [':id' => $articleId]

:id - двоеточие обязательно, id любая придуманная нами псевдопеременная
далее запятая,
потом массив где псевдопеременной присваивается реальная переменная

Правильно понял?

ivashkevich 23.08.2020 в 08:54

Да

Dram 19.08.2020 в 17:40

Мое решение - изменить запрос на

        $articles = $this->db->query('SELECT t1.*,t2.nickname FROM `articles` as t1
 inner join users as t2 on t1.author_id = t2.id
;');

В шаблоне добавить

<p>Автор: <?= $article['nickname'] ?></p>
ivashkevich 19.08.2020 в 18:00

Годится

demos 07.09.2020 в 12:40

ArticlesController.php

<?php

namespace MyProject\Controllers;

use MyProject\Services\Db;
use MyProject\View\View;

class ArticlesController
{
    /** @var View */
    private $view;

    /** @var Db */
    private $db;

    public function __construct()
    {
        $this->view = new View(__DIR__ . '/../../../templates');
        $this->db = new Db();
    }

    public function view(int $articleId)
    {
        $result = $this->db->query(
            'SELECT * FROM `articles` as a join `users` as b on a.author_id=b.id WHERE a.id = :id',
            [':id' => $articleId]
        );
        if ($result === []) {
            $this->view->renderHtml('errors/404.php', [],404);
            return;
        }
        $this->view->renderHtml('articles/view.php', ['article' => $result[0]]);
    }
}

templates/articles/view.php

<?php include __DIR__ . '/../header.php'; ?>
    <h1><?= $article['name'] ?></h1>
    <p><?= $article['text'] ?></p>
    <i><?= $article['nickname'] ?></i>
<?php include __DIR__ . '/../footer.php'; ?>
ivashkevich 07.09.2020 в 12:54

Отлично

pavelvlk 16.10.2020 в 22:10

Приветствую. Так правильно или стоит по другому делать?
ArticlesController.php

public function view(int $articleId)
    {
        $result = $this->db->query('SELECT * FROM `articles` WHERE id = :id;',
        [':id' => $articleId]);

        if ($result === [])
        {
            $this->view->renderHtml('errors/404.php', [], 404);
            return;
        }

        $author = $this->db->query('SELECT u.nickname, a.name FROM users AS u INNER JOIN articles AS a ON u.id=a.author_id WHERE a.id = :id;',
        [':id' => $articleId]);

        $this->view->renderHtml('articles/view.php', ['article' => $result[0], 'author' => $author[0]]);
    }

view.php

<?php include __DIR__ . '/../header.php'; ?>
    <h1><?= $article['name'] ?></h1>
    <p><?= $article['text'] ?></p>
    <p>Автор статьи: <?= $author['nickname'] ?></p>
<?php include __DIR__ . '/../footer.php'; ?>
ivashkevich 18.10.2020 в 15:20

Всё просто отлично!)

Ed8L 23.10.2020 в 13:06

Запрос в ArticlesController::view()

$result = $this->db->query(
            'SELECT articles.*, users.nickname FROM articles INNER JOIN users on users.id=articles.author_id WHERE articles.id = :id',
            [':id' => $articleId]
        );

Шаблон

<p><?= $article['nickname'] ?></p>
ivashkevich 26.10.2020 в 05:44

Отлично

SkSeMi 11.11.2020 в 01:16

Приает, Артём!
Подскажи при твлем подходе, варианте реализации представления и шаблона возможно следующее.
Что у меня вот например неоьходимо реализовать так что в нутри файла есть разные подшаблоны файлы.
Например для меню, таблицы контекста.
Каким образом можно внутри шаблона снова вызвать рендеринг вложенного в него подшаблона?!
То есть например, внутри шаблона вывода контента различной структуры вызвать реедеринг подшаблона что подобие таким образом
$this->view->renderHtml('main/main_сontent.php',['content' => $contet]);
А у же в этом файле подшаблона
Вывод контента соответсвующим оьразом как в данной статье.
Большое спасибо!

ivashkevich 13.11.2020 в 02:30

Можно сделать статический метод для такого, например. Сделайте класс Renderer и у него статический метод render(string $pathToTemplate, array $vars)

SkSeMi 16.11.2020 в 00:17

Домашняя работа.
ArticlesXontroller.php содержит теперь:

    public function view(int $articleId)
    {
        $result = $this->db->query(
            'SELECT * FROM `articles` WHERE id = :id;',
            [':id' => $articleId]
        );

        print_r("<pre>");

        $result2 = $this->db->query(
            'SELECT nickname FROM `users` WHERE id = :id;',
            [':id' => $result[0]["author_id"]]
        );

        $result[0]["nickname"]  = $result2[0]["nickname"];
        // print_r($result2);
        print_r($result);
        print_r("</pre>");

        if ($result === []) {
            $this->view->renderHtml('errors/404.php', [], 404);
            return;
        }

        $this->view->renderHtml('articles/view.php', ['article' => $result[0]]);
    }

А в шаблоне C:\OpenServer\domains\phpzone2\templates\articles\view.php
Решил просто поставить над загооловком статьи

<?php include __DIR__ . '/../header.php'; ?>
    <h2><?= $article['nickname'] ?></h2>
    <h1><?= $article['name'] ?></h1>
    <p><?= $article['text'] ?></p>
<?php include __DIR__ . '/../footer.php'; ?>
SkSeMi 16.11.2020 в 00:22

В идеале наверное как-то так нужно было сделать SQL запрос

SELECT * FROM articles INNER JOIN users ON (articles.author_id=:id1)WHERE(articles.id=:id2)

ivashkevich 17.11.2020 в 17:15

Да нет, прошлый вариант ок

SkSeMi 23.11.2020 в 23:35

Хотелось бы просто еще больше тренироваться и понимать на практике сложные SQL запросы.

ivashkevich 17.11.2020 в 17:15

Вместо print_r используйте var_dump

https://php.zone/post/krasivyy-vyvod-var-dump-openserver

В целом ок, единственное, запихивать никнейм в статью - как-то не очень. Лучше отдельным параметром его в рендерилку передать

SkSeMi 23.11.2020 в 23:36

Да, спасибо большое!
Обязательно учту. Это просто старая привычка у меня осталась.
Скоро от нее принтов окончательно избавлюсь.

RosenRot 21.11.2020 в 11:39
:id

Скажите, это вообще что? Не могу понять. И откуда берется?

ivashkevich 23.11.2020 в 17:32

Это подстановка. На её место встанет значение, переданное в параметрах с этим ключем.

SkSeMi 23.11.2020 в 23:32

В файле templates/main/main.php вместо

<?php include __DIR__ . '/../main/header.php'; ?>
<?php foreach ($articles as $article): ?>
    <h2><a href="/articles/<?= $article['id'] ?>"><?= $article['name'] ?></a></h2>
    <p><?= $article['text'] ?></p>
    <hr>
<?php endforeach; ?>
<?php include __DIR__ . '/../main/footer.php'; ?>

Заработал код

<?php include __DIR__ . '/../header.php'; ?>
<?php foreach ($articles as $article): ?>
    <h2><a href="/articles/<?= $article['id'] ?>"><?= $article['name'] ?></a></h2>
    <p><?= $article['text'] ?></p>
    <hr>
<?php endforeach; ?>
<?php include __DIR__ . '/../footer.php'; ?>

Точно ли все в порядке с путями?!

ivashkevich 25.11.2020 в 21:13

Ну так в уроке вроде так и написано, нет?

SkSeMi 25.11.2020 в 22:20

templates/main/main.php

<?php include __DIR__ . '/../main/header.php'; ?>
<?php foreach ($articles as $article): ?>
    <h2><a href="/articles/<?= $article['id'] ?>"><?= $article['name'] ?></a></h2>
    <p><?= $article['text'] ?></p>
    <hr>
<?php endforeach; ?>
<?php include __DIR__ . '/../main/footer.php'; ?>

Зайдём в корень нашего сайтика и увидим, что теперь мы можем переходить по каждой статье отдельно.

ivashkevich 29.11.2020 в 11:48

Аа, в самом конце уже. Спасибо, исправил) Странно, что в начале урока всё правильно было.

SkSeMi 29.11.2020 в 18:29

Убедительно прошу только понять меня правильно, что я задаю вопросы здесь и в чате телеграмма только для того чтобы все максимально разобраться, применять, и если найдены ошибки их помочь исправить.
В частности проблема как писал ранее в чате или в комментариях есть в пути /.. /src/ пришлось заменить на /src/.
И есть другие еще моменты, которые предоставлю, для исправления/обсуждения в конце прохождения курса.
И если не против, то готов стать соавтором, соредактором проекта. Цель самое главное взаиморазвитие, взаимопомощь.

ivashkevich 01.12.2020 в 04:04

Да конечно, я только за! Напиши в личку в телеге.

pixel 15.12.2020 в 06:30
public function view(int $articleId)
    {
        $result = $this->db->query(
            'SELECT * FROM `articles` AS a 
                INNER JOIN `users` AS u 
                ON a.author_id = u.id 
                WHERE a.id = :id;',
            [':id' => $articleId]
        );

        if ($result === []) {
            $this->view->renderHtml('errors/404.php', [], 404);
            return;
        }

        $this->view->renderHtml('articles/view.php', ['article' => $result[0]]);
    }
ivashkevich 17.12.2020 в 17:46

Отлично

MikeSiebel 11.01.2021 в 09:43

Добрый день!
Домашнее задание
ArticlesController.php

…
public function view(int $articleId)
{
    $articles = $this->db->query(
        'SELECT * FROM `articles` WHERE id = :id;',
        [':id' => $articleId]
    );

    var_dump($articles);

    if ($articles === []) {
        $this->view->renderHtml('errors/404.php', [], 404);
        return;
    }
    $users = $this->db->query(
        'SELECT * FROM `users` WHERE id = :id',
        [':id' => $articles[0]['author_id']]
    );

    if ($users === []) {
        $users[0]['nickname'] = 'не известен';
    }

    $this->view->renderHtml('articles/view.php', ['article' => $articles[0], 'nickname' => $users[0]['nickname']]);

}

view.php

<?php
/** @var ArticlesController $article */
/** @var ArticlesController $nickname */
use MyProject\Controllers\ArticlesController?>

<?php include __DIR__ . '/../header.php'; ?>
<h1><?= $article['name'] ?></h1>
<p><?= $article['text'] ?></p>
<p>Автор статьи: <?= $nickname ?></p>
<?php include __DIR__ . '/../footer.php'; ?>
ivashkevich 11.01.2021 в 19:49

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

zick 17.02.2021 в 22:37

Пытаюсь в MainController добавить автора, выдает везде admin, дело в foreach(е), не пойму в чем конкретно

public function main()
    {
        $articles = $this->db->query("SELECT * FROM `articles`;");
        $result_user = $this->db->query("SELECT * FROM `users` WHERE id=:id;",
            [":id"=>$articles[0]["author_id"]]
        );
        $this->view->renderHtml('main/main.php', ['articles' => $articles, 'nickname' => $result_user[0]['nickname']]);
    }
    public function sayHello(string $name)
    {
        $this->view->renderHtml('main/hello.php', ['name' => $name, "title" => "Страница приветствия"]);
    }

main.php

<?php include __DIR__ . "/../header.php"; ?>
<?php foreach ($articles as $article): ?>
    <h2><a href="/articles/<?= $article["id"]?>"><?=$article["name"]?></a></h2>
    <p><?= $article["text"] ?></p>
    <p>Имя автора: <?= $nickname ?></p>
    <hr>
<?php endforeach; ?>
<?php include __DIR__ . "/../footer.php";
ivashkevich 20.02.2021 в 05:02

Дело не в foreach. Воспользуйтесь дебаггером.

Egor.Ka 05.04.2021 в 19:13

ArticlesController.php

 public function view(int $articleId)
    {
        $result = $this->db->query(
            '
                 SELECT * FROM users INNER JOIN articles ON users.id = articles.author_id WHERE articles.id = :id;',
            [':id' => $articleId]
        );

view.php

<?php include __DIR__ . '/../header.php'; ?>
    <h1><?= $article['name'] ?></h1>
    <p><?= $article['text'] ?></p>
    <p><?= $article['nickname'] ?></p>
<?php include __DIR__ . '/../footer.php'; ?>
ivashkevich 08.04.2021 в 19:45

Ок

Vladimir96 26.04.2021 в 17:55

ArticlesController.php

    public function view(int $articleId)
    {
        $result = $this->db->quary(
            'SELECT * FROM `articles` WHERE id = :id;',
            [':id' => $articleId]
        );

        //начало дз
        $authorId = $result[0][1] ?? '';
        $author = $this->db->quary(
            'SELECT `nickname` FROM `users` WHERE  id = :author_id',
            [':author_id' => $authorId]
        );
        //конец дз

        if ($result === [] || $author === []) {
            $this->view->renderHtml('errors/404.php', [], 404);
            return;
        }

        $this->view->renderHtml('articles/view.php', ['article' => $result[0], 'nickname' => $author[0]]);
    }

view.php

<?php include __DIR__ . '/../header.php'; ?>
    <h1><?= $article['name'] ?> </h1>
    <p><?= $article['text'] ?> </p>
    <p>Автор: <?= $nickname['nickname'] ?> </p>
<?php include __DIR__ . '/../footer.php'; ?>
ivashkevich 28.04.2021 в 19:22
$authorId = $result[0][1] ?? ''

Лучше использовать именованные ключи. Почему используется пустая строка, если значения нет?

        $author = $this->db->quary(
            'SELECT `nickname` FROM `users` WHERE  id = :author_id',
            [':author_id' => $authorId]
        );

Почему автор запрашивается, если authorId может быть пустой строкой?

        $this->view>renderHtml('articles/view.php', ['article' => $result[0], 'nickname' => $author[0]]);

В шаблон передается не никнейм, а сам автор, некорректное название.

        if ($result === [] || $author === []) {
            $this->view->renderHtml('errors/404.php', [], 404);
            return;
        }

Некорректная обработка ситуации, когда статья найдена, а автор - нет.

Vladimir96 06.05.2021 в 14:23

вроде понял, надеюсь правильно все, спасибо за обратную связь) от души душевно в душу))

    public function view(int $articleId)
    {
        $result = $this->db->query(
            'SELECT * FROM `articles` WHERE id = :id;',
            [':id' => $articleId]
        );

        if ($result !== []) {
            $authorIdForQuery = $result[0]['author_id'];

            $author_id = $this->db->query(
                'SELECT * FROM `users` WHERE id = :author_id',
                [':author_id' => $authorIdForQuery]
            );
        }

        if ($result === []) {
            $this->view->renderHtml('errors/404.php', [], 404);
            return;
        }

        $this->view->renderHtml('articles/view.php', ['article' => $result[0], 'author' => $author_id[0]]);
    }
}

view.php

<?php include __DIR__ . '/../header.php'; ?>
    <h1><?= $article['name'] ?></h1>
    <p><?= $article['text'] ?></p>
    <p>Автор: <?= $author['nickname'] ?></p>
<?php include __DIR__ . '/../footer.php'; ?>
ivashkevich 19.05.2021 в 21:17

Теперь норм

Логические задачи с собеседований