N
N
Nick2021-07-20 14:16:14
PHP
Nick, 2021-07-20 14:16:14

Why doesn't the code in the php guestbook task work?


1. The persons table in the phpMyAdmin open server "test" database, the working database was checked, there is a connection, the data is displayed separately:
60f6ae3b6bb5b160112543.jpeg
2. code in php files in the open server folder:

index.php:

<?php
require __DIR__ . '/classes/GuestBook.php';
require __DIR__ . '/classes/View.php';
$dsn = 'mysql:host=127.0.0.1;dbname=test';
$dbh = new PDO ($dsn, 'root', '');
$sth = $dbh->prepare('SELECT * FROM persons');
$sth->execute();
$data = $sth->fetchAll();
$view = new View();
$view->assign('persons', $data);
$view->display(__DIR__ . '/templates/index.php');



Templates folder:


index.php:

<!doctype html>
<html lang="ru">
<head>
<title>Гостевая книга</title>
<style>
article {
margin-bottom: 15px;
paddi ng: 1Opx;
border: lpx dotted #008000;
}
</style>
</head>
<body>
<h1>Персонал:</hl>
<hr>
<?php foreach ($persons as $person) { ?>
<ul>
<li><?php echo $person ['lastName'] ; ?></li>
<li><?php echo $person ['firsName']; ?></li> </ul>
<?php } ?>
</body>
</html>

guestBookRecord.php:

<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<article>
    <p><?php echo $this->getMessage(); ?></p>
    <?php if (!empty($this->getAuthor())) { ?>
        <p style="text-align: right"><?php echo $this->getAuthor(); ?></p>
    <?php } ?>
    <hr>
</article>
</body>
</html>



Folder with classes classes:


GuestBookRecord.php:

<?php

class GuestBookRecord
{
    protected $author;
    protected $message;

    public function __construct($message, $author = null)
    {
        $this->author = $author;
        $this->message = $message;
    }

    public function getMessage()
    {
        return $this->message;
    }

    public function getAuthor()
    {
        return $this->author;
    }

    public function render()
    {
        ob_start();
        include __DIR__ . '/../templates/guestBookRecord.php';
        $content = ob_get_contents();
        ob_end_clean();

        return $content;
    }
}

GuestBook.php:

<?php

require_once __DIR__ . '/GuestBookRecord.php';

class GuestBook
{
    protected $data;

    public function __construct($file)
    {
        $lines  = file($file, FILE_IGNORE_NEW_LINES);
        $this->data = [];
        foreach ($lines as $line)
        {
            $this->data[] = new GuestBookRecord($line, 'Есенин');
        }
    }

    public function getRecords()
    {
        return $this->data;
    }

    public function add(GuestBookRecord $record)
    {
        $this->data[] = $record;
    }
}


/*require_once __DIR__ . '/TextFile.php';

class GuestBook extends TextFile
{
    public function __construct($path)
    {
        $this->path = $path;
        $this->data = file($this->path, FILE_IGNORE_NEW_LINES);
    }
}*/

View.php:

class View
{
    protected $data;

    public function __construct()
    {
    }

    public function assign(string $name, $value)
    {
        $this->data = [];
        $this->data[$name] = $value;

        //file_put_contents($this->path, implode("\n", $this->data));
    }

    public function display(string $template)
    {
        echo $this->render($template);
    }

    public function render(string $template)
    {
        ob_start();
        include $template;
        $content = ob_get_contents();
        ob_end_clean();

        return $content;

//        include __DIR__ . '/../templates/guestBookRecord.php';
//        $content = ob_get_contents();
//        ob_end_clean();
//
//        return $content;
    }
}



The browser gives the following error:
60f6b00c10bed972733283.jpeg

The result should be something like this:
Personnel:
• Ivanov
• Ivan
• Petrov
• Peter
• Sidorova
• Ekaterina

I am a beginner, so please do not judge strictly.
Thank you in advance for your response.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
A
Alexey Hog, 2021-07-20
@Enlightened1

The render() method in the View class does not work as you would expect.
When you include a template, in this case only $this is available there, and $this is the View object itself.
Therefore, you can get an array of persons only through $this->data['persons'] and naturally there is no $persons there.
those. the template will only work like this

//...
foreach ($this->data['persons'] as $person) {
  echo $person['lastName'];
//  ...
}

Do you understand?
In order to have access to the $persons variable in the template, you need to import it in the render() method using the extract() function or by assigning a variable to a variable
public function render(string $template) 
{
  ob_start();
  // функция импорта
  extract($this->data, EXTR_OVERWRITE);
  include $template;
  $content = ob_get_contents();
  ob_end_clean();

  return $content;
}

Or through variable variables
public function render(string $template) 
{
  ob_start();
  // Импорт
  foreach($this->data as $key => $value) {
   // Переменные переменных $$
    $$key = $value;
  }
  include $template;
  $content = ob_get_contents();
  ob_end_clean();

  return $content;
}

In both cases, the result is the same.
And then in the template you can already work directly with $persons

T
ThunderCat, 2021-07-20
@ThunderCat

In order:

The browser gives the following error:
Firstly, not a browser, but a server, and the browser only displays it. Secondly, this is a notice and a warning, not an error.
Further, if yours works correctly, then there is nothing in the index BEFORE this place on the date. Which is easy to check with var_dump. And if it's not empty - something in your view works crookedly, or not as you expect, read the documentation for this method. $view->assign('persons', $data);

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question