Search code examples
phpfat-free-framework

build model structure - Fat Free Framework


I'm creating model structure with f3 but towards to end I stuck. I cant access to my functions another page.

Here is error:

Fatal error: Call to a member function load() on null [C:/UwAmp/www/test/app/models/User.php:12]

Where is wrong? Is this way good or not?

-models
----Model.php
----User.php

-controllers
----Controller.php
----UserController.php

UserController.php

class UserController extends Controller {


    private $_usermodal;

    public function __construct(){
      parent::__construct();
    }

    function Register(){

        $this->_usermodal = new User();
        $this->_usermodal->getAll();
    }

}

Model.php

class Model {

    private $db;

    public function __construct($table){

        $this->db=new DB\SQL(
            'mysql:host=localhost;port=3306;dbname=database',
            'root',
            'root'
        );

        return new DB\SQL\Mapper($this->db,$table);
    }


}

User.php (model)

class User extends Model {

    public function __construct(){
        parent::__construct('users');

    }

    public function getAll(){
        $x = $this->db->load('id = 1');
        print_r($x);
    }
}

Solution

  • Instead of returning a mapper instance from the __constructor (which is not possible in PHP), you could extend the framework mapper:

    Model.php:

    class Model extends DB\SQL\Mapper {
    
        protected $db;
    
        public function __construct($table) {
            $this->db=new DB\SQL(
                'mysql:host=localhost;port=3306;dbname=database',
                'root',
                'root'
            );
            parent::__construct($this->db,$table);
        }
    
    }
    

    User.php:

    class User extends Model {
    
        public function __construct() {
            parent::__construct('users');
        }
    
        public function getAll() {
            return $this->find('',['order'=>'id']);
        }
    
    }
    

    Now you can access your db records using the usual mapper methods:

    $user = new User;
    $user->load(['id=?',1]);
    // or
    foreach ($user->find(['name LIKE ?','%John%']) as $u)
      echo $u->name;
    

    or using your custom methods:

    foreach ($user->getAll() as $u)
      echo $u->name;
    

    This structure can still be improved though as it creates a new DB\SQL instance for every fetched record. You could create a central DB service and use it by default in Model:

    Index.php:

     $f3->DB = function() {
         if (!Registry::exists('DB')) {
             $db=new DB\SQL(
                 'mysql:host=localhost;port=3306;dbname=database',
                 'root','root');
             Registry::set('DB',$db);
         }
         return Registry::get('DB');
     };
    

    Model.php:

    class Model extends DB\SQL\Mapper {
    
        public function __construct($table,$db=NULL) {
            if (!isset($db)) {
                $f3=\Base::instance();
                $db=$f3->DB();
            }
            parent::__construct($db,$table);
        }
    
    }