Visualizzazione dei risultati da 1 a 4 su 4
  1. #1
    Utente di HTML.it
    Registrato dal
    Oct 2011
    Messaggi
    590

    errore parent::__constructor

    salve, ho un problema con la modellazione mvc in php.
    Purtroppo il codice è lungo ma come vedete è molto banale (ho tralasciato la view, non è lì il problema). Il db è formato semplicemente dalla tabella page(id,title,text).
    Ho un errore Call to a member function query() on a non-object
    chiamato alla riga $this->result=$this->mysqli->query($q);Suppongo che l'obj mysqli non venga istanziato per qualche ragione.
    Ok, quindi il titolo che c'entra? sono praticamente certo che il problema sia lì

    Per risparmiare tempo ad interpretare il codice: non fa altro che prelevare una tupla dal db in base ad un id (preso da $_GET['page'] o "1" di default)

    Codice PHP:
    <?php

    class Conf {
        protected 
    $dbhost='localhost';
        protected 
    $dbname='db';
        protected 
    $dbuser='root';
        protected 
    $dbpass='';


    }
    class 
    Db extends Conf{
        private 
    $mysqli;
        public 
    $result;


        function 
    __construct(){
            
    $this->mysqli= new mysqli($this->dbhost,$this->dbuser,$this->dbpass,$this->dbname); 
        }
        public function 
    query($q){
            
    $this->result=$this->mysqli->query($q);
            return 
    $this->result;
        }
    }

    /*---model----------------*/
    class ModContent extends Db{
        private 
    $table;
        function 
    __construct($tab){
            
    $this->table=$tab;
        }

        function 
    selectContent($pageid){
            
    $query="SELECT * FROM page WHERE id='".$pageid."'";
            
    $result=$this->query($query);
            return 
    $result;
        }

    }

    /*---control----------------*/
    class ControlContent extends ModContent {
        function 
    getContent($pageid){
            
    $result=$this->selectContent($pageid);
            
    $content=$result->fetch_assoc();
            return 
    $content;
        }
        function 
    __construct(){
            
    parent::__construct('page');
        }
    }

    $pageid=(isset($_GET['page']))?$_GET['page']:1;
    $cc=new ControlContent();
    $content=$cc->getContent($pageid);


    print_r($content); ?>
    Ultima modifica di jimbo0; 01-12-2015 a 02:05

  2. #2
    Quando fai l'override di un metodo (in questo caso il costruttore), tieni presente che il PHP non chiama automaticamente il parent: devi farlo tu.

    Codice PHP:
    /*---model----------------*/
    class ModContent extends Db{    
        private 
    $table;    function __construct($tab){
                
    $this->table=$tab;    
                
    parent::__construct(); // <------- qui!
        
    }
        function 
    selectContent($pageid){
            
    $query="SELECT * FROM page WHERE id='".$pageid."'";
            
    $result=$this->query($query);        
           return 
    $result;
        } 
    Inoltre se vuoi uno spunto di riflessione: l'ereditarietà al 90% è male. (vedi la prima fonte in italiano che ho trovato https://it.wikipedia.org/wiki/Compos...ditariet%C3%A0 )

    Tecnicamente il controller non è un database: perché estendi la classe Database per crearlo? Sono due cose diverse e come tali devono essere trattate. Buon proseguimento.

    UPDATE: inoltre occhio alle Sql injection. https://it.wikipedia.org/wiki/SQL_injection
    Ultima modifica di chumkiu; 01-12-2015 a 10:51

  3. #3
    Utente di HTML.it
    Registrato dal
    Oct 2011
    Messaggi
    590
    quindi per risolvere l'errore i due costruttori diventano:
    Codice PHP:
    class ModContent extends Db{
        private 
    $table;
        function 
    __construct($tab){
            
    $this->table=$tab;
            
    parent::__construct();
        }
    }
    class 
    ControlContent extends ModContent {
        function 
    __construct(){
            
    parent::__construct('page');
        }


    Tecnicamente il controller non è un database: perché estendi la classe Database per crearlo? Sono due cose diverse e come tali devono essere trattate. Buon proseguimento.
    quindi come suggerisci di strutturare la cosa? (in realtà sto seguendo una guida su youtube per mvc in php che fa questo, ha lasciato perplesso anche me)

  4. #4
    Scusa mi ero dimenticato di questo post


    Dunque Database, Controller e Model sono 3 oggetti diversi. Quindi 3 classi differenti.


    Il Controller si preoccupa di gestire gli input dell'utente, quindi non ha bisogno del database. Non lo deve manco vedere

    E' Il Model quello che si preoccupa di prendere e modellare i dati. E' lui ad avere bisogno del database.


    Una ipotesi di MVC


    Codice PHP:
    <?php
    class Db {
        public function 
    __construct() {

        }

        public function 
    connect($host$user$pass$db) {

        }

        
    // altri metodi per il db
        
    public function fetchRow($qry) {

        }
    }

    // il Model si preoccupa di prendere i dati e ritornarli
    class Model {
        protected 
    $db;

        public function 
    __construct(Db $db) {
            
    $this->db $db;
        }

        public function 
    fetchPageInfo($pageId) {
            return 
    $this->db->fetchRow("SELECT * FROM page WHERE id = ? ", array($pageId));
        }
    }


    // il Controller ha in mano tutti gli strumenti per controllare il flusso
    // prende gli input (GET, Url) e cerca di capire cosa deve fare.
    // una volta che ha capito cosa fare, utilizza il Model e la View per fare ciò che deve
    class Controller {

        protected 
    $post;
        protected 
    $get;

        
    // Model e View li passo nel costruttore. Così li ha sempre disponibili
        
    public function __construct(Model $ModelView $View) {
            
    $this->Model $Model;
            
    $this->View  $View;
        }

        
    // questo giusto per non far accedere alle variabili superglobali
        
    public function setInput($post$get) {
            
    $this->post $post;
            
    $this->get  $get;
        }

        
    // il metodo che decide cosa fare
        
    public function run($url) {
            
    // facciamo finta che: tutti gli url devono essere del tipo /page/?id=xx
            
    if (stripos($url"/page/") !== false) {
                
    // prendo l'id (eventualmente fai il check dell'esistenza)
                
    $pageId $this->get['id'];

                
    // qui utilizzo il model. E' lui che deve darmi i dati dal database
                
    $page $this->Model->fetchPageInfo($pageId);

                
    // ora che ho i dati, dico alla View di stamparla nel modo che ritiene opportuno
                
    $this->View->printPage($page);
            } else {
                
    // se l'url non è del tipo /page/?id=xx => not found
                
    $this->View->notFound();
            }
        }

    }

    class 
    View {
        
    // qui magari puoi passare una istanza di un template engine (Smarty o quel che vuoi)
        // per semplicità facciamo solo echo
        
    public function __construct() {

        }

        public function 
    notFound() {
            
    header("HTTP/1.0 404 Not Found");
            echo 
    "page not found";
        }

        public function 
    printPage($page) {
            echo 
    "<h1>{$page['title']}</h1>\n";
            echo 
    "<p>{$page['html']}</p>";
        }
    }

    // qui preparo tutto l'occorrente
    $db = new Db();
    $db->connect("localhost","root","root","mydb");

    $Model = new Model($db);
    $View  = new View();

    $Controller = new Controller($Model$View);

    // Conviene che sia il main ad avere accesso alle GET e POST
    $Controller->setInput($_POST$_GET);

    // Eseguo l'url corrente. Anche qui, lo passo dal Main e non lo faccio prendere dall'oggetto
    $Controller->run($_SERVER['REQUEST_URI']);

    Questa è una ipotesi. Ci sono altri esempi dove è il Model a interagire con la View (a me personalmente non piace e non so quanto sia corretto)
    Però le regole del pattern MVC sono rispettate.

    - Il model fornisce i metodi per accedere ai dati
    - Il View visualizza i dati per il client
    - Il controller gestisce i due metodi a seconda dei dati in input

    I tre compiti sono separati.

    Controller -> Sa cosa fare ma non dove prendere i dati e come mostrarli
    Model->Sa dove prendere i dati, ma non sa quando e men che meno mostrarli
    View-> Sa come mostrare i dati che riceve, ma non sa da dove vengono e perché.

    In questo caso è il main che instanzia tutti gli oggetti e poi li passa agli oggetti di competenza (crea il db che viene dato al Model, crea il Model e il View che vengono dati al Controller).
    C'è chi li fa istanziare direttamente dagli oggetti, ma in questo caso crei una forte dipendenza che personalmente non mi piace.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.