Autor Zpráva
KubaFibi
Profil
Dobrý den, nevím jestli jsem správně pochopil, jak se píše v PHP OOP, tak jsem napsal velice jednoduchý kód a chtěl bych, aby jste mi napsali názor. Potřebuji hlavně vědět, jestli by takhle mohl vypadat i nějaký např. redakční systém. Jen by v něm bylo třeba víc druhů stránek, např. by k sekci, přibyla kategorie, článek, diskuze, apod.

Takže k věci. Mám soubory:
Section.php - jeden ze souborů typu stránek, např. sekce, kategorie, článek, atd. Přemýšlel jsem také o mětodě toString(), která by zhotovila celou stránku a v souboru index.php by se pak volala jen ta. To jsem ale prozatím zavrhl.
<?php
class Section {
  private $file;
  public function __construct($file){
    $this->file = $file;
  }
  public function getTitle(){
    require $this->file;
    return $title;
  }
  
  public function getNadpis(){
    require $this->file;
    return $nadpis;
  }
  public function getText(){
    require $this->file;
    return $text;
  }
}
?>
data.php - pro jednoduchost jsem zvolil uložení dat v souboru. Jinak by místo souboru byla databáze a podle toho by byl upraven i soubor section.php
<?php
$title = "TITLE";
$nadpis = "NADPIS";
$text = "TEXT";
?>
index.php - v tomto souboru bude vše spuštěno
<?php
require_once "section.php"; 
$page = new Section("data.php");
?>
<head>
<title><?php echo $page->getTitle(); ?></title>
</head>

<body>
<h1><?php echo $page->getNadpis(); ?></h1>
<p><?php echo $page->getText(); ?></p>
</body>



Ještě pro doplnění. Až by byla data tahána z databáze, tak by se objekt nevytvářel použitím jména souboru, ale třeba přes id sekce.
Majkl578
Profil
To, co jsi tam předvedl s require v metodách je krásný příklad toho, co nikdy nedělat. Třída naprosto nesmyslně spoléhá na existenci nějaké proměnné v jiném PHP souboru (která nemusí být definována, soubor nemusí existovat, může v něm být něco co při každém načtení ovlivní třídu/aplikaci apod.), to je zkrátka špatně. Třída sama o sobě by asi takhle i vypadat mohla (vč. použití v HTML), nicméně to načítání ze souboru je podobně zlé jako použití global. Tady by asi víc dávalo smysl ze třídy Section udělat jen schránku na data a plnit ji zvenčí (tj, nějaký konfigurační soubor / nastavení z DB by se načetlo jinde a vytvořilo 1-N instancí této třídy, dle nastavení).
Keeehi
Profil
Syntakticky to není špatně, ale logicky je to úplně vedle. OOP není o nových slovíčkách class, new nebo protected ale o určitém pohledu na problém. Když to zjednoduším: žijeme ve světě obklopeni věcmi (objekty). Tyto věci mají různé vlastnosti/stavy(atributy) kterými jsou popsány. Takže objektem je třeba židle, televize, lampa. Vezmeme si třeba lampu. Lampa je objekt který má mnoho vlastností. Některé z nich jsou třeba barva, velikost, váha, svítící/nesvítící žárovka. Soubor těchto atributů nám říká, jaká ta lapa je, nebo v jakém stavu se nachází. A dále má lampa ještě funce(metody) kterými může svoje stavy měnit. Vypínač mění stav svítí/nesvítí.

Ve tvém případě je tvým objektem Stránka, atributy jsou titulek, nadpis, a text. A dále metody, podle toho, co všechno stránka umí.

class Stranka {
  private $title="Defaultní titulek";
  private $nadpis="";
  private $text="";

  public function setTitle($title){
    $this->title = $title;
  }
  public function setNadpis($nadpis){
    $this->nadpis = $nadpis;
  }
  public function setText($text){
    $this->text = $text;
  }

  public function makePage(){
    echo "<head>
<title>".$this->title."</title>
</head>
 
<body>
<h1>".$this->nadpis."</h1>
<p>".$this->text."</p>
</body>";
  }
}

A použití:
require "data.php"; //no dejme tomu zatím
require "stranka.php";

$page = new Stranka("data.php");

$page->setTitle($title);
$page->setNadpis($nadpis);
$page->setText($text);

$page->makePage();

Měl by jsi se rozhodnout jestli pro názvy funkcí, tříd, souborů, proměnných, atd. budeš používat jen česká nebo jen anglická slova. Takhle to míchat dohromady, to není pěkné. doporučuji čistě angličtinu.
KubaFibi
Profil
Děkuji za odpovědi, verze od Keeehi je asi lepší než ta moje, ale ještě bych měl jeden dotaz.

když bych měl v db tabulku:
id
type
name
text
V řádku s adresou by bylo id stránky např.
http://127.0.0.1/index.php?page=12

