Чат Telegram
Группа ВКонтакте

Комментарии к публикации
View в MVC

Новый комментарий


tomsonst 01.09.2018 в 14:12
// MainController.php

<?php

namespace MyProject\Controllers;
use MyProject\View\View;
class MainController
{
    private $view;

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

    public function main()
    {
        $articles = [
            ['name' => 'Статья 1', 'text' => 'Текст статьи 1'],
            ['name' => 'Статья 2', 'text' => 'Текст статьи 2'],
        ];
        $title = '';
        $this->view->renderHtml('main/main.php', ['articles' => $articles], $title);
    }

    public function sayHello(string $name)
    {
        $title = 'Страница приветствия';
        $this->view->renderHtml('main/hello.php', ['name' => $name], $title);
    }
}

// View.php 

<?php

namespace MyProject\View;
class View
{
    private $templatesPath;

    public function __construct(string $templatesPath)
    {
        $this->templatesPath = $templatesPath;
    }

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

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

        echo $buffer;
    }
}

// header.php

    <?php 
    if (!empty($title)) {
        $title;
    } else {
    $title = 'Мой блог';
} ?>
    <title><?= $title ?></title>
ivashkevich 01.09.2018 в 19:09

А зачем вам еще один параметр? Можно же title положить в vars, просто еще одно значение.
Выводить можно проще:

<title><?= $title ?? 'Мой блог' ?></title>
Sparkqy 05.09.2018 в 13:10

Переменную $title передаю из MainController в renderHtml (в массив $vars). Все работает, но не получается вывести <title> при пустом значении $title. Вывожу так:
<title><?= $title ?? "Мой блог" ?></title>

Если делать проверку if (empty($title)), то выводит что надо. Почему <?= $title ?? "Мой блог" ?> не работает?

ivashkevich 05.09.2018 в 23:47

Оператор ?? работает только с null-ом. Значит там не null, попробуй через var_dump узнать, что в переменной лежит. Скорее всего у тебя там пустая строка =)

Sparkqy 06.09.2018 в 14:35

О, да, так и есть. Не знал про Null :)

computerix 24.09.2018 в 08:49
//routes
<?php
return [
    '~^hello/(.*)$~' => [\MyProject\Controllers\MainController::class, 'sayHello'],
    '~^bye/(.*)$~' => [\MyProject\Controllers\MainController::class, 'sayBye'],
    '~^$~' => [\MyProject\Controllers\MainController::class, 'main'],
    '~(.*)$~' => [\MyProject\Controllers\MainController::class, 'title'],
];

//MainController
<?php
namespace MyProject\Controllers;

use MyProject\View\View;

class MainController
{
    private $view;

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

    public function main()
    {
        $articles = [
            ['name' => 'Статья 1', 'text' => 'Текст статьи 1'],
            ['name' => 'Статья 2', 'text' => 'Текст статьи 2'],
        ];
        $this->view->renderHtml('main/main.php', ['articles' => $articles]);
    }
    public function sayHello(string $name)
    {
        $this->view->renderHtml('main/hello.php', ['name' => $name]);
    }
    public function sayBye(string $name)
    {
        $this->view->renderHtml('main/bye.php', ['name' => $name]);
    }
    public function title(string $title)
    {
        $articles = [
            ['name' => 'Статья 1', 'text' => 'Текст статьи 1'],
            ['name' => 'Статья 2', 'text' => 'Текст статьи 2'],
        ];
       $this->view->renderHtml('main/main.php', ['title' => $title, 'articles' => $articles]);
    }
}

//main
<? if (empty($title)) {$title = 'Мой блог';} ?>
<title><?= $title ?></title>
<?php include __DIR__ . '/../header.php'; ?>
<?php foreach ($articles as $article): ?>
    <h2><?= $article['name'] ?></h2>
    <p><?= $article['text'] ?></p>
    <hr>
<?php endforeach; ?>
<?php include __DIR__ . '/../footer.php'; ?>

//hello
<title>Страница приветствия</title>
<?php include __DIR__ . '/../header.php'; ?>
Привет, <?= $name ?>!!!
<?php include __DIR__ . '/../footer.php'; ?>
ivashkevich 24.09.2018 в 23:10

Вся домашка заключалась в следующем:

  • в шаблоне header.php добавить:
    <title><?= $title ?? 'Мой блог' ?></title>
  • в экшене sayHello() сделать следующее:
    public function sayHello(string $name)
    {
    $this->view->renderHtml('main/hello.php', ['name' => $name, 'title' => 'Страница приветствия']);
    }

Возможно, я плохо сформулировал домашнее задание, если это так, напишите мне в ВК, подумаем, как сделать лучше.

Если же вам просто захотелось поэкспериментировать - то всё в порядке =)

computerix 25.09.2018 в 05:14

Все оказалось проще, чем я понял) Я ещё подумал, что сложноватая домашка, но зато разобрался хорошо, пока делал)

ArtemijeKA 17.10.2018 в 09:26

Я написал в /src/MVCExample/Views/View.php

public function renderHtml(string $templateName, array $vars)

Обязательно ли писать:

array $vars = []
ivashkevich 19.10.2018 в 00:17

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

ArtemijeKA 20.10.2018 в 07:02

Понял, спасибо.

ArtemijeKA 17.10.2018 в 10:53

Учитель, почему у меня не подключаются стили если я перехожу на /hello/Name?
code github

PS
У меня структура локального сайта построена как учебник с папками по этому дирректория с фронтальным контроллером такая:

http://php_book/mvc/www/index.php
ivashkevich 19.10.2018 в 00:19

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

ArtemijeKA 20.10.2018 в 06:57

Я так понял у нас localhost подключен к www?
И тогда подключая стили через / корневой слеш мы не ошибаемся и попадаем сначала в www дирректорию.

ivashkevich 20.10.2018 в 10:06

www - должна быть корневой директорией сайта. И если в браузере пишем /что-то там, то веб сервер будет искать именно в папке www. Как и index.php в этой папке является точкой входа в приложение.

SBTesla 17.10.2018 в 12:29
//header.php
<title><?= $title ?? 'Мой блог-жек'?></title>

//routes.php
return[
      '~^hello/(.*)$~' => [\MyProject\Controllers\MainController::class, 'sayHello'],
      '~^$~' => [MyProject\Controllers\MainController::class, 'main'],
      '~^bye/(.*)$~' => [MyProject\Controllers\MainController::class, 'sayBye'],
     '~(.*)$~'=>[MyProject\Controllers\MainController::class, 'sayHello']
      ];

//MainController.php

namespace MyProject\Controllers;

use MyProject\View\View;

class MainController
     {
          private $view;

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

     public function main()
          {

               $articles = [
                     ['name' => ' Статья 1 ', 'text' => ' Текст статьи 1'],
                    ['name' => ' Статья 1 ', 'text' => ' Текст статьи 2'],
               ];
               include __DIR__ . '/../../../templates/main/main.php';
          }
          public function sayHello(string $name)
          {
               $this->view->renderHtml('main/hello.php', ['name' => $name, 'title' => 'Страница приветствия']);
          }

          public function sayBye(string $name)
          {
               echo 'Досвидания, ' . $name;
          }

     }
ivashkevich 19.10.2018 в 00:19

Супер! =)

ArtemijeKA 20.10.2018 в 09:30
// MainController.php
public function sayHello(string $name)
    {
        $this->view->renderHtml('main/hello.php', ['name' => $name, 'title' => 'Страница приветствия']);
    }
// header.php
<title><?=$title ?? 'Мой блог'?></title>
ivashkevich 20.10.2018 в 10:07

Отлично!

AxLT 01.11.2018 в 23:10

Почему так работает:

<?= $title ?? 'Мой блог' ?>

а так нет?

<?php $title ?? 'Мой блог' ?>
ivashkevich 02.11.2018 в 01:24

<?=... - это сокращение для <?php echo...

demyanovpaul@yandex.ru 07.11.2018 в 12:59

Сделайте чтобы title для каждой страницы можно было задавать через переменную для шаблона. В случае, когда title не передан, выводите заголовок по умолчанию - "Мой блог". Для страницы /hello/username сделайте title "Страница приветствия".

//header.php
<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <title><?= $title ?? 'Мой блог'; ?></title>
    <link rel="stylesheet" href="/styles.css">
</head>
<body>

<table class="layout">
    <tr>
        <td colspan="2" class="header">
            Мой блог
        </td>
    </tr>
    <tr>
        <td>
//MainController.php
public function sayHello(string $name)
    {
        $this->view->renderHtml('main/hello.php', ['name' => $name, 'title' => 'Страница приветствия']);
    }
ivashkevich 08.11.2018 в 10:37

То что нужно!

Todd 08.11.2018 в 00:57

MainController

 public function sayHello(string $name) {
        $this->view->renderHtml('main/hello.php', ['name' => $name, 'title' => 'Страница приветствия']);
    }

header

<title><?= $title ?? 'my blog' ?></title>
ivashkevich 08.11.2018 в 10:38

Отлично! Не забывайте переносить для функций открывающую фигурную скобку на отдельную строку.

bildep 18.11.2018 в 18:21

MainController.php

<?php
namespace MyProject\Controllers;

use MyProject\View\View;

class MainController
{

    private $view;

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

    public function main()
    {
        $articles = [
            ['name' => 'Статья 1', 'text' => 'Текст статьи 1'],
            ['name' => 'Статья 2', 'text' => 'Текст статьи 2'],
        ];
        $this->view->renderHtml('main/main.php', ['articles' => $articles]);
    }

    public function sayHello(string $name)
    {

        $this->view->renderHtml('main/hello.php', ['name' => $name, 'title' => "Страница приветствия" ]);
    }

    public function sayBye(string $name)
    {
        echo 'Пока, ' . $name;
    }
}

header.php

<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <title><?=$title ?? 'Мой блог';?></title>
    <link rel="stylesheet" href="/styles.css">
</head>
<body>

<table class="layout">
    <tr>
        <td colspan="2" class="header">
            Мой блог
        </td>
    </tr>
    <tr>
        <td>
ivashkevich 19.11.2018 в 21:53

Ты за пару дней решил весь курс пройти?) Супер-прогресс! Программировал до этого?

virtual2018 26.12.2018 в 10:19

MainController.php

    public function sayHello(string $name)
    {
        $this->view->renderHtml('main/hello.php', ['name' => $name, 'title' => 'Страница приветствияs']);
}

header.php

    <title><?= $title ?? 'Мой блог'?></title>
ivashkevich 26.12.2018 в 23:37

Отлично!

alepawka 02.01.2019 в 11:24

не понятно про
renderHtml('main/main.php', ['articles' => $articles]);
зачем тут массив? я так и не понял
и для чего применять extract в методе renderHTML??

ivashkevich 02.01.2019 в 21:28

extract из ключей массива делает переменные. Внутри метода renderHtml после вызова extract появится переменная $articles, значением которой будет значение элемента массива.

alepawka 02.01.2019 в 12:03
<title><?= $title ?? 'Мой блог ?>'</title> //header.php
$this->view -> readerHTML('/main/hello.php',['name' => $name],'title' = 
                'Страница приветствия']);//maincontroller.php
ivashkevich 02.01.2019 в 21:28

Не работает.

alepawka 04.01.2019 в 07:53

$this->view -> readerHTML('/main/hello.php',['name' => $name],'title' =>
'Страница приветствия']);

ivashkevich 04.01.2019 в 08:55

Я вижу что не работает, даже не запуская. Вы себя пытаетесь обмануть?)

Bogdan 10.01.2019 в 17:48
$this->view -> readerHTML('/main/hello.php',['name' => $name],'title' =>
'Страница приветствия']);

если я правильно понял, то у тебя закрыта скобка после => $name], а дальше пошла фигня))

ivashkevich 11.01.2019 в 11:09

Именно)

virtual2018 02.01.2019 в 15:10

Вопрос по примеру с обработкой ошибки, в этом коде

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

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

    $error = 'В шаблоне была ошибка!';

    if (empty($error)) {
        echo $buffer;
    } else {
        echo $error;
    }
}

всегда будет сообщение об ошибке в шаблоне, так как мы "влоб" указали $error. Как узнать, что в шаблоне ошибка?

ivashkevich 02.01.2019 в 21:29

Просто передавайте её через переменные для шаблона, при вызове renderHtml

landialog 06.01.2019 в 23:09

Честно говоря запутался. Решение в комментах уже видел, но сам бы не сделал.
Не понятно как title с контроллера попадает в шаблон header.php, ведь передача идет на main.php?
Почему title сделали в методе sayHello?
Есть схожесть передачи переменных в шаблон (на фр.ворке Laravel). Но там как-то изящнее

ivashkevich 06.01.2019 в 23:14
  1. header подключается внутри main и переменная в нём доступна.
  2. Данные из контроллера передаются в шаблон, непонятен ваш вопрос.
Bogdan 10.01.2019 в 17:08

MainController.php

<?php

namespace MyProject\Controllers;

use MyProject\View\View;

class MainController
{
    private $view;

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

    public function main()
    {
        $articles = [
            ['name' => 'Статья 1', 'text' => 'Текст статьи 1'],
            ['name' => 'Статья 2', 'text' => 'Текст статьи 2'],
        ];
        $this->view->renderHtml('main/main.php', 'Мой блог', ['articles' => $articles]);
    }

    public function sayHello(string $name)
    {
        $this->view->renderHtml('main/hello.php', 'Страница приветствия' , ['name' => $name]);
    }

View.php

<?php

namespace MyProject\View;

class View
{
    private $templatesPath;

    public function __construct(string $templatesPath)
    {
        $this->templatesPath = $templatesPath;
    }

    public function renderHtml(string $templateName, string $title, array $vars = [] )
    {
        array_push($vars, $title);
        extract($vars); // в неё передаётся массив ['key1' => 1, 'key2' => 2, ...],
        //                 а после её вызова у нас имеются переменные $key1 = 1 и $key2 = 2, ... .

        ob_start();
        include $this->templatesPath . '/' . $templateName;
        $buffer = ob_get_contents(); // весь этот поток вывода положить во временный буфер вывода
        ob_end_clean();

        echo $buffer;
    }

}

main.php

<?php include __DIR__ . '/../headerTop.php'; ?>
    <title><?= $title ?></title>
<?php include __DIR__ . '/../headerBot.php'; ?>
<?php foreach ($articles as $article): ?>
    <h2><?= $article['name'] ?></h2>
    <p><?= $article['text'] ?></p>
    <hr>
<?php endforeach; ?>
<?php include __DIR__ . '/../footer.php'; ?>

hello.php

<?php include __DIR__ . '/../headerTop.php'; ?>
    <title><?= $title ?></title>
<?php include __DIR__ . '/../headerBot.php'; ?>
    Привет, <?= $name ?>!!!
<?php include __DIR__ . '/../footer.php'; ?>
ivashkevich 11.01.2019 в 11:13

Зачем два header-а и между ними вывод $title? Не нужно ещё один аргумент в renderHtml. Используйте существующие.

Bogdan 11.01.2019 в 21:32

я изначально думал что надо разбить еще хедер на 2 части, что б вынести title (а разметку оставить нетронутой, и потом не искать где и что выводится), так как мы сделали с хедером и футером, потом уже посмотрел как делали другие и все исправил. Спасибо

excent63 14.02.2019 в 12:04

Добрый день!
Вот решение дз:

//header.php
<title><?=$title ?? 'Мой блог';?></title>

//MainController.php
public function sayHello(string $name)
    {
        $this->view->renderHtml('main/hello.php',['name'=>$name, 'title'=> 'Страница приветствия!']);
    }
ivashkevich 17.02.2019 в 21:59

Отлично!

radinpasha13@gmail.com 15.03.2019 в 15:29

я,может, чего не понял, но как в самом начале при переходе по http://myproject.loc/, нам выдает страницу с блогом,если блог находится в другой директории, а в контроллере мы просто включили этот файл

ivashkevich 17.03.2019 в 23:23

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

Alexander 23.03.2019 в 22:27

Изначально не полностью понял про extract и создавал сначала переменную(как в коде снизу), а потом передавал в массив $vars, но после по комментам понял, что можно прямо так. Да и в статье ведь написано, что создается переменная из ключа.. Но да ладно, хоть разобрался) Спасибо за урок)

// MainController.php

public function sayHello(string $name)
    {
        $title = 'Страница приветсвия';
        $this->view->renderHtml('main/hello.php', ['name' => $name, 'title' => $title]);
    }

    public function sayBye(string $name)
    {
        $title = 'Страница прощания';
        $this->view->renderHtml('main/bye.php', ['name' => $name, 'title' => $title]);
    }

// header.php

<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <title><?= $title ?? 'Мой блог' ?></title>
    <link rel="stylesheet" href="/styles.css">
</head>
<body>

<table class="layout">
    <tr>
        <td colspan="2" class="header">
            <?= $title ?? 'Мой блог' ?>
        </td>
    </tr>
    <tr>
        <td>
ivashkevich 23.03.2019 в 22:36

Отличный код =)

Evgeny 24.03.2019 в 00:10

<?php

namespace MyProject\Controllers;

use MyProject\View\View;

class MainController
{
    private $view;

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

    public function main(): void
    {
        $articles = [
            ['name' => 'Статья 1', 'text' => 'Текст статьи 1'],
            ['name' => 'Статья 2', 'text' => 'Текст статьи 2'],
        ];

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

    public function sayHello(string $name): void
    {
        $this->view->renderHtml('main/hello.php', ['name' => $name, 'title' => 'Страница приветствия']);
    }
}

Header.php


<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <title><?= $title ?: 'Мой блог'; ?></title>
    <link rel="stylesheet" href="/styles.css">
</head>
<body>

<table class="layout">
    <tr>
        <td colspan="2" class="header">
            Мой блог
        </td>
    </tr>
    <tr>
        <td>
ivashkevich 24.03.2019 в 00:24

Отлично

CarfikDK 26.03.2019 в 17:10

Спасибо за урок!

heder.php

<title> <?= $title ?? 'Мой блог'; ?> </title>

MainController.php

public function sayHello(string $name)
    {
        $this->view->renderHtml('main/hello.php', ['name' => $name, 'title' => 'Страница приветствия']);
    }
ivashkevich 27.03.2019 в 11:38

Отлично

babls2332@gmail.com 04.04.2019 в 11:54
public function renderHtml(string $templateName, array $vars = [], string $title)
    {
        if ($title === null || empty($title)) {
            $title = "Мой блог";
        }
        extract($vars);

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

        echo $buffer;

    }

<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <title><?= $title ?></title>
    <link rel="stylesheet" href="../styles.css">
</head>
<body>

<table class="layout">
    <tr>
        <td colspan="2" class="header">
            Мой блог
        </td>
    </tr>
    <tr>
        <td>
ivashkevich 05.04.2019 в 11:14

Зачем отдельный параметр, если есть vars?

Boodoo 14.04.2019 в 17:39

View.php

<?php
    namespace MyProject\View;

    class View
    {
        private $templatesPath;

        public function __construct(string $templatesPath)
        {
            $this->templatesPath = $templatesPath;
        }

        public function renderHtml(string $templateName, array $vars = [], string $title = 'Мой блог')
        {
            extract($vars);

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

            echo $buffer;
        }
    }

MainController.php

<?php
    namespace MyProject\Controllers;

    use MyProject\View\View;

    class MainController
    {
        private $view;

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

        public function main()
        {
            $articles = [
                ['name' => 'Статья 1', 'text' => 'Текс статьи 1'],
                ['name' => 'Статья 2', 'text' => 'Текс статьи 2']
            ];
            $this->view->renderHtml('main/main.php', ['articles' => $articles]);
        }

        public function sayHello(string $name)
        {
            $this->view->renderHtml('main/hello.php', ['name' => $name], 'Страница приветствия');
        }
    }

header.php

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title><?= $title ?></title>
    <link rel="stylesheet" href="/styles.css">
</head>
<body>
<table class="layout">
    <tr>
        <td colspan="2" class="header">
            Мой блог
        </td>
    </tr>
    <tr>
        <td>
ivashkevich 15.04.2019 в 08:09

Не нужно для тайтла делать третий аргумент. Смотрите решения выше.

Boodoo 15.04.2019 в 14:18

header.php

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title><?= $title ?? 'Мой блог' ?></title>
    <link rel="stylesheet" href="/styles.css">
</head>
<body>
<table class="layout">
    <tr>
        <td colspan="2" class="header">
            Мой блог
        </td>
    </tr>
    <tr>
        <td>

MainController.php

.....
public function sayHello(string $name)
        {
            $this->view->renderHtml('main/hello.php', ['name' => $name, 'title' => 'Страница приветствия']);
        }
ivashkevich 15.04.2019 в 14:27

Ок!

polvanovv 07.05.2019 в 09:47

MainController.php

 public function main()
    {
        $articles =[
            ['name' => 'Article 1', 'text' => 'Text of article 1'],
            ['name' => 'Article 2', 'text' => 'Text of article 2'],
        ];
        $this->view->renderHtml('main/main.php', ['articles' => $articles , 'title' => 'My blog']);
    }

    public function sayHello(string  $name)
    {
        $this->view->renderHtml('main/hello.php', ['name' => $name , 'title' => 'Welcome page']);
    }

header.php

  <meta charset="UTF-8">
    <title><?= $title ?></title>
    <link rel="stylesheet" href="/Myproject/templates/main/style.css">
ivashkevich 10.05.2019 в 13:29

Не хватает тайтла по умолчанию, пересмотрите ДЗ повнимательнее.

Dram 13.05.2019 в 20:26

К сожалению не могу продолжать делать домашку, так и не смог победить баг из прошлого урока.
У меня на странице http://localhost/hello/username

ошибка
) Fatal error: Uncaught ArgumentCountError: Too few arguments to function MyProject\Controllers\MainController::sayHello(), 0 passed in C:\OSPanel\domains\localhost\index.php on line 32 and exactly 1 expected in C:\OSPanel\domains\localhost\src\MyProject\Controllers\MainController.php on line 26

хотя все остальное работает.

ivashkevich 13.05.2019 в 23:13

Проверьте дебаггером. Теряется аргумент где-то.

ashfedor 13.06.2019 в 13:40

в header.php

<title><?= $title ?? 'Мой блог' ?></title>

в MainController.php

public function sayHello(string $name)
    {
        $this->view->renderHtml('main/hello.php', [
                'name' => $name,
                'title' => 'Приветствие пользователя' 
            ]
        );
    }

вроде все!

ivashkevich 13.06.2019 в 19:49

Отлично!

Moskva 10.07.2019 в 15:18

Сначала не понял, как требуется сделать домашку, потом подсмотрел и разобрался:)
MainController.php

public function sayHello(string $name){
        $this->view->renderHtml('main/hello.php', ['name' => $name , 'title' => 'Страница приветствия']);
    }

header.php

<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <title><?= $title ?? 'Мой блог'?></title>
    <link rel="stylesheet" href="/style.css">
</head>
<body>
<table class="layout">
    <tr>
        <td colspan="2" class="header">
            <?= $title ?? 'Мой блог'?>
        </td>
    </tr>
    <tr>
        <td>
ivashkevich 12.07.2019 в 05:31

Отлично! Подсматривать можно)

Invo 11.07.2019 в 22:45

header.php:

<head>
    <meta charset="UTF-8">
    <title>
        <?= $title ?? "Мой блог" ?>
    </title>
    <link rel="stylesheet" href="/styles.css">
</head>

MainController:

<?php

namespace MyProject\Controllers;

use MyProject\View\View;

class MainController
{
    private $view;

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

    public function main()
    {
        $articles = [
            ['name' => 'Статья 1', 'text' => 'Текст статьи 1'],
            ['name' => 'Статья 2', 'text' => 'Текст статьи 2']
        ];
        $this->view->renderHtml('main/main.php', ['articles' => $articles]);
    }

    public function sayHello(string $name)
    {
        $this->view->renderHtml('main/hello.php',['name' => $name, 'title' => 'Страница приветствия']);
    }

    public function sayBye(string $name)
    {
        echo 'Bye ' . $name;
    }
}
ivashkevich 12.07.2019 в 05:42

Отлично!

Вот тут нужно использовать одинарные кавычки.

<?= $title ?? "Мой блог" ?>
Iliusha99 20.07.2019 в 14:43

описание картинкиописание картинки
Поможете пути разобрать, а то ни как ни подключается файл styles.css

ivashkevich 20.07.2019 в 14:45

Напиши в личку

Metey 20.07.2019 в 17:20
<?php

namespace MyProject\Controllers;

use MyProject\View\View;

class MainController
{
    private $view;

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

    public function main()
    {
        $articles = [
            ['name' => 'Статья 1', 'text' => 'Текст статьи 1'],
            ['name' => 'Статья 2', 'text' => 'Текст статьи 2'],

        ];

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

    public function sayHello(string $name)
    {
        $this->view->renderHtml('main/hello.php', ['name' => $name, 'title' => 'Страница приветствия']);
    }
}

<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <title><?= $title ?? 'Мой блог' ?></title>
    <link rel="stylesheet" href="/styles.css">
</head>
<body>
...........
ivashkevich 21.07.2019 в 05:16

Отлично

Iliusha99 20.07.2019 в 20:04

Очень интересно)), особенно когда в конструкторе контролера создаем объект View где сразу же вызывается и его конструктор.

Iliusha99 20.07.2019 в 20:29
Controller:
...
public function main()
    {

        $title = [ 'title' => 'Мой блог' ];

        $articles = [
            ['name' => 'Статья 1', 'text' => 'Текст статьи 1'],
            ['name' => 'Статья 2', 'text' => 'Текст статьи 2'],
        ];

        $this->view->renderHtml('main/main.php', ['articles' => $articles, 'page_title' => $title]);
    }

    public function sayHello(string $name)
    {
        $title = [ 'title' => 'Страница приветствия' ];
        $this->view->renderHtml('main/hello.php', ['name' => $name, 'page_title' => $title]);
    }
...
========================================
header.php :
<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <title><?=$page_title['title'] ?? 'Мой блог';?></title>
    <link rel="stylesheet" href="/styles.css">
</head>
<body>

<table class="layout">
    <tr>
        <td colspan="2" class="header">
            <?=$page_title['title'] ?? 'Мой блог';?>
        </td>
    </tr>
    <tr>
        <td>
==============================
Вмешательство в View даже не потребовалось, круто)
ivashkevich 21.07.2019 в 05:18

Всё отлично, только зачем оборачивать title в ещё один массив?
$page_title['title']
Нужно, чтобы в шаблоне просто был $title

Iliusha99 21.07.2019 в 10:15

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

ivashkevich 21.07.2019 в 14:23

Что же в этом понятнее? Простая строка для заголовка страницы - первое что приходит на ум.

Iliusha99 21.07.2019 в 14:40

Тесть вы имеете ввиду что лучше передавать $title параметром по умолчанию со значением 'Мой блог'?

ivashkevich 21.07.2019 в 14:46

Нет. Передавать надо как-то так:

$this->view->renderHtml('main/hello.php', ['name' => $name, 'title' => 'Страница приветствия']);

Не нужно передавать в значение title массив. Просто строку.

Iliusha99 21.07.2019 в 14:50

Понятно, а если нам нужно как нибудь значение title поменять, для этого нам нужно переменная нет? Чтобы вручную не записать или как?

ivashkevich 21.07.2019 в 19:21

Сформулируй вопрос более понятно. Желательно с примером кода.

Iliusha99 21.07.2019 в 19:30
 public function sayHello($text){

        $this->view->renderHtml('main/hello.php',['introducing' => $text]);
    }

Здесь например, передаем через $text, и туда может тоже хотим передавать в зависимости что находится в $title.

ivashkevich 21.07.2019 в 19:32

Не вижу в примере $title.

ivashkevich 21.07.2019 в 19:35

Как я понял, вопрос в том, как передавать другие переменные в шаблон. Вот так:

    public function sayHello(string $name)
    {
        $this->view->renderHtml('main/hello.php',['name' => $name, 'title' => 'Страница приветствия']);
    }
Iliusha99 21.07.2019 в 19:42

да, но почему объезательно через строку 'Страница приветствия', почему нельзя через переменную которую можем получать ее например из функции чтобы было универсально.

ivashkevich 21.07.2019 в 19:45

Значение можно брать откуда угодно. Хоть напрямую из строки, хоть из переменной.

Iliusha99 21.07.2019 в 19:48

Понятно.

artemship 01.08.2019 в 18:05

В header.php стало так:

<title><?= $title ?? 'Мой блог' ?></title>

В MainController.php поправил экшн:

    public function sayHello(string $name)
    {
        $this->view->renderHtml(
            'main/hello.php',
            ['name' => $name, 'title' => 'Страница приветствия']
        );
    }
ivashkevich 01.08.2019 в 20:37

Отлично

khuurak 21.08.2019 в 03:55
public function sayHello(string $name)
    {
        $this->view->renderHtml('main/hello.php', ['name' => $name, 'title' => 'Страница приветствия']);
    }

<title><?= $title ?? 'Мой блог'; ?></title>
ivashkevich 22.08.2019 в 06:52

Отлично!

fosfat 30.08.2019 в 21:08

Артем, это не критика, а просто попытка новичка в php разобраться в примере. Может, я чего-то не понял:

Ты пишешь, цитата: «Если нам понадобится в другом контроллере или другом экшне добавить логику для работы с шаблонами, нам снова придется перечислять список переменных, а затем писать include с указанием полного пути для шаблона. Звучит не очень хорошо. Поэтому мы просто вынесем логику с подключением нужного шаблона в отдельный класс».

1) Если выйти за рамки учебного примера, то в реальности и не потребуется в методе «перечислять списки переменных», которые являются аналогом БД. Если брать данные из этого примера (заголовки / текст статьи, имя пользователя), то это все будет лежать в реальной БД. Соответственно, аргумент «нам снова придется перечислять список переменных» - не представляется чем-то логичным.

2) Ты пишешь, что, цитата: «нам снова придется… писать include с указанием полного пути для шаблона. Звучит не очень хорошо».

Почему не очень хорошо? Строчка include DIR . '/../../../templates/main/main.php'; КОРОЧЕ чем строчка из нового решения: $this->view->renderHtml('main/main.php', ['articles' => $articles]);

В чем здесь «оптимизация» процесса? Ведь точно также при подключении нового шаблона мы будем из раза в раз использовать эту еще более длинную строчку.

3) В целом разве можно назвать это решение целесообразным и рациональным?

Ты ведь наоборот, на мой взгляд, все усложнил. В первом простом варианте мы для подключения нового шаблона всего лишь создали бы новый метод, а теперь с предлагаемым тобой решением все то же самое плюс «сверху» новый класс с 2 методами, 1 свойством + метод-конструктор и 1 свойство в контроллере. Вопрос: зачем? И как это можно перенести в плоскость реальной разработки?

И еще момент: я сделал файловую структуру точно такую же, как у тебя в примере. При таком положении указанная тобой строчка <link rel="stylesheet" href="/styles.css"> не будет подключать файл со стилями. Даже phpstorm выделяет ее как ошибку «Cannot resolve file», т.е. работающий вариант <link rel="stylesheet" href="/www/styles.css">.

ivashkevich 31.08.2019 в 05:08

Если коротко - чем меньше ответственности у каждого класса, тем проще. Контроллер не должен знать о том, как рисовать шаблоны. Он просто начинает использовать View для этого.

ivashkevich 31.08.2019 в 05:10

А ты php-скрипты тоже с www в пути открываешь? Если да, то смотри курс для начинающих, урок про настройку OpenServer. PhpStorm может ошибаться.

Pro100Bah 05.09.2019 в 17:02

Мне кажется или мы создавали файл style.css , a не styles, в связи с этим у коллеги выше не подключаются стили.

P.S Поправьте меня, если я ошибаюсь, если нет в уроках необходимо убрать букву *****s.css) в этом уроке)

ivashkevich 05.09.2019 в 19:40

С такими проблемами на этом этапе обучения нужно разбираться самостоятельно. А в уроке всё ок.

Pro100Bah 06.09.2019 в 12:19

Сначала как начал делать домашку, подумал нужно следовать алгоритму в конце урока:
"Давайте повторим последовательность шагов, которые необходимо сделать для добавления новой странички:
-Добавляем экшн в контроллер (либо создаём ещё и новый контроллер);
-Добавляем для него роут в routes.php;
-Описываем логику внутри экшена и в конце вызываем у компонента view метод renderHtml();
-Создаём шаблон для вывода результата.
"
Но потом понял, это для создания новой странички, а мы создаем переменную для шаблона.
Результат MainController.php

namespace MyProject\Controllers;

use MyProject\View\View;

class MainController
{
    private $view;

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

    public function main()
    {
        $articles = [
            ['name' => 'Статья 1', 'text' => 'Текст статьи 1'],
            ['name' => 'Статья 2', 'text' => 'Текст статьи 2'],
        ];
        $this->view->renderHtml('main/main.php', ['articles' => $articles]);
    }

    public function sayHello(string $name)
    {
        $this->view->renderHtml('main/hello.php', ['name' => $name, 'title' => 'Страница приветствия']); //Homework 14
    }

    public function sayBye(string $name)            //Homework 13.2
    {
        echo 'Пакедова, дружище ' . $name;
    }
}

header.php

<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <title><?= $title ?? 'Мой блог'; ?></title>    <!-- Homework 14 -->
    <link rel="stylesheet" href="/styles.css">
</head>
<body>

<table class="layout">
    <tr>
        <td colspan="2" class="header">
            Мой блог
        </td>
    </tr>
    <tr>
        <td>

Правильно я понимаю, если необходимо изменить заголовок на всех страницах, то в header.php

<title><?= $title = 'Мой первый Framework' ?? 'Мой блог'; ?></title>    <!-- Homework 14 -->

т.е. задаем значение непосредственно в шаблоне хедера в переменную $title, а если необходимо изменить заголовок на других страницах, то необходимо делать обработку писать в контроллере?
Помогите учитель, мозг кипит.

P.S
Комментарием выше сам сделал ошибку, создав style.css вместо styles.css, поэтому и не работали стили у меня, все поправил. У Вас все действительно было верно в данном уроке)

ivashkevich 08.09.2019 в 09:26

Всё ок, кроме шаблона - непонятно для чего переменная там определяется переменная title.

shrineofamana 25.09.2019 в 16:37

Сделал через аргумент по умолчанию:

public function renderHtml(string $templateName, array $vars = [], string $title = 'Мой блог')

Но потом прочел коментарии и задумался. Получается, так делать не рекомендуется и это плохое решение?

ivashkevich 27.09.2019 в 17:56

Конечно, у нас ведь уже есть способ передачи переменных в шаблон.

XXX 01.10.2019 в 19:43

header.php

<title><?= $title ?? 'Мой Блог' ?></title>

MainController.php

public function sayHello(string $name)
    {
        $this->view->renderHtml('main/hello.php', ['name' => $name, 'title' =>'Страница приветствия']);
    }
ivashkevich 03.10.2019 в 00:11

Отлично

prinzplanloser0514@gmail.com 05.10.2019 в 20:53

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

prinzplanloser0514@gmail.com 05.10.2019 в 21:11
 public function renderHtml(string $templateName, array $vars = [])
    {
        extract($vars);

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

        $error='В шаблоне была ошибка!';

        echo $buffer;

    }

В строке с include немного непонятно,откуда у нас есть путь до папки с шаблонами.

Всё,этот момент разобрал,мы его даём,когда создаём обьект View, извините конечно за вопросы,но мы как-то с кошечек на такие вещи перепрыгнули,тут по 100000 вопросов в секунду возникают)

ivashkevich 05.10.2019 в 21:40

Главное не торопись. Да, этот курс я делал более сжатым и уже не разжевывал по 10 раз всё. Но и вы уже не такие балбесы как в курсе для начинающих. Учись осмысливать сжатую информацию без воды - пригодится в дальнейшем при чтении документации.

dliashchenko 25.10.2019 в 23:20

MainController.php

public function sayHello(string $name)
    {
        $this->view->renderHtml('main/hello.php', ['name' => $name, 'title' => 'Страница приветствия']);
    }

header.php

<?= $title ?? 'Мой блог';?>
ivashkevich 26.10.2019 в 07:47

Супер!

H3licoptero 15.11.2019 в 14:18

header

<title><?= $title ?? 'Мой блог' ?></title>

Controller

 public function sayHello(string $name)
    {
        $this->view->renderHtml('main/hello.php', ['name' => $name, 'title' => 'Страница приветствия']);
    }
ivashkevich 15.11.2019 в 18:48

Отлично

VpsK 03.12.2019 в 15:21

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

ivashkevich 05.12.2019 в 14:42

Что именно непонятно?

VpsK 11.12.2019 в 14:38

Уже нормально, просто по какой то причине уроки начали даваться только после двух подходов с перерывом на отдых ))) видимо особенность )))

ivashkevich 11.12.2019 в 17:41

Ну, они конечно посложнее стали, это действительно требует больше внимания и времени.

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