panique / mini

Just an extremely simple naked PHP application, useful for small projects and quick prototypes. Some might call it a micro framework :)
1.35k stars 479 forks source link

[USEFUL! :)] Multiple Models #195

Open coyarzun2013 opened 9 years ago

coyarzun2013 commented 9 years ago

Hi everyone:

First of all, this is an awesome tiny php script, really great work.

For those who want to use this script with multiple Models, i´ll give you some little changes in the controller.php file

the new constructor function look like this

function __construct() { //getting the className of the Controller who extends controller class $class = get_called_class(); $this->openDatabaseConnection(); //passing this classname as parameter to loadModel Function $this->loadModel($class); }

then in loadModel Function

/* * Loads the "model". * @return object model / public function loadModel($class=null) { (string)$modelFile = strtolower($class); $instanceClass = $class.'Model'; require APP . 'model/'.$modelFile.'.php'; // create new "model" (and pass the database connection) $this->model = new $instanceClass($this->db); }

and finally, declare your model Class name as 'nameModel' for example homeModel, songsModel, etc. and thats it!!!

deathbeam commented 9 years ago

Yey awesome, I vouch for this. :+1:

betweenbrain commented 9 years ago

This is very exciting, I look forward to testing it.

sanjayrup commented 9 years ago

Hello,

We can have both single, and multiple model.

I have use this exemple for multiple model, and make the older script has $this->utils for shared functions.

I can post a exemple if needed !

ponsundar commented 9 years ago

This one is what I am looking for.. :) Love you guys.. This peice of work is good. One more thing, I have customized mini to support sessions and logins. Shall I Commit the code? Will that be useful?

skrecker commented 9 years ago

@coyarzun2013 I have implemented this technique in my project. I actually thought this was implemented in previous versions of the project. I see that this issues has not been closed. I would like to submit changes for this if you are no longer working on the changes.

However, I would make a few changes. The loadModel() method does not need to be so verbose. I would suggest something like this:

 /**
     * Loads the "model".
     * @return object model
     */
    public function loadModel($model_name)
    {

require APP . 'model/' . strtolower($model_name) . '.php';

        return new $model_name($this->db);
    }

As a general suggestion, I would space out your concatenated strings such as: "$instanceClass = $class.'Model';" Instead do, $instanceClass = $class . 'Model'; So that it doesn't look like a method call that you'd see in other languages.

Also, I would suggest keeping the model class and extending it to classes using it. So the model would simply be:

class Model
{
    /**
     * @param object $db A PDO database connection
     */
    function __construct($db)
    {
        try {
            $this->db = $db;
        } catch (PDOException $e) {
            exit('Database connection could not be established.');
        }
    }

This way you can include other methods that you will share across all other models extending the base class.

In order to show how this works l would create a new class, SongsModel, to show the method examples such as getAllSongs, etc.

Let me know what you think.

ghost commented 8 years ago

great work but why only a single model? yes there previous version had multiple models. too make it makes an awesome code so limited. I hope someday to see this update for those of use not using Slim. cheers.

panique commented 8 years ago

Hi @mynumbercrunching , because thats the most simple case! when this project had multiple model-classes people were asking to merge everything to one class, now it has one class and people ask to split it to multiple classes. :) it's always a little bit tricky when software is designed by a community.

Personally I think it's okay to stay with one class for now as it's the most simple solution possible and it will work for most users who only need <10 database calls. I you need multiple models, then please have a look at the above solution.

By the way, this script does not use Slim, it's 100% pure native PHP. :)

sanjayrup commented 8 years ago

ahahahaha ! In my case, i have made a shared model classes, && a multiple classe for each controller ! ;)

jaonoctus commented 8 years ago

@panique Can you tell me what was the commit where this project was still wearing multiple models?

skrecker commented 8 years ago

@JaoNoctus I'm not sure what commit had the multiple models but it's not that much different. You just need to change the controller class, this way everything else will still be up to date.

In the controller class:

   /**
     * Loads the "model".
     * @return object model
     */
    public function loadModel($model_name)
    {
        require APP . 'model/model.php';
        require APP . 'model/' . strtolower($model_name) . '.php';

        return new $model_name($this->db);
    }

When you create a new model just extend the model class.
jaonoctus commented 8 years ago

Thank you @skrecker :smile:

jaonoctus commented 8 years ago

@skrecker If i try to load 2 models that extends Model, the application returns the error:

mod_fcgid: stderr: PHP Fatal error:  Cannot redeclare class Model

The right way would be this:

require_once APP . 'model/model.php';
skrecker commented 8 years ago

@JaoNoctus You're right. I've been using only one model in my controllers. Thank you

jaonoctus commented 8 years ago

@coyarzun2013 @skrecker @mynumbercrunching @sanjayrup @betweenbrain I Implemented the PSR-4 autoloader to use multiple models and controllers, look:

jaoNoctus/mini

bestdamnfriend commented 8 years ago

Using this code, I seem to have problems with MINI's default 'Home' model class being loaded, as there is already a controller with the class name 'Home'.

Fatal error: Cannot redeclare class Home

I need to change the loadModel() function to the following:

public function loadModel($model_name = null) {

    require_once APP . 'model/model.php';
    require_once APP . 'model/' . strtolower($model_name) . 'Model.php';

    $model = $model_name . 'Model';
    return new $model($this->db);

}

And then ensure I name my model class 'HomeModel', and the file 'homeModel.php'.

panique commented 8 years ago

Good point! This will be fixed with MINI3, where a model is named xxxModel and a controller xxxController! Thanks for the report & code!