Autor Zpráva
KubaFibi
Profil
Zdravím, pokusil jsem se udělat něco, co jsem potřeboval a k tomu jsem si chtěl zkusit jak by to bylo v OOP. Jedná se o RSS generátor.

Zde je kód:
<?php
class RSS {
  private $title, $link, $description, $language;
  private $image_title, $image_url, $image_link, $image_width, $image_height;
  private $items = array();

  public function __construct($title, $link, $description, $language){
    $this->title = $title;
    $this->link = $link;
    $this->description = $description;
    $this->language = $language;
  }

  public function setImage($title, $url, $link, $width, $height){
    $this->image_title = $title;
    $this->image_url = $url;
    $this->image_link = $link;
    $this->image_width = $width;
    $this->image_height = $height;
  }

  public function setItems($items){
    $return = "";
    foreach($items as $item){
      $return .= $item;
    }
    $this->items = $return;
  }

  public function __toString(){
    return '<?xml version="1.0" encoding="UTF-8"?>
    <rss version="0.91">
      <channel>
        <title>'.$this->title.'</title>
        <link>http://'.$this->link.'</link>
        <description>'.$this->description.'</description>
        <language>'.$this->language.'</language>
        <image>
          <title>'.$this->image_title.'</title>
          <url>'.$this->image_url.'</url>
          <link>'.$this->image_link.'</link>
          <width>'.$this->image_width.'</width>
          <height>'.$this->image_height.'</height>
        </image>

        '.$this->items.'

      </channel>
    </rss>';
  }
}

class RSS_item {
  private $title, $link, $description, $pubDate;

  public function __construct($title, $link, $description, $pubDate){
    $this->title = $title;
    $this->link = $link;
    $this->description = $description;
    $this->pubDate = $pubDate;
  }

  public function __toString(){
    return "<item>
    <title>".$this->title."</title>
    <link>".$this->link."</link>
    <description>".$this->description."</description>
    <pubDate>".$this->pubDate."</pubDate>
    </item>";
  }
}
?>

Poté by se to použilo takto:
<?php
$rss = new RSS("title", "link", "description", "language");
$rss->setItems(array(new RSS_item("title 1","link 1","description 1","Sat, 18 May 2002 15:21:36 GMT"),
                     new RSS_item("title 2","link 2","description 2","Sun, 19 May 2002 15:21:36 GMT"),
                     new RSS_item("title 3","link 3","description 3","Mon, 20 May 2002 15:21:36 GMT")
                     ));
echo $rss;
?>

Data, jako např. title 1, link 1, title 2, atd. by se doplnili z databáze pomocí cyklu, ale to tu nechci řešit, protože o to mi nejde.

Po Vás chci, aby jste přispěli svým názorem na tyto dvě třídy. S programováním v OOP začínám, takže opravdu nevím, zda je toto použitelné. Neměl bych někde ověřovat správnost zadaných údajů? např. zda bylo do metody setItems() zadáno pole?

DODATEK:
Ještě bych se chtěl zeptat, k tomu RSS, jaké jsou rozdíly mezi verzemi 0.91, 1.0 a 2.0. Když jsem totiž hledal na netu, tak všechny tři verze měli všechny značky stejný - jen v hlavičce je číslo verze.
Kcko
Profil
KubaFibi:
Moc jsem to nezkoumal, nejsem OOP guru, nicméně metoda setItems je hodně prapodivná.

Mělo by to být spíše něco jako

$rss->addItem(new RSS_item(...));
$rss->addItem(new RSS_item(...));
$rss->addItem(new RSS_item(...));

Na začátečníka to asi ujde, ale je to takové hodně jednoduché a nic moc to neumí.
Alphard
Profil
Návrh nebudu hodnotit, jste začátečník, a vznitřní implementace není to nejpodstatnější. Ale měl byste myslet hlavně na to, aby zvenku třída dělala to, co se předpokládá.
Například na bezpečnost, escapovat data vypisovaná do XML by měla být samozřejmost. To je jedna z věcí, kterou od podobné třídy očekávám. Nepotřebuji třídu na něco, co vytvořím jedním cyklem, když nic jiného neumí.
Další věcí je třeba datum publikace. Když už používám třídu na generování RSS, nechci v manuálu hledat, jak mám formátovat datum. Chci předat Datetime, nebo klasický řetězec výstupu z databáze 'rrrr-mm-dd' a čekám, že si to třída upraví.
KubaFibi
Profil
Díky za odpovědi,
metodu setItems() jsem přepsal na addItems() takto:
  public function addItem($item){
    if(is_object($item) && get_class($item) == "RSS_item")
      $this->items .= $item;
  }
Dále jsem upravil způsob zápisu data, v db to ukládám v unixu, takže jsem to podle toho udělal. Data jsem escapoval funkcí htmlspecialchars() a u čísel jsem to ošetřil přetypováním.

Ve škole jsme začli dělat OOP v Javě, akorát, že se tam učíme pořád dokola, jak vypadá konstruktor, metody, dědění, rozhrání, apod., ale vůbec si neříkáme o tom escapování, a bezpečnosti vůbec, také co by měla třída všechno dělat. Takže kdyby někoho něco napadlo, tak budu rád, když to sem připíše.
Kcko
Profil
KubaFibi:
Imho by to mělo vypadat takhle


  public function addItem(RSS_item $item){
      $this->items[]= $item;
  }
KubaFibi
Profil
No, toto jsem zkoušel a když by se do $item dostalo něco jiného než typ RSS_item, tak skript skončí chybou, když je to tak jak to mám já, tak to chybou neskončí, akorát se prvek vynechá. Jak to tedy má být?
Ugo
Profil
KubaFibi:
má to být tak jak řekne tvůrce :) většina lidí má názor že to chce silnou datovou kontrolu nejlíp jako v C, podle mě je phpko právě o opaku že si můžu dávat co chci takže se snažim aby skripty fungovali se stringem, polem, objektem... samozřejmě je to pak bordel a bude to i zdržovačka kontrolovat všude typy, ale když se jednou rozhodnu použít pole protože už ho mám nachystané a nebo podobný objekt, tak se nic neděje. Výhoda druhého přístupu je jasná, patrně to bude rychlejší (i když nevim jak php kontroluje ten typ - ale je to 1 kontrola), pak je to psychologický - jednoduše víš že můžeš jenom to a tak tě nenapadne experimentovat co všechno to zchroustne (což může vést k chybám) - to je myslim špatně, kód upravují programátoři a ne BFU, ovšem cizím programátorům z toho plyne výhoda - nepotřebují tak robustní dokumentaci když to umí jen jeden vstup. Takže je to na tobě obé má něco (ještě ... když očekáváš jen objekt, tak je to přece více OOP), správně je to co funguje.

btw. k setItems, co tak udělat metodu addItems a té dávat pole? A pak onu setItems klidně nechat, ale aby přepisovala dosavadní pole (tak jak byla vlastně). Všechny budou ve finále volat addItem, jen za použivatele udělají cyklus který by jim zbytečně dělal bordel v kódu :)

osobně mi chybí možnost vynechat některé parametry pro RSS_item a určitě není nejlepší jak píše Kcko uchovávat položky jako string, jakákoliv manipulace s nimi je pak nemožná.
Alphard
Profil
Ugo:
Tak lze udělat třeba RSS_item::fromArray($arr) že ano. Bez újmy na obecnosti a se zachováním aspoň nějaké kvality návrhu.

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: