Autor Zpráva
sir_lamoid
Profil
Dobrý den,

snažím se naprogramovat jednoduchý redakční systém v architektuře MVC, ale narážím na chybu
 Fatal error: Call to a member function vypisView() on a non-object in C:\wamp\www\xx\xxx\view\rozlozeni.phtml on line 239

Můj zkraceny kod rozlozeni.phtml
<meta name="description" content="<?= $popis ?>" />
    <meta name="keywords" content="<?= $klicova_slova ?>" />
    <meta name="author" content="Jakub Stejskal" />
    <title><?= $titulek ?></title>
.......
...
....
<?php foreach ($zpravy as $zprava) : ?>
            <p class="zprava"><?= $zprava ?></p>
                  <?php endforeach ?>
        
                <!-- End page header -->
                
                
                <!-- Your awesome content goes here -->
                
                
                <?php $this->controller->vypisView() ?>
kod Controller.php
<?php

// Výchozí Controller
abstract class Controller
{

    // Pole, jehož indexy jsou poté viditelné v šabloně jako běžné proměnné
    protected $data = array();
    // Název šablony bez přípony
    protected $view = "";
    // Hlavička HTML stránky
    protected $hlavicka = array('titulek' => '', 'klicova_slova' => '', 'popis' => '');

    // Funkce rekurzivně ošetří hodnoty v poli $data tak, aby je bylo možné 
    // bezpečně vypsat v šabloně. Ošetřují se řetězce a to i ve vnořených 
    // polích. Objekty (které v šabloně většinou nejsou třeba) si musíte ošetřit manuálně.
    private function osetri($x = null)
    {
        if (!isset($x))
            return null;
        elseif (is_string($x))
            return htmlspecialchars($x);
        elseif (is_array($x))
        {
            foreach($x as $k => $v)
            {
                $x[$k] = $this->osetri($v);
            }
            return $x;
        }
        else
            return $x;
    }
    
    // Vyrenderuje view
    public function vypisView()
    {
        if ($this->view)
        {
            extract($this->osetri($this->data));
            extract($this->data, EXTR_PREFIX_ALL, "");
            require("view/" . $this->view . ".phtml");
        }
    }
    
    // Přesměruje na dané URL
    public function presmeruj($url)
    {
        header("Location: $url");
        header("Connection: close");
        exit;
    }

    // Hlavní metoda controlleru
    abstract function zpracuj($parametry);

}

// Funkce pro zjednodušené manuální zabezpečení vstupů v případě, že chceme
// zabezpečit jen některé části pole $data a ostatní již obsahují HTML výstup
function o($s)
{
    return htmlspecialchars($s);
}
kod SmerovacController.php
<?php

// Router je speciální typ controlleru, který podle URL adresy zavolá
// správný controller a jím vytvořený view vloží do šablony stránky

class SmerovacController extends Controller
{
    // Instance controlleru
    protected $controller;
    
    // Metoda převede pomlčkovou variantu controlleru na název třídy
    private function pomlckyDoVelbloudiNotace($text) 
    {
        $veta = str_replace('-', ' ', $text);
        $veta = ucwords($veta);
        $veta = str_replace(' ', '', $veta);
        return $veta;
    }
    
    // Naparsuje URL adresu podle lomítek a vrátí pole parametrů
    private function parsujURL($url)
    {
        // Naparsuje jednotlivé části URL adresy do asociativního pole
        $naparsovanaURL = parse_url($url);
        // Odstranění počátečního lomítka
        if (mb_strpos($naparsovanaURL["path"], "/") === 0)
            $naparsovanaURL["path"][0] = "";
        // Rozbití řetězce podle lomítek
        $rozdelenaCesta = explode("/", $naparsovanaURL["path"]);
        // Odstranění bílého místa z částí řetězce
        for ($i = 0; $i < count($rozdelenaCesta); $i++)
            $rozdelenaCesta[$i] = trim($rozdelenaCesta[$i]);
        return $rozdelenaCesta;
    }

    // Naparsování URL adresy a vytvoření příslušného controlleru
    public function zpracuj($parametry)
    {
        $naparsovanaURL = $this->parsujURL($parametry[0]);
            
        // Výchozí URL pokud je zadána prázdná
        if (!$naparsovanaURL[0])
            $naparsovanaURL = array('pacman-remake');
            
        // Vytvoření controlleru
        $mc = new ManazerClanku();
        // Pokud existuje článek s URL co je v 1. parametru, controller je ArticleController
        if ($mc->clanekExistuje($naparsovanaURL[0]))
            $this->Controller = new ClanekController($naparsovanaURL[0]);
        else
        {
            // Článek nenalezen, Controller je 1. parametr URL
            $tridaControlleru = $this->pomlckyDoVelbloudiNotace(array_shift($naparsovanaURL)) . 'Controller';
            if (file_exists('controller/' . $tridaControlleru . '.php'))
                $this->Controller = new $tridaControlleru;
            else
            {
                header("HTTP/1.0 404 Not Found");
                exit;
            }
        }     
        
        // Volání controlleru
        $this->Controller->zpracuj($naparsovanaURL);
        
        // Nastavení proměnných pro šablonu
        $this->data['titulek'] = $this->Controller->hlavicka['titulek'];
        $this->data['popis'] = $this->Controller->hlavicka['popis'];
        $this->data['klicova_slova'] = $this->Controller->hlavicka['klicova_slova'];
        $this->data['zpravy'] = Zprava::vratZpravy();
        
        // Nastavení hlavní šablony
        $this->view = 'rozlozeni';
    }

}
Tori
Profil
sir_lamoid:
V jakém kontextu spouštíte tu druhou šablonu? Zřejmě $this odkazuje na něco jiného, než čekáte.
Tori
Profil
Až teď jsem si všimla:
šablona: $this->controller->vypisView()
router: protected $controller; ale: $this->Controller = new $tridaControlleru; (ř. 49 + 55)

Tomuhle typu chyb se dá předcházet např. tím, že všechny třídy budou potomkem nějakého základního objektu, který bude při pokusu o přiřazení do nedefinované vlastnosti házet výjimku (viz Nette\Object).

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: