Autor Zpráva
Dreamer
Profil
Ahoj, mám malý problém. Začínám s OOP a snažím se vytvořit script na výpočet BMI, bohužel se mi moc nedaří. Nebudu to dále rozepisovat a uvedu script, jenž mi nefunguje. Formulář to vypíše, bohužel, po odeslání vyplněného formuláře to opět vypíše ten stejný formulář.
<?php
class BMI {
    function __construct() {
        if (!isset($HTTP_GET_VARS)) {
            $this->BMIform();
        }
        else $this->BMIvypocet($HTTP_GET_VARS["vaha"],$HTTP_GET_VARS["vyska"]);
    }
    public static function BMIform() {
    echo"<form method=\"GET\" action=\"\"><BR>
    Vaše váha:<input type=\"text\" name=\"vaha\" size=\"3\">Kg.<BR>
    Vaše výška:<input type=\"text\" name=\"vyska\" size=\"3\">Cm<BR>
    <input type=\"submit\" value=\"Odeslat\">
    </form>";
    }
    public function BMIvypocet($vaha,$vyska) {
        
        $this->$vyska = $vyska*0.01;
        return "Vaše BMI je: ".$this->vaha/($this->$vyska*$this->$vyska);
    }
    
};
$new = new BMI;
?>

Jsem nováček, což je na scriptu znát. Jen bych ještě rád dodal, že není ještě hotový, chybí například ochrana před zadáním potencionálně škodlivého kódu apod.
Předem děkuji za rady.
PS: Doufám, že se mi nevysmějete.
Joker
Profil
Dreamer:
Možná má server vypnuté register_long_arrays, takže nezaloží proměnnou $HTTP_GET_VARS. Tato už není v PHP podporována a nedoporučuje se ji používat, místo ní už hezkých pár let je $_GET.

Jsem nováček, což je na scriptu znát.
Tak se možná bude hodit pár dalších poznámek:
- Ta třída je taková jednorázová. Kód kde vlastně aplikace s objektem pracuje by měl být venku a ne v konstruktoru.
- Třída by měla být víc zapouzdřená, nespoléhat na to, že někde v GETu budou zrovna nějaké proměnné.
- Váha a výška by mohly být atributy objektu. Dokonce ve výpočtu se s nimi i tak pracuje, ale nevidím je definované nikde

Příklad, jak by to šlo upravit:
<?php 
class BMI { 
    public $vaha;
    public $vyska;
    
    function __construct($vaha, $vyska) { 
      // váhu a výšku převezmeme jako parametry konstruktoru
      $this->vaha = $vaha;
      $this->vyska = $vyska;
    }
    
    // ke jménu metody bych nepřidával jméno třídy, spíš ty znaky využít pro výstižnější název
    public function zobrazForm() 
    { 
      // udělám nestatickou abych mohl předvyplnit hodnoty políček
      $vaha = ""; //pokud je vyplněno $this->vaha, zkopírujeme to tam, jinak prázdné
      if($this->vaha > 0) $vaha = $this->vaha;
      $vyska = ""; //totéž pro výšku
      if($this->vyska > 0) $vyska = $this->vyska;

      echo "<form method=\"GET\" action=\"\"><BR> 
      Vaše váha:<input type=\"text\" name=\"vaha\" size=\"3\" value=\"". $vaha ."\">Kg.<BR> 
      Vaše výška:<input type=\"text\" name=\"vyska\" size=\"3\" value=\"". $vyska ."\">Cm<BR> 
      <input type=\"submit\" value=\"Odeslat\"> 
      </form>"; 
    }
    
    function vypocet()
    { 
        $vyska = $this->vyska*0.01; // převedeme do lokální proměnné, tu pak použijeme ve výpočtu
        if($vyska == 0) return; // taky není od věci ohlídat dělení nulou
        return $this->vaha/($vyska*$vyska); // u váhy se naopak používá atribut objektu
        // vrátíme raději jen číslo než text, bude to univerzálnější
    } 
}
$vyska = 0;
if(!empty($_GET["vyska"])) $vyska = intval($_GET["vyska"]);
$vaha = 0;
if(!empty($_GET["vaha"])) $vaha = intval($_GET["vaha"]);

$bmi = new BMI($vyska, $vaha);
$bmi->zobrazForm();
if(($vyska > 0) && ($vaha > 0)) echo "Váš BMI je: ".$bmi->vypocet();

Je to samozřejmě jen taková ukázka, snažil jsem se do toho nacpat předvedení některých principů.
motik
Profil
Dreamer:
<?php
class BMI {
    function __construct() {
        if (!isset($_GET['odeslat'])) {
            $this->BMIform();
        }
        else $this->BMIvypocet($_GET["vaha"],$_GET["vyska"]);
    }
    public static function BMIform() {
    echo"<form method=\"GET\" action=\"\"><BR>
    <input type=\"hidden\" name=\"odeslat\">
    Vaše váha:<input type=\"text\" name=\"vaha\" size=\"3\">Kg.<BR>
    Vaše výška:<input type=\"text\" name=\"vyska\" size=\"3\">Cm<BR>
    <input type=\"submit\" value=\"Odeslat\">
    </form>";
    }
    function BMIvypocet($vaha,$vyska) {
        
        $this->$vyska = $vyska*0.01;
        
        echo  "Vaše BMI je: ". ($vaha/($this->$vyska*$this->$vyska));
    }
    
};
$new = new BMI;
?> 


Jsem nováček, což je na scriptu znát.
snaž se aspoň psát kód úhledně a jedním stylem - je to hrůza..

---------------------------------------------------------------------------------------------------------------------------
jako OOP já moc neumím, ale ten kód je psaný moc chaoticky a dle mého názoru špatně (ale třeba se pletu)
- podle mě nemá cenu dělat funkci, když ji použiješ stejnak jen jednou
- a funkce by neměla vypisovat, ale vracet
...
Dreamer
Profil
Jokere, moc ti děkuji, krásně vysvětleno.
PS:Konečně jsem pochopil něco málo o oop. Jsem ti navěky vděčný.
Joker
Profil
motik:
funkce by neměla vypisovat, ale vracet
Poznámka, „funkce“ u objektů jsou metody.
A ono tohle nemusí být úplně vždycky, samozřejmě je univerzálnější hodnotu vrátit než ji vypsat, protože s tím pak aplikace může dál pracovat.
Názorný příklad je ten výpočet, tam je opravdu daleko logičtější to číslo jen vrátit.
Naopak u té metody generující formulář bych tak kategorický nebyl, tam dává smysl i to přímo vypsat (byť by ta metoda samozřejmě mohla výsledný kód vrátit).
motik
Profil
Joker:
říkám, že v OOP se moc nevyznám..

jinak
$bmi = new BMI($vyska, $vaha);

mi příjde takový dost komplikovaný (nevím, jestli to použils jen kůli vysvětlení)..
když už na takovou věc dělat třídu (nevím, jestli se tomu tak říká), tak tam nacpat vše a jedním příkazem ji vypsat (max. tam dát nějaký parametr na nastavení např. $zobraz = TRUE; - aby se zobrazil formulář s výsledkem, jinak bych tam žádné proměné necpal a vše ošetřil v té třídě)
pcmanik
Profil
Hmm doteraz som moc neprisiel na vyznam OOP. A tento skript ma v tom utvrdzuje, je nejaky vyznam to robit takto? Ved staci obycajny intval na vstupoch a nakoniec to vypocitat a nie takato kopa kodu.
Bertram
Profil
@motik, dreamer@

Je důležité uvědomit si, že OOP není to, že svůj dřívější kód dám mezi složené závorky a pojmenuji to.

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:

0