Oddzielenie logiki od widoku

0

Witam, chciałbym się upewnić czy poprawnie rozumiem stwierdzenie oddzielene logiki od widoku. Mianowicie, osobiście piszę w taki sposób

$stmt=$this->db->prepare('SELECT * FROM produkty ORDER BY id DESC');
		$stmt->execute();
		foreach($stmt as $row)
		{
			echo "<br><font color=\"#2D8C5F\"><td><b>".$row['produkt']."</b><br></td></font>";
			echo "Promocja:<font color=\"red\"><td><b>".$row['promocja']."</b></td></font><br>";
			echo 'ilosc: ';
			echo "<b>".$row['ilosc']."<br></b>";
			echo "Cena: ";
			echo $row['cena']." zł<br>";
			echo $row['rodzaj']."<br>";
			echo "Dodany: ";
			echo $row['data']."<br>";
			echo "<td>
				<a href=\"delete.php?id={$row['id']}\"><b>Usun</b></a><br> 
				<a href=\"editpro.php?id={$row['id']}\"><b>Edytuj</b></a>
			</td>"; 
}

Po czym funkcję przenoszę obiektowo do pliku widoku. Nie wiem czy dobrze robię dodając przy wywołaniu divy do niektórych wartości wyciągniętych z bazy. Lecz co jeśli chcemy nadać akurat tej wartości konkretny margin ?

0

Dodam jeszcze że powyższy kod jest w pliku gdzie posiadam wszystkie funkcję, które przenosze do warstwy widoku odwołując się do konkretnej klasy, nie ma tam nic z HTMLa. Czyli moje pliki widoku wyglądają mniej tak

HTML
			<?php startblock('dodaj_produkt') ?>
<?$klasa->funkcja();?>
			<?php endblock() ?>

HTML
0

Przecież w Twoim kodzie masz logikę tuż obok widoku.
To, że wrzucisz wszystko do klasy nic nie zmienia.

Widok nie powinien w ogóle wiedzieć skąd wczytywane są dane - on tylko je wyświetla.

0

A jakby to miało wyglądać gdyby rozdzielić te warstwy ?

0

Aaaa może byś tak poczytał w internecie na czym w ogóle polega model MVC/MVVP, a nie od razu leciał z tym na forum?
Nie widzę sensu w pisaniu całego artykułu na ten temat, skoro wartościowe materiały masz na wyciągnięcie palców.

0

Wykorzystaj twiga.

0

Ja bym to zrobił tak

 $stmt=$this->db->prepare('SELECT * FROM produkty ORDER BY id DESC');
$widok = new views;
        $stmt->execute();
        foreach($stmt as $row)
        {
          $widok->rysuj_opcje($row['produkt'],$row['promocja'].$row['ilosc'],$row['rodzaj'],$row['data'],$row['id'],$row['id']);
          
}

//kod funckji rysuj_opcje
//przykładowo nazwałem te zmienne od a do h
public function rysuj_opcje($a,$b,$c,$d,$e,$f,$g,$h) {
print ("  echo "<br><font color=\"#2D8C5F\"><td><b>".$a."</b><br></td></font>";
            echo "Promocja:<font color=\"red\"><td><b>".$b."</b></td></font><br>";
            echo 'ilosc: ';
            echo "<b>".$c."<br></b>";
            echo "Cena: ";
            echo $d." zł<br>";
            echo $e."<br>";
            echo "Dodany: ";
            echo $f."<br>";
            echo "<td>
                <a href=\"delete.php?id={$g}\"><b>Usun</b></a><br> 
                <a href=\"editpro.php?id={$h}\"><b>Edytuj</b></a>
            </td>"; ");
}


 
0

Jest sens zmieniać kod z tematu na kod który podpowiedział pol90? czy wyjdzie na to samo ?

0

Do ogarnięcia tematu polecam zobaczyć jak to się dzieje w jakimś prostym fw. (np. larva, yii2, slim)

0

Z ciekawości zapytam, z tych dwóch metod, która jest lepsza?

Wiadomo, laravel albo yii mają już wbudowane systemy szablonów.

0

Żadna.
System szablonów jest jedyną sensowną opcją.

Nigdy nie mieszaj kodu PHP oraz HTML bez wykorzystania jakiegoś sensownego systemu szablonów - w innym wypadku bardzo łatwo można stracić pojęcie, co się w ogóle dzieje w kodzie.

1

Witam, chciałbym się upewnić czy poprawnie rozumiem stwierdzenie oddzielene logiki od widoku.

Weź parę zleceń na freelance, wykonaj je a potem zacznij robić poprawki od marudnego klienta - to zobaczysz wtedy po co jest potrzebne oddzielenie warstw (choćby logiki od widoku).

  • "Dobrze, dane są okej, ale chciałbym wyświetlać je na różowo w zielonej ramce."
  • "Wygląd jest okej, ale chciałbym, żeby zamiast jednej tabelki były dwie tabelki, które wyświetlałyby dane z dwóch różnych magazynów (i z dwóch różnych baz danych)."
  • "Chciałbym, żeby te same dane wyświetlały się na trzy sposoby - raz w wynikach wyszukiwania produktów, jako ikony + cena, drugi raz widok szczegółowy produktu, trzeci raz w koszyku jako pozycja w tabeli"

jeśli masz wszystko ładnie oddzielone (dane od widoku, choćby na bardzo podstawowym poziomie podziału) to po prostu masz jeden moduł do ładowania danych i masz kilka widoków, które karmisz tymi danymi (albo odwrotnie - jeden widok, który może przyjmować dane z różnych źródeł).

Jeśli nie masz kodu podzielonego w sensowny sposób (a pierwszy twój przykład wcale nie jest nijak podzielony - mieszasz w jednym kotle odwoływanie się do bazy danych z wyświetlaniem tychże danych w HTML) to kod staje się strasznie nieelastyczny. Wtedy niespodziewane wymaganie biznesowe będzie wymagało albo dużej modyfikacji kodu, albo pójście na skróty (np. programowanie za pomocą kopiuj-wklej, co może być skuteczne na krótką metę, ale na dłuższą metę sprawi, że będziesz miał z 10 razy więcej kodu do utrzymania - bo każde kolejne wymaganie biznesowe, to kolejna kopiuj wklejka).

Generalnie powinno się tak programować, żeby jeden moduł robił jedną rzecz - jeśli pobiera dane, to już nie wyświetla. To się nazywa Single responsibility principle. Chodzi o to, żeby był tylko jeden powód do modyfikacji danego modułu (czyli np. zmiana sposobu wyświetlania, zmiana sposobu wczytywania danych itp. ). Wtedy jeśli np. zmieniasz widok, a nie zmieniasz danych to w ogóle nie ruszasz pliku odpowiedzialnego za pobieranie danych. Moduły są niezależne, jak klocki Lego i łączysz je ze sobą. W twoim przykładzie niestety się to miesza ze sobą wszystko, więc nie oddzielisz łatwo jednej rzeczy od drugiej.

1

W bardzo dużym uproszczeniu:

View.php

<?php

class View
{
    private $file;
    private $data;

    public static function factory($file, array $data)
    {
        return new View($file, $data);
    }

    public function __construct($file, array $data)
    {
        $this->file = $file;
        $this->data = $data;
    }

    public function render()
    {
        extract($this->data);
        ob_start();
        include $this->file;
        return ob_get_clean();
    }

    public function __toString()
    {
        return $this->render();
    }

}

szablon base.php

<html>
    <head>
        <meta charset="utf-8" />
    </head>
    <body>
        <?php if (isset($content)) echo $content; ?>
    </body>
</html>

szablon content.php

        <dl>
            <dt>Firstname</dt>
            <dd><?= $user->firstname ?></dd>
            <dt>Lastname</dt>
            <dd><?= $user->lastname ?></dd>
            <dt>Age</dt>
            <dd><?= $user->age ?></dd>
        </dl>

no i index.php

<?php
define('DOCROOT', realpath(dirname(__FILE__)).DIRECTORY_SEPARATOR);

spl_autoload_extensions('.php');
spl_autoload_register();

$user = new stdClass;
$user->firstname = 'John';
$user->lastname  = 'Doe';
$user->age       = 40;

$content = View::factory(DOCROOT . 'content.php', array('user'    => $user));
$base    = View::factory(DOCROOT . 'base.php',    array('content' => $content));

echo $base;

Przyjrzyjcie się dokładnie i spróbujcie załapać o co tutaj chodzi. We frameworkach rzecz jasna jest to profesjonalne ale i bardziej skomplikowane. A szablony Blade, Mustache czy tam Twig to trochę inna bajka.

1 użytkowników online, w tym zalogowanych: 0, gości: 1