Proto jsem také v mé první verzi udělal konstruktor jen pro "id" (tam to byl název souboru, ale v tom případě to sloužilo jako takové id). Zbývající data by se vytáhla z toho souboru, teď tedy z databáze. Šlo by to tak nějak, aby data z db vytáhla třída? Nebo to musím udělat v index.php?
Alphard
Profil
Objektový návrh obsahuje více tříd. Funkčnosti se dosahuje skládáním objektů dohromady. Keeehi tady prezentoval třídu Stranka, která plní funkci jakési šablony, předáte jí data a ona je vykreslí.
Pro získání dat z db si vytvoříte další třídy, potřebná data předáte třídě Stranka a ona je zase vykreslí.
KubaFibi
Profil
Tak jsem ještě něco zkusil, chtěl bych také vědět, jestli je to dobře, že tahám data z db ve třídě nebo jestli bych to měl udělat v index.php

Mám soubor section.php
<?php
class Section {
  private $id, $table, $connect;
  public function __construct($id, $table, ConnectDB $connect){
    $this->id = $id;
    $this->table = $table;
    $this->connect = $connect;
  }

  public function getTitle(){
    $this->connect->joinDB();
    $sql = mysql_query("SELECT title FROM ".$this->table." WHERE id='".$this->id."' LIMIT 1");
    $extract = mysql_fetch_array($sql);
    return $extract['title'];
  }

  public function getName(){
    $this->connect->joinDB();
    $sql = mysql_query("SELECT name FROM ".$this->table." WHERE id='".$this->id."' LIMIT 1");
    $extract = mysql_fetch_array($sql);
    return $extract['title'];
  }

  public function getText(){
    $this->connect->joinDB();
    $sql = mysql_query("SELECT text FROM ".$this->table." WHERE id='".$this->id."' LIMIT 1");
    $extract = mysql_fetch_array($sql);
    return $extract['title'];
  }
}

class ConnectDB {
  private $host, $user, $password, $db_name;
  
  public function __construct($host, $user, $password, $db_name){
    $this->host = $host;
    $this->user = $user;
    $this->password = $password;
    $this->db_name = $db_name;
  }
  
  public function joinDB(){
    $connect = mysql_connect($this->host, $this->user, $this->password);
    mysql_select_db($this->db_name, $connect);
  }
}
?>

Další soubor index.php
<?php 
require "section.php";
$spojeni = new ConnectDB("server", "jmeno", "heslo", "jmeno_databaze");
$stranka = new Section($_GET["page"],"db_stranky", $spojeni);
?>
<head>
<title><?php echo $stranka->getTitle(); ?></title>
</head>

<body>
<h1><?php echo $stranka->getNadpis(); ?></h1>
<p><?php echo $stranka->getText(); ?></p>
</body>
Nox
Profil
Máš tam jakousi třídu Connect, ale v Section stejně řešíš komunikaci s DB přímo, to nedává smysl. Nehlede na to že co volání get*, to query do databáze...

OOP je založené na jakési hierarchii (síť, stromy...) navzájem komunikujících objektů, to je asi to hlavní. Myslim že dost pomůže se kouknout na existující řešení, např. knihovny/frameworky (Nette2, Symfony2, Doctrine2 etc.) případně celé projekty, pokud něco najdeš.
Keeehi
Profil
class Stranka {
  private $title="Defaultní titulek";
  private $nadpis="";
  private $text="";
 
  public function setTitle($title){
    $this->title = $title;
  }
  public function setNadpis($nadpis){
    $this->nadpis = $nadpis;
  }
  public function setText($text){
    $this->text = $text;
  }
 
  public function makePage(){
    echo "<head>
<title>".$this->title."</title>
</head>
 
<body>
<h1>".$this->nadpis."</h1>
<p>".$this->text."</p>
</body>";
  }
}

class DB {
  public function __construct($host, $user, $password, $db_name){
    $this->host = $host;
    $this->user = $user;
    $this->password = $password;
    $this->db_name = $db_name;
    $connect = mysql_connect($this->host, $this->user, $this->password);
    mysql_select_db($this->db_name, $connect);
  }
  
  public function getData($id) {
    $sql = mysql_query("SELECT title, nadpis, text FROM tabulka WHERE id='".$this->id."' LIMIT 1");
    return mysql_fetch_assoc($sql);
  }

}

Použití:
$page = new Stranka("data.php");
$db = new DB("server", "jmeno", "heslo", "jmeno_databaze");
$data=$db->getData((int)$_GET["page"]);
 
$page->setTitle($data["title"]);
$page->setNadpis($data["nadpis"]);
$page->setText($data["text"]);
 
$page->makePage();

Ale pro práci s db bych raději použil dibi.
Nox
Profil
Řešit OOP u jediného objektu, který je jen naivní obálka nad daty a nic nedělá, je dost k ničemu...

Keeehi: to co tu máš je skoro vlastně procedurální programování ... žádná komunikace objektů, žádný polymorfismus, zapouzdření také není defakto vidět, identita není prezentována...
(a mj. SQL injection, $this->id neexistuje, connect je třeba uložit a používat - $this->connect, resp. spíš $this->connection...)
Keeehi
Profil
Nox:
to co tu máš je skoro vlastně procedurální programování
Vždyť já vím, ale v rozsahu "zadání" toho moc není takže ani není s čím pracovat.

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: