Autor Zpráva
kachnak
Profil
Zdravím,
Doteraz som mal pocit, že php ovládam "dosť dobre", (používal som funkcie a vedel som naprogramovať všetko čo som len potreboval aby to fungovalo), a romýšlal som, že by som sa tým možno chcel živiť.
Lenže ako som zistil doteraz som písal jednoduchý ale špinavý kód.
Týmto spôsobom som si vytvoril som si vlastné fórum aj eshop. Všetko fungovalo a bol som spokojný.
Používal som len globálne premnné.
Lenže som zistil, že v PHP existujú "nejaké" classy, objektové programovanie, mvc model a rôzne ďalšie zápisy typu
  echo $obj->foo;
  $className::run(); 
s ktorými som sa doteraz nestretol.
Nenašiel som na nete žiadne vysvetlenie načo vôbec classy existujú.
Načo a ako sa používa private public protected atd.
Či to slúži ako nejaká ochrana pred hackermi atd.

Našiel som nejaké príručky najlepšie na
http://php.net/manual/en/language.oop5.php
lenže nejak mi to aj tak neni jasné.
Nieje to tu niekde na fóre lepšie vysvetlené? Možno to len neviem nájsť.
vďaka

príklad kódu aký píšem pre kontaktny formular:

PRE PHP VYKONAVACIU CAST HORE NAD HTML KODOM
<?php
    if(isset($_POST[kontaktpotvrdit]))
    {      
      $kontaktname=text_input($kontaktname);
      $kontaktmail=text_input($kontaktmail);
      $kontaktpredmet=text_input($kontaktpredmet);
      $kontakttext=text_input($kontakttext);      
      $kontaktmail=strtolower($kontaktmail);
      $kontaktmail=str_replace(" ", "",$kontaktmail);
        if(($kontaktmail=="") || ($kontaktpredmet=="") || ($kontakttext=="") || ($kontaktname==""))
        {
                $hlaseniekontakt="Nezadali ste";
            if($kontaktname=="")$hlaseniekontakt="$hlaseniekontakt Meno, ";                
                if($kontaktmail=="")$hlaseniekontakt="$hlaseniekontakt Email, ";
                if($kontaktpredmet=="")$hlaseniekontakt="$hlaseniekontakt Predmet, ";
                if($kontakttext=="")$hlaseniekontakt="$hlaseniekontakt Text správy";
      }
      else
      {
           $kontrolamail=0;    
           $bufx=kontrola_mail($kontaktmail);
             if($bufx=="fail")
               $hlaseniekontakt="Zadaný email $kontaktmail má nesprávny tvar.";
           else
           {              
              $kontaktmail=$bufx;
              if($capture<>"")
              $hlaseniekontakt="Políčko antispamovej kontroly musí byť prázdne.";                            
              else
              {
                $odosielatel_meno="$kontaktname";
                    $odosielatel_mail="$kontaktmail";
                        $prijmatel_mail="info@stranka.net";
                        $mail_text="Správa z portálu Stranka.net                
                 
Meno: $kontaktname
Email: $kontaktmail
Predmet: $kontaktpredmet                                                                                                        

Text správy: $kontakttext                                                                                                       
";
                        $mail_predmet="$kontaktpredmet";
                        $mail_predmet = "=?utf-8?B?" . base64_encode($mail_predmet) . "?=";
                $headers .= "From: ". $odosielatel_meno . " <" . $odosielatel_mail . ">\r\n";
                $headers .= "Content-Type: text/plain; charset=utf-8\n";
                mail($prijmatel_mail, $mail_predmet, $mail_text, $headers);                           
                $hlaseniekontakt="Správa bola úspešne odoslaná.<br/>Odpoveď vám príde na email: $kontaktmail";
                header("Location: index.php?obsah=kontakt&hlaseniekontakt=$hlaseniekontakt");
                
                $kontaktname="";
                $kontaktmail="";
                $kontaktpredmet="";
                $kontakttext="";
              }  
           }
      }
    }
?>


PRE ZOBRAZENIE NA STRANKE
<?php
      $query=mysql_query("SELECT id FROM capture order by id DESC");
      list($id)=mysql_fetch_row($query);
      $captureid=rand(1,$id);
      $query=mysql_query("SELECT question FROM capture WHERE id='$captureid' ");
      list($question)=mysql_fetch_row($query);
            
      echo"<div id=\"nadpis\" class=\"main_nadpis\">Kontaktný Formulár</div>      
      <div class=\"main_line\"></div>";    
      if($hlaseniekontakt!="") echo"<div class=\"in_hlasenie\">$hlaseniekontakt</div>";      
      echo"<div class=\"in\">      
      <form action=\"index.php?obsah=kontakt#nadpis\" method=\"post\">                  
      <div class=\"form_popis\"><span class=\"red\">*</span> <span class=\"b\">Meno:</span></div>
      <div class=\"in_input\">
        <div class=\"input_left\"></div>
        <div class=\"input_middle\">       
        <input class=\"input_text\" type=\"text\" maxlength=\"100\" name=\"kontaktname\" ";
      if($meno_L!="") echo"value=\"$meno_L $priezvisko_L\"";
      else
      {
        if($kontaktname!="")
        echo"value=\"$kontaktname\"";
      }               
      echo"/>
        </div>
        <div class=\"input_right\"></div>
      </div>                  
      <div class=\"form_popis\"><span class=\"red\">*</span> <span class=\"b\">Email:</span> (na tento email vám príde odpoveď)</div>
      <div class=\"in_input\">
        <div class=\"input_left\"></div>
        <div class=\"input_middle\">      
        <input class=\"input_text\" type=\"text\" maxlength=\"100\" name=\"kontaktmail\" ";
      if(($mail_L!="")&&($kontaktmail==""))
      $kontaktmail="$mail_L";
      if($kontaktmail!="")
      echo"value=\"$kontaktmail\"";
      echo"/>
        </div>
        <div class=\"input_right\"></div>
      </div>      
      <div class=\"form_popis\"><span class=\"red\">*</span> <span class=\"b\">Predmet:</span></div>
      <div class=\"in_input\">
        <div class=\"input_left\"></div>
        <div class=\"input_middle\">      
      <input class=\"input_text\" type=\"text\" maxlength=\"100\" name=\"kontaktpredmet\" ";
      if($kontaktpredmet!="") echo"value=\"$kontaktpredmet\"";
      echo"/>
        </div>
        <div class=\"input_right\"></div>
      </div>                  
      <div class=\"form_popis\"><span class=\"red\">*</span> <span class=\"b\">Text Správy:</span></div>
      <div class=\"form_textarea_top\"></div>
      <div class=\"form_textarea_mid\"><textarea id=\"kontakttext\" name=\"kontakttext\" class=\"form_textarea\">";                  
      if($kontakttext!="") echo"$kontakttext";
      echo"</textarea></div>     
      <div class=\"form_textarea_bot\"></div>
      
      <div class=\"form_popis\"><span class=\"red\">*</span> <span class=\"b\">Antispam: (nevyplňovať)</span></div>
      <div class=\"in_input\">
        <div class=\"input_left\"></div>
        <div class=\"input_middle\">      
      <input class=\"input_text\" type=\"text\" maxlength=\"100\" name=\"capture\" ";
      if($capture!="") echo"value=\"$capture\"";
      echo"/>
        </div>
        <div class=\"input_right\"></div>
      </div>                  
      <input type=\"hidden\" name=\"captureid\" value=\"$captureid\"/>           
      <div class=\"form_sub\"><input type=\"submit\" name=\"kontaktpotvrdit\" value=\"Odoslať Správu\"/></div>        
      </form></div>";
?>
Sir Tom
Profil
kachnak:
Také zdravím,

programování existuje procedurální (to ses patrně naučil) a dále i objektově orientované. Objektově orientované je OOP. Zkus si na webu najít něco o tomto OOP stylu programování. Je to jiný pohled na programování. Na google je spousta odkazů na OOP PHP. Já nicméně doporučuji si koupit knížku Rudolfa Pecinovského o OOP. Tam se dozvíš myšlenku OOP. Nicméně Rudolf Pecinovský používá k příkladům svůj oblíbený programovací jazyk JAVA, tak jestli ti nebude vadit, že příklady jsou v jiném jazyce než PHP, tak jsi tu knížku opravdu kup a dozvíš se tam alespoň ten styl OOP. PHP a JAVA jsou skoro úplně stejné... Veř mi, že když umíš syntaxi PHP, tak se i rychle naučíš syntaxi jazyka JAVA.
Tori
Profil
Je to odlišný přístup. Funkce se soustředí na činnost. Říkáte, co se bude dít a předáte jí upřesňující parametry kde a jak ta činnost má proběhnout a co při ní použije. Chci třeba, aby někdo pověsil ten obraz, tak tři metry od okna a do výšky hlavy:
function zavesObrazekNaStenu($obraz, $x, $y) {
    if ($GLOBALS['mameDomaKladivo'] === false || $GLOBALS['mameDomaHrebiky'] === false) {
        $GLOBALS['chyba'] = 'nemáme kladivo a/nebo hřebiky';
        return false;
    }
    if (!zatlucHrebikDoZdi($x, $y)) {
        $GLOBALS['chyba'] = 'neumím zatlouct hřebík';
        return false;
    }
    zmenPolohu($obraz, $x, $y);
    return true;
}
// volám:
$chyba = '';
if (!zavesObrazekNaStenu('ten Picasso po babičce', 3, 2))
    echo 'Nepodařilo se pověsit obrázek, protože: ' . $chyba;
else 
    echo 'Už visí!';

Kdežto v OOP se soustředíte ...no, na objekty. :) Objekt je zároveň věc, její vlastnosti, činnosti které může provádět a způsoby, jakými se může měnit. Takze budu mít objekty Člověk, Obraz, Kladivo, Hřebík (Zeď vynechávám). Řeknu:
try {   // očekávám, že to bude bez problémů, ...

    $clovek = new Clovek();
    $obraz = new Obraz('ten Chagall támhle v koutě');
    $clovek->povesObraz($obraz, 3, 2);
    echo 'Už visí';

} catch (Exception $e) {  // ... ale kdyby došlo k nějaké výjimečné situaci, tady ji zachytím a můžu na ni nějak reagovat
    echo 'Nepodařilo se pověsit obrázek, protože: ' . $e->getMessage(); 
}
Hned vidíte, že navenek nemusím upřesňovat, jakým způsobem se má ta akce provést. To už je starost toho člověka (tj. vnitřní implementace třídy), jak si s tím úkolem umí poradit. Může to vypadat takhle:

class Clovek {

    public function povesObraz($obraz, $x, $y) {
        if (!$this->chceSeMiNecoDelat()) {
            throw new Exception('Teď mam strašně moc práce, .. pověsíme to zejtra, jo?');
    }
    
    private function chceSeMiNecoDelat() {
        return false;
    }
}
- anebo takhle:

class Clovek {

    public function povesObraz($obraz, $x, $y) {
        $kladivo = null;
        if (Skrin::obsahuje('kladivo'))
            $kladivo = new Kladivo;
        else {
            foreach (Dum::$obyvatele as $soused) {
                if ($soused->jeDoma() && $soused->maNaradi('kladivo')) {
                    $kladivo = $soused->pujcitNaradi('kladivo');
                    break;
                }
            }
            if (!$kladivo)
                throw new Exception('Nemáme doma kladivo a u sousedů jsem nesehnal/a');
        }
        $this->zatlucHrebik($kladivo, $x, $y); // tady nic neověřuju, pokud nemáme hřebíky, vyhodí výjimku volaná metoda
        $obraz->x = $x;
        $obraz->y = $y;
        if ($kladivo->vlastnik->jmeno !== $this->jmeno)
            $this->vratitVec($kladivo);
    }
}
V tom prvním případě nemůžu vědět, jestli fakt má práci nebo se vymlouvá, protože nevím že má nějakou metodu chceSeMi() (je soukromá, a do hlavy nikomu cizímu nevidíš, jen sobě), a nevidím ani, jak je udělaná metoda povesObraz().

Zacházení s chybami je v OOP odlišné - nemusím ověřovat jestli návratová hodnota není FALSE/NULL. Resp. metoda vrací FALSE jen pokud je to očekávaná hodnota (třeba jestli soused má/nemá kladivo), ale v případě neočekávané (tj. výjimečné) chyby by měla metoda vyhazovat výjimku (třeba kdyby soused byl doma a měl kladivo, ale nechtěl by ho půjčit). Od toho místa výjimka probublá na nejbližší úroveň, kde najde try-catch blok. To je jedna z podstatných věcí v OOP - objekty jsou v nějaké hierarchii, každý se stará jen u určitou věc. Pokud si s něčím neumí poradit, vyhodí výjimku a nechá to vyřešit nadřízeného. Tzn. když děcko neví, co dělat, když doma nemáme kladivo a u sousedů nepořídilo, tak předá rozhodování mně (jestli zatlouct sama jiným předmětem, říct někomu jinému, nebo koupit kladivo a zavolat dítě, ať to zkusí (= try) udělat znova).


Nicméně bez ohledu na to, jestli budete psát procedurálně nebo objektově, jsou věci společné pro oba přístupy, které byste měl zlepšit, hlavně co se týká čitelnosti kódu: jednotné odsazování bloků, řetězce psát jako řetězce (a ne nedefinované konstanty, viz hned druhý řádek). Místo $promenna = $promenna . ' neco'; použít $promenna .= ' neco'; (ř.12-16). Používat čitelné názvy proměnných (třeba místo všech $kontakt<něco> použít pro údaje z formuláře pole). Použít nějaké šablony a tím oddělit HTML od PHP taky pomůže (pro začátek to klidně můžou být ty řádky odtud, vystrčené do samostatného souboru a upravené, aby četly data jen z jednoho pole (třeba $templateData). Pak můžete nasypat data do pole a zavolat include './sablony/kontaktniFormular.php';).
kachnak
Profil
Zdravím, no študujem tú knižku o jave a objektovom programovaní od pána Pecinovského.
Tam si posúvam štvorček po obrazovke a je mi jasné že ten štvorček je objekt a dávam mu príkazy.
ale neviem si to predstaviť v PHP že čo by tam mal byť ten objekt.
Napríklad som vyrobil veľmi jednoduchú knihu návštev. Ukladajú sa tam texty do databázy a čítajú sa z databázy.

Vedel by mi niekto na tomto jednoduchom príklade ukázať aby to malo byť zapísané objektovo alebo s triedami? Lebo mám pocit že nič jednoduchšie a prehladnejšie ako som napísal ja, už nemôže byť.
Ukážte mi Prosím niekto kde tu je v knihe návštev nejaký objekt a ako by to mohlo byť zapísané ináč.
Na tomto vašom prepise sa to naučím najlepšie a pochopím to konečne.
Vďaka.

testovacia stránka: http://kachnak.euroscene.net

<?php     
  header('Content-Type: text/html; charset=utf-8');
  $spojenie=mysql_connect("db50.***.net", "name", "pass");mysql_select_db("databaza");  
  //pouzivam include"functions.php";
  //pre jednoduchsiu ukazku vysledok includu je tu:
  function nahrad_smajlikov($text)
  {             
    $text=" $text ";
    $text=str_replace(" :D ", " <img src=\"smiles/1.gif\"> ",$text);
    $text=str_replace(" :-D ", " <img src=\"smiles/1.gif\"> ",$text);
    $text=str_replace(" :) ", " <img src=\"smiles/19.gif\"> ",$text);
    $text=str_replace(" :-) ", " <img src=\"smiles/19.gif\"> ",$text);
    $text=str_replace(" :( ", " <img src=\"smiles/6.gif\"> ",$text);
    $text=str_replace(" :-( ", " <img src=\"smiles/6.gif\"> ",$text);
    return $text;
  }
  function text_input($text)
  {    
    $text=str_replace("&","&amp;",$text);
    $text=str_replace("<","&lt;",$text);
    $text=str_replace(">","&gt;",$text);      
    $text=str_replace("'","'",$text);
    $text=str_replace("\"","&quot;",$text);
    $text=str_replace("˜","&tilde;",$text);
    $text=trim($text);      
    return $text;       
  }  
  //pouzivam include"kniha_navstev_php.php";
  //pre jednoduchsiu ukazku vysledok includu je tu:
  if(isset($_POST['send']))
  {
    $nick=text_input($_POST['nick']);
    $text=text_input($_POST['text']);    
    if($nick=="" || $text=="")
    $hlasenie="Nezadali ste Nick alebo Text.";
    else
    {
      $time=date("d.m.Y (H:i)");
      $query_insert=mysql_query("INSERT INTO kniha_navstev 
      SET nick='$nick' , text='$text' , time='$time' ");  
      $hlasenie="Sprava bola uspesne pridana.";  
    }
  }
?>      
  <!doctype html>
  <head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
  <title>TEST - Kniha Navstev</title>
  </head>
  <body>       
  <?php
    // VYPIS ODKAZOV       
    //pouzivam include"kniha_navstev_form.php";
    //pre jednoduchsiu ukazku vysledok includu je tu:
    if($hlasenie!="")echo"$hlasenie<br><br>";
    echo"
    <form action=\"index.php\" method=\"post\">
      Nick:<br><input type=text name=nick><br>
      Text:<br><textarea name=text></textarea><br>
      <input type=submit name=send value=Send><br><br>
    </form>";        
    $query=mysql_query(" SELECT nick,text,time FROM kniha_navstev ORDER BY id DESC ");
    while(list($nick,$text,$time)=mysql_fetch_row($query))
    {
      $text=nahrad_smajlikov($text);
      echo"<b>$nick</b> $time<br>$text<br><br>";      
    }    
  ?>     
  </body>
  </html>
<?php    
  mysql_close($spojenie);   
?>
pcmanik
Profil
kachnak:
1. Prečo si si vymyslel vlastnú funkciu (text_input) na ošetrovanie vstupov, keď je na to už natívna funkcia? Naviac ju využívaš zle, slúži na ošetrenie výstupu a nie vstupu!
2. Keď pridávaš príspevok do knihy návštev, tak už neoveruješ či sa príspevok skutočne pridal, ale len vypíšeš správu o tom, že bol pridaný.
3. Stačí keď v echu zmeníš úvodzovky (") na apostrofy (') a potom sa vyhneš spätným lomitkám -
echo "<form action=\"index.php\" method=\"post\">...";
echo '<form action="index.php" method="post">...';
4. mysql_close je zbytočné, pripojenie sa ukončí automaticky.
5. Pozri sa po mysqli, alebo PDO. Mysql je už deprecated a nemalo by sa používať, v budúcnosti bude zmazané.
6. Prečo využívaš include aj na iných miestach ako je súbor s funkciami? Nedáva mi to význam, jedine že by si tie súbory využil aj niekde inde.
7. Stĺpec time je pravdepodobne typu DATETIME, alebo TIMESTAMP. Prečo teda nevyužiješ priamo MySQL funkciu NOW() na vloženie času?
kachnak
Profil
1. Nevedel som že existuje funkcia na nahradenie znakov. Vďaka odteraz ju budem použivať.
2. funkcia na overenie zápisu by mohla byť takáto?
  if(isset($_POST['send']))
  {
    $nick=text_input($_POST['nick']);
    $text=text_input($_POST['text']);    
    if($nick=="" || $text=="")
    $hlasenie="Nezadali ste Nick alebo Text.";
    else
    {
      $time=date("d.m.Y (H:i)");
      if(!$query_insert=mysql_query("INSERT INTO kniha_navstev 
      SET nick='$nick' , text='$text' , time='$time' "))  
      $hlasenie="Spravu sa nepodarilo zapisat do db.";
      else
      $hlasenie="Sprava bola uspesne pridana.";  
    }
  }
3. hej o tom viem ale myslel som že zápis \" je validnejší v html ako '
4. nevedel som že netreba uzatvárať spojenie. Vďaka
5. máš namysli že príkazy dole treba nahradiť novšími?
mysql_connect
mysql_select_db
6. includovanie som používal pretože používam vlastné moduly a aby to bolo prehladné:
Fórum malo dva moduly php a form, Kniha_návštev mala dva moduly php a form, eshop mal vlastné moduly php a form.
modul php obsahuje príkazy
modul form obsahuje vzhľad na webe.
hore nad html kódom príkazy:
naprílad: if(isset($_POST['send'])) (zápis do databázy, zmazanie z databázy)
include"kniha_navstev_php.php";
alebo
include"forum_php.php";
alebo
include"eshop_php.php";
V strede html kódu: (zobrazenie modulov, fyzicky ako vyzerá, výpis správ, výpis produktov v eshope)
include"kniha_navstev_form.php";
alebo
include"forum_form.php";
alebo
include"eshop_form.php";
7. zapisujem vlastný formát času do varchar(18) "23.03.2013 (13:39)"

táto kniha návštev je len na skúšku, nieje naprogramovaná detailne.
Mne išlo hlavne o to objektové programovanie, či by mi to na nej niekto vedel ukázať.
pcmanik
Profil
kachnak:
2. Áno tak to stačí
3. Do HTML sa ti neodosiela ' ale ".
5. Môžes využiť mysqli, alebo PDO, vyber si sám ktoré ti lepšie vyhovuje.
7. Využívaj stĺpce ktoré su na to určené, teda DATETIME, alebo TIMESTAMP vo výsledku si čas môžes naformátovať podľa seba pomocou funkcie DATETIME()

A na ošetrenie vstupov do databázy slúži mysql_real_escape_string()
Tori
Profil
kachnak:
Napríklad som vyrobil veľmi jednoduchú knihu návštev“ - no a tu máte objekt Guestbook.
- Má veřejné vlastnosti (počet záznamů) a metody (přidat nový záznam; načíst jeden záznam podle ID; načíst všechny záznamy; smazat jeden záznam podle ID).
- Pak má soukromé vlastnosti (např. odkaz na úložiště*) a metody (nahrazení smajlíků; kontrola povinně zadaných polí + max.povolené délky).

* tj. jiný objekt, který řeší ukládání do konkrétního místa - různý typ databáze, soubory, atd. Pro začátek můžete počítat napevno jen s jedním možným úložištěm a použít přímo instanci mysqli nebo PDO. Ale vytvořte ji mimo Guestbook a tomu ji jen předejte.
kachnak
Profil
Tori:
no už som trochu upravil ten kód, aby to vyzeralo ako objekt, ale neviem dobre zavolať funkciu, lebo aj keď je public tak mi píše: Call to undefined function zapis_spravu pri odoslaní formulára riadok 70.

<?php     
  header('Content-Type: text/html; charset=utf-8'); 
  class Guestbook
  {       
    function database_open()
    {
      $link=mysql_connect("db50.***.net", "name", "pass");
      mysql_select_db("databaza",$link);
      return $link;
    }
    function database_close($link)
    {
      mysql_close($link);
    }
    public function nahrad_smajlikov($text)
    {             
      $text=" $text ";
      $text=str_replace(" :D ", " <img src=\"smiles/1.gif\"> ",$text);
      $text=str_replace(" :-D ", " <img src=\"smiles/1.gif\"> ",$text);
      $text=str_replace(" :) ", " <img src=\"smiles/19.gif\"> ",$text);
      $text=str_replace(" :-) ", " <img src=\"smiles/19.gif\"> ",$text);
      $text=str_replace(" :( ", " <img src=\"smiles/6.gif\"> ",$text);
      $text=str_replace(" :-( ", " <img src=\"smiles/6.gif\"> ",$text);
      $text=trim($text);
      return $text;
    }
    public function text_input($text)
    {    
      $text=htmlspecialchars($text);
      $text=trim($text);      
      return $text;       
    }
    public function zapis_spravu($nick,$text)
    {
      $link=$this->database_open();      
      $nick=$this->text_input($nick);
      $text=$this->text_input($text);
      if($nick=="" || $text=="")
      $hlasenie="Nezadali ste Nick alebo Text.";
      else
      {
        $time=date("d.m.Y (H:i)");
        if(!$query_insert=mysql_query("INSERT INTO kniha_navstev 
        SET nick='$nick' , text='$text' , time='$time' "))
        $hlasenie="Spravu sa nepodarilo zapisat do databazy.";
        else  
        $hlasenie="Sprava bola uspesne pridana.";  
      }
      $this->database_close($link);
      return $hlasenie;        
    }
    public function allPosts()
    {
      $link=$this->database_open(); 
      $vystup="";
      $query=mysql_query(" SELECT nick,text,time FROM kniha_navstev ORDER BY id DESC ");
      while(list($nick,$text,$time)=mysql_fetch_row($query))
      {
        $vystup="$vystup <b>$nick</b> $time<br>$text<br><br>";              
      }
      if($vystup=="")
      $vystup="Ziadna sprava nebola pridana";
      $this->database_close($link);
      return $vystup;         
    }
  }

  if(isset($_POST['send']))
  {    
    $hlasenie=zapis_spravu($_POST['nick'],$_POST['text']);
  } 
  
?>      
  <!doctype html>
  <head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
  <title>TEST - Kniha Navstev</title>
  </head>
  <body>       

  <?php
    if($hlasenie!="")echo"$hlasenie<br><br>";
    echo"
    <form action=\"index.php\" method=\"post\">
      Nick:<br><input type=text name=nick><br>
      Text:<br><textarea name=text></textarea><br>
      <input type=submit name=send value=Send><br><br>
    </form>";        
    $gb=new Guestbook();
    echo $gb->allPosts();
        
  ?>     
  </body>
  </html>
kachnak
Profil
tak už viem aká tam bola chyba, malo to vyzerať takto:
  if(isset($_POST['send']))
  {    
    $gb=new Guestbook();
    $hlasenie=$gb->zapis_spravu($_POST['nick'],$_POST['text']);
  } 
Tori
Profil
Mohlo by to vypadat i třeba takhle: Hlavním rozdílem je to, že třída Guestbook je samostatnější, nevypisuje přímo data ale jen je vrací, o zobrazení se stará šablona. Instance DB se nevytváří uvnitř návštěvní knihy (pravděpodobně ji budou potřebovat i jiné části stránky). Pardon, že tam tak míchám české a anglické názvy, je to psané narychlo.

- lib/includes.php
<?php
define('TPL_DIR', __DIR__.'/../templates');
define('DB_HOST', '');
define('DB_NAME', '');
define('DB_USER', '');
define('DB_PASS', '');

/* Dostane data a název šablony, a vykreslí šablonu. */
function renderTemplate($tplName, $data = array()) {
    header('Content-Type: text/html; charset=utf-8'); 
    extract($data);

    if (!file_exists(TPL_DIR.'/'.$tplName))
        $tplName = '404.php';
    require TPL_DIR.'/'.$tplName;
}

- lib/Guestbook.php
<?php
class Guestbook
{
    protected $db;
    
    public function setDb($db)
    {
        $this->db = $db;
    }
    
    protected function nahrad_smajlikov($text)
    {             
        $text = " $text ";
        $text = str_replace(" :D ", " <img src=\"smiles/1.gif\"> ",$text);
        $text = str_replace(" :-D ", " <img src=\"smiles/1.gif\"> ",$text);
        $text = str_replace(" :) ", " <img src=\"smiles/19.gif\"> ",$text);
        $text = str_replace(" :-) ", " <img src=\"smiles/19.gif\"> ",$text);
        $text = str_replace(" :( ", " <img src=\"smiles/6.gif\"> ",$text);
        $text = str_replace(" :-( ", " <img src=\"smiles/6.gif\"> ",$text);
        $text = trim($text);
        return $text;
    }
    
    public function text_input($text)
    {    
        $text = htmlspecialchars($text);
        $text = trim($text);      
        return $text;       
    }
    
    public function zapis_spravu($nick, $text)
    {
        $nick = $this->text_input($nick);
        $text = $this->text_input($text);
        if($nick == "" || $text == "")
            throw new Exception("Nezadali ste Nick alebo Text.");
            
        if(!$this->db->query("INSERT INTO kniha_navstev SET 
            nick='".$this->db->real_escape_string($nick)."' , 
            text='".$this->db->real_escape_string($text)."' , 
            time='".date("d.m.Y (H:i)")."'"))
            throw new Exception("Spravu sa nepodarilo zapisat do databazy.");
        
        return true;        
    }

    /* Najde všechny zprávy. Vrací vždy pole */    
    public function getAllPosts()
    {
        $return = array();
        $result = $this->db->query("SELECT nick, text, time FROM kniha_navstev ORDER BY id DESC");
        if ($result === false) // pokud dotaz selhal
            throw new Exception($this->db->error);
            
        while($row = $result->fetchAssoc())
        {
            $return[] = $row;
        }
        return $return;         
    }
}

-templates/guestbook.php
<!doctype html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
<title>TEST - Kniha Navstev</title>
</head>
<body>       

<?php if ($hlasenie != "") echo $hlasenie, "<br><br>"; ?>

<form action="index.php" method="post">
    Nick:<br><input type=text name=nick><br>
    Text:<br><textarea name=text></textarea><br>
    <input type=submit name=send value=Send><br><br>
</form>

<?php
if (empty($data)) 
    echo '<p>Ziadna sprava nebola pridana</p>';
else
{
    foreach($data as $zprava)
    {
        echo "<b>$zprava[nick]</b> $zprava[time]<br>$zprava[text]<br><br>";
    }
}
?>

</body>
</html>

- navstevni-kniha.php (= hlavní, řídicí skript)
<?php
require 'lib/include.php';
require 'lib/Guestbook.php';

// naváže připojení k DB a předá ho instanci knihy návštěv
$db = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);
$kniha = new Guestbook;
$kniha->setDb($db);

try {
    if(isset($_POST['send']))
    {    
        $kniha->zapis_spravu($_POST['nick'], $_POST['text']);
    } 
} catch(Exception $e) {
    $hlasenie = $e->getMessage();
}


renderTemplate('guestbook.php', array(
    'data' => $kniha->getAllPosts(),
    'hlasenie' => $hlasenie,
));
kachnak
Profil
vdaka Tori :) skusim si nastudovat a pochopit tento lepsi zapis toho co mam ja a co mi nebude jasne sa spytam
kachnak
Profil
no sa mi to podarilo spojazdniť. Musel som nahradiť
while($row = $result->fetchAssoc())
týmto kódom, lebo mi písalo chybu: Call to a member function fetchAssoc() on a non-object
while($row = mysqli_fetch_assoc($result))

a ešte bolo treba do spojenia z databázou zapísať port , "3308"

idem študovať ďalej :)
kachnak
Profil
Hlásanie že: Správa bola úspešne pridaná, sa môže spraviť tiež cez "throw new Exception" alebo by sa to malo spraviť ináč?

<?php  public function zapis_spravu($nick, $text) {
    $nick = $this->text_input($nick);
    $text = $this->text_input($text);
    if($nick == "" || $text == "")
      throw new Exception("Nezadali ste Nick alebo Text.");            
    if(!$this->db->query("INSERT INTO kniha_navstev SET 
      nick='".$this->db->real_escape_string($nick)."' , 
      text='".$this->db->real_escape_string($text)."' , 
      time='".date("d.m.Y (H:i)")."'"))
      throw new Exception("Spravu sa nepodarilo zapisat do databazy.");
    else
      throw new Exception("Sprava bola uspesne pridana.");        
    return true;        
} ?>

<?php 
try
{
  if(isset($_POST['send']))
  {    
    $kniha->zapis_spravu($_POST['nick'], $_POST['text']);
  } 
}
catch(Exception $e)
{
  $hlasenie=$e->getMessage();
}
?>

Nebol by lepší zápis takýto? Menej kódu prehladnejšie.. Prečo sa používa TRY?

<?php  public function zapis_spravu($nick, $text) {
    $nick = $this->text_input($nick);
    $text = $this->text_input($text);
    if($nick == "" || $text == "")
      $hlasenie="Nezadali ste Nick alebo Text.";            
    if(!$this->db->query("INSERT INTO kniha_navstev SET 
      nick='".$this->db->real_escape_string($nick)."' , 
      text='".$this->db->real_escape_string($text)."' , 
      time='".date("d.m.Y (H:i)")."'"))
      $hlasenie="Spravu sa nepodarilo zapisat do databazy.";
    else
      $hlasenie="Sprava bola uspesne pridana.";        
    return $hlasenie;        
} ?>

<?php 
if(isset($_POST['send']))
{    
  $hlasenie=$kniha->zapis_spravu($_POST['nick'], $_POST['text']);
}
?>

a ešte neviem vycucať z databázy stĺpec time (formát datetime 0000-00-00 00:00:00) čas v tvare 24.12.2013 (18:41)
toto nefunguje
$result=$this->db->query("SELECT nick, text, time(d.m.Y (H:i)) FROM kniha_navstev ORDER BY id DESC");
Tori
Profil
kachnak:
Hlásanie že: Správa bola úspešne pridaná, sa môže spraviť tiež cez "throw new Exception"?
Ne, výjimky se používají v situaci, kdy dojde k chybě, se kterou si aktuální metoda/funkce neví sama poradit, takže to nechá na nějakou nadřízenou metodu. Podobně jako při return false; se při vyhození výjimky neprovádí žádný další kód na aktuální úrovni (tj. zbytek funkce se "přeskočí"). Rozdíl je v tom, že to samé se pak u výjimek opakuje i na všech vyšších úrovních až do té doby, dokud se nenajde blok try-catch. Zkuste si napsat nějaká vnořená volání funkcí, na různá místa dát try-catch a zkoušet, jak se to chová. Svým způsobem to je podobné probublávání událostí v JavaScriptu (událost onclick se spustí na kliknutém prvku, pak na jeho rodiči, pak na rodiči rodiče atd. až do doby, kdy je na nějaké úrovni zastavena zavoláním event.stopPropagation().
function x() {
    return false; 
    echo 'x ';
}
function y() { 
    x(); 
    echo 'y ';
}
function z() { 
    y(); 
    echo 'z '; 
}
x();// napíše "y z "

function a() { 
    throw new Exception('chyba'); 
    echo 'a ';
}
function b() { 
    a(); 
    echo 'b '; 
}
function c() { 
    b(); 
    echo 'c '; 
}
function d() { 
    try {
        c();
    } catch (Exception $e) {
        echo 'zachycena vyjimka: '.$e->getMessage().' ';
    }
    echo 'd ';
}
d();// napíše "zachycena vyjimka: chyba d ". Nezobrazilo se "a", "b" ani "c".
Je to jen trochu odlišný přístup. Buď můžete vždy vracet true/false, a při každém volání funkce to ověřovat, anebo prostě počítáte s tím, že program proběhne normálně (tj. jako by vrátil true) a chybové stavy zpracujete až v části catch.

Zlepšuje to čitelnost kódu v případě, kdy po sobě následuje několik vzájemně souvisejících příkazů, které se mají provést buď všechny nebo žádný. Pokud např. prvním příkazem vytvořím nový článek v DB a v dalších příkazech s ním chci pracovat, tak je určitě lépe čitelné tohle:
try {
    $clanek = $model->clanky->pridejNovy($data);
    Mail::posliUpozorneni('clanek', $clanek);
    JinyObjekt::udelejNeco($clanek);
    echo 'OK';
} catch (Exception $e) {
    echo 'Chyba: '.$e->getMessage();
}
než tohle:
if ($clanek = $model->clanky->pridejNovy($data)) {
    if (Mail::posliUpozorneni('clanek', $clanek)) {
        if (JinyObjekt::udelejNeco($clanek)) {
            echo 'OK';
        } else {
            echo 'Nepodařilo se udělat něco.';
        }
    } else {
        echo 'Nepodařilo se poslat upozornění e-mailem.';
    }
} else {
    echo 'Nepodařilo se uložit článek do DB.';
}


neviem vycucať z databázy stĺpec time
Je doporučené dávat identifikátory (tj. názvy sloupců, tabulek a pohledů) do zpětných apostrofů: SELECT `text`, .... Pokud jako identifikátor používáte vyhrazené slovo MySQL ("text", "time"), tak je to nutné.

Formátování data viz MySQL funkce DATE_FORMAT.
kachnak
Profil
takže úspešná hláška by sa dala dorobiť takto:
<?php 
try
{
  if(isset($_POST['send']))
  {    
    $kniha->zapis_spravu($_POST['nick'], $_POST['text']);
    $hlasenie="Sprava bola uspesne pridana.";
  } 
}
catch(Exception $e)
{
  $hlasenie=$e->getMessage();
}
?>

Doplnil som aj zmenu smajlikov do funkcie getAllPosts:

public function getAllPosts()
{
  $return = array();
  $result = $this->db->query("SELECT `nick`, `text` , DATE_FORMAT(time,'%d.%m.%Y (%H:%i)') as `time` FROM akniha_navstev ORDER BY id DESC");
  if ($result === false) // pokud dotaz selhal
    throw new Exception("Chyba:<br>Nepodarilo sa načítať správy z databázy.");            
  while($row = mysqli_fetch_assoc($result)) 
  {
    $row[text]=$this->nahrad_smajlikov($row[text]);
    $return[] = $row;
  }
  return $return;         
} 

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: