Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Diskuze: Konzultace - pole a OOP

Aktivity
Avatar
Tomáš Dvořák:27.2.2018 22:41

Ahoj, generuji PDF pro tisk kódů na tiskárnu lepících štítku a chci to vytvořit přes OOP a rád bych poprosil o poznatky ohledně kódu níže. Určitě tam budou věci, které nejsou dobře a rád si vyslechnu co tam je špatně. Nyní to chodí dle představy, ale například u pole mám velké mezery.

soubor s polem a generováním do PDF:

include('MPDF57/mpdf.php'); // knihovna mPDF
require_once 'TiskKodu.php';

$tiskkodu = new TiskKodu('','');
$pole = [];
$pole[] = '16561-1-5';
$pole[] = 'asda5s5464-2-2';
$pole[] = 'asvsdvd4-2-8';

foreach ($pole as $klic => $hodnota)
{
    $hodnoty = explode('-', $hodnota);
    $tiskkodu->pridejStitek($hodnoty[0],$hodnoty[1],$hodnoty[2]);
}

$tiskkodu->tisk();
$tisk = mb_convert_encoding($tiskkodu, 'UTF-8', 'UTF-8');

$pdf = new mPDF('utf-8', array(100,128), '','',0,0,2,0,0,0);
$pdf->WriteHTML($tisk);
$content = $pdf->Output('');
file_put_contents("temp/a.pdf",$content);

a třída TiskKodu.php:

<?php
    class TiskKodu {
        protected $tisk = '';
        protected $stitek = '';

        public function __construct($tisk, $stitek) {
            $this->tisk = $tisk;
            $this->stitek = $stitek;
        }

        function pridejStitek($kod,$pocet_sloupcu,$opakovani) {
            for($i=0;$i<$opakovani;$i++){
                if($pocet_sloupcu==1){
                    $this->stitek .= "<div class=\"column\">".$kod."</div>";
                }
                else{
                    $this->stitek .= "<div class=\"column-left\">".$kod."</div>";
                    $this->stitek .= "<div class=\"column-right\">".$kod."</div>";
                }
            }
        }

        function getStitek() {
            return $this->stitek;
        }

        function getTisk() {
            return $this->tisk;
        }

        function tisk() {
            $this->tisk = "
            <html>
            <head>
            <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />
            <style type=\"text/css\">
              .column-left{ font-size: 22px; text-align:center; float: left; width: 51%; border-bottom: 1px dotted black; padding-left:0px; padding-top: 7px; padding-bottom: 6px;}
              .column-right{ font-size: 22px; text-align:center; float: right; width: 48%; border-bottom: 1px dotted black; padding-left:0px; padding-top: 7px;  padding-bottom: 6px;border-left: 1px dotted black;}
              .column{ font-size: 22px; text-align:center; width: 100%; border-bottom: 1px dotted black; padding-left:0px; padding-top: 7px;  padding-bottom: 6px;}
            </style>
            </head>
            <body>
            <div class=\"wrap\">
            ".$this->stitek."
            </div>
            </body>
            </html>";
        }
        function __toString() {
            return $this->tisk;
        }
    }

Díky moc.

 
Odpovědět
27.2.2018 22:41
Avatar
Odpovídá na Tomáš Dvořák
Martin Konečný (pavelco1998):27.2.2018 23:47

Ahoj,

určitě by bylo hodně možných návrhu k řešení, nicméně když bych to řešil puntíčkářsky:

Ta třída TiskKodu je spíš jen taková šablona pro tu stránku, podle toho názvu bych spíš očekával, že ta třída reálně něco tiskne. Tedy bych ji trochu přejmenoval, třeba PdfSablona.

Samotné HTML bych pak generoval až v jedné metodě, která by to generování měla na starost. Takhle tam máš dvě metody, které dělají vlastně to samé (přidávají nějaký HTML kód). Tedy bych upravil metody pridejStitek() a tisk() tak, aby:

  1. metoda pridejStitek() negenerovala HTML, ale uložila si informace o tom novém štítku, třeba
private $stitky = array();

public function pridejStitek($kod, $pocetSloupcu, $opakovani)
{
        $this->stitky[] = array("kod" => $kod, "pocetSloupcu" => $pocetSloupcu, "opakovani" => $opakovani);
}

a v podstatě to, co generuješ v té metodě, vygeneruješ až v té metodě tisk().

public function tisk()
{
        $html = "nějaký začátek";  // to samé, co je aktuálně v té metodě jako  $this->tisk = "..."

        foreach ($this->stitky as $stitek) {
                // zde bude to generování, co aktuálně máš v metodě pridejStitek()
        }

        $html .= "nějaký konec";

        return $html;
}
  1. metoda tisk() je v tomhle stavu taková podle mě trošku nesmyslná, jelikož ji explicitně musíš zavolat, aby něco přiřadila do atributu objektu. Buď by ta metoda byla jen taková pomocná, byla by private a volala by si ji sama třída, nebo tak, jak popisuji v bodě č. 1), že bude generovat celé HTML a bude jej vracet.

Metodu __toString() pak upravíš jednoduše tak, že si v ní vygeneruješ to HTML a vypíšeš

public function __toString()
{
        $html = $this->tisk();

        return $html;
}

Ten konstruktor se mi takto zdá zbytečný, jelikož dle kódu bys tam leda tak dával rovnou nějaké HTML, což nechceš. Do třídy si předávej data a HTML si nech generovat. Tedy když bys chtěl, můžeš si tam pro příklad zadat třeba nějaké nastavení pro tu šablonu (třeba barvu textu atd.,).
Když už jsme u toho nastavení, mohlo by tam být i třeba nastavení kódování, které ručně nastavuješ mimo tu třídu řádkem

$tisk = mb_convert_encoding($tiskkodu, 'UTF-8', 'UTF-8');

To bys klidně mohl mít řešené už v té třídě, které předáš "UTF-8" jako parametr.

Pokud bych chtěl jít ještě do větších detailů, tak by sis mohl pro ty štítky udělat vlastní objekt, protože dle mého návrhu vidíš, že do pole $stitky přidávám další pole, které má nějaké konkrétní prvky, což pomalu zavání nějakou strukturou. Tedy bys klidně mohl zjednodušeně mít

class Stitek
{

        private $kod;
        private $opakovani;
        private $pocetSloupcu;

        public function __construct($kod, $opakovani, $pocetSloupcu)
        {
                // přirazení do atributů
        }

}

a v PdfSablona (TiskKodu) bys jednoduše měl

public function pridejStitek($kod, $opakovani, $pocetSloupcu)
{
        $this->stitky[] = new Stitek($kod, $opakovani, $pocetSloupcu);
}

ve třídě Stitek by sis pak přidal nějaké gettery, abys mohl ty atributy $kod, $opakovani a $pocetSloupcu nějak použít.

Když budu ještě víc důsledný, tak coding standards v PHP říkají, že názvy funkcí a proměnných by měly být notací camelCase, tedy např. $pocetSloupcu, ne $pocet_sloupcu.

Tedy pro příklad by ten příklad mohl vypadat třeba takto: https://pastebin.com/nUwhjT4L

Určitě bude řada jiných možných návrhů, jiných možných detailů atd., třeba někdo napíše svůj názor :)

Akceptované řešení
+20 Zkušeností
+2,50 Kč
Řešení problému
Nahoru Odpovědět
27.2.2018 23:47
Aktuálně připravuji browser RPG, FB stránka - https://www.facebook.com/AlteiraCZ
Avatar
Tomáš Dvořák:28.2.2018 15:08

Funguje to, děkuji za učesání, určitě si to vezmu k srdci ;)

Jen tne mb_convert_encoding musím dát až do volání metody WriteHTML, jinak to nejede a mpdf hlásí chybu kódování.

 
Nahoru Odpovědět
28.2.2018 15:08
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 3 zpráv z 3.