Welcome Guest, Not a member yet? Register   Sign In
Where to put plain object classes?
#21

(This post was last modified: 12-28-2014, 04:04 PM by sneakyimp. Edit Reason: fixed quote blocks )

(12-27-2014, 07:57 PM)includebeer Wrote: Code redundancy and bugs? It's only one line of code. I can live with one redundant line!
I'm curious what kind of bugs you had with include/require you don't have with an autoloader.
I find it interesting that you somehow get away with only using one include/require in all of your files. I've got code related to user purchases that must include/require a lot of stuff:
* site-wide configuration for values that are not part of the framework (e.g., email credentials for SendGrid, payment gateway credentials, cloud credentials)
* Payment gateway library (e.g., paypal, authorize.net, possibly other)
* functionality to forward user to the optimal next page for purchasing behavior
* classes to get/set user access levels based on purchased digital property
* classes to create purchase-related database items for user (subscriptions, authorizations, orders)
* class to create payment journal entries for accounting
* class for error logging

I'm looking at one of my legacy files now with 13 require_once statements in it. CodeIgniter should help a lot by its clever structure and autoloading, but at least half of those includes will not go away. My legacy code has 2032 require_once statements in it. Surely we can agree that a dozen lines of autoloading code in a pre-system hook would be better? You have to admit it would result in less code redundancy. The other advantage it provides is lazy loading. The autoload function only requires the file when PHP actually encounters some usage of the corresponding class.

The errors I encountered usually happen when some useful code was used in a new context -- in a cron job, for instance. While the script that is accessed via apache might run just fine because the script handling apache requests has already included a few base classes, when I try to use the same function in a cron job, that cron job's different execution path might not have included these base classes. Failure to include/require some class often times becomes evident during testing, but in complex code, an infrequently-executed branch of code might not do it properly.  Specifically, this is the error I'm talking about:
Code:
Fatal error: Class 'Foo' not found in /var/www/erep_v2/chump.php on line 3

The solution? Manually dig around and sort out your require/include statements like a caveman. I like autoloading better.

(12-27-2014, 07:57 PM)includebeer Wrote: You can pass arguments to the loader class in the second parameter:
$params (array) – Optional array of parameters to pass to the loaded library’s constructor
I'm aware you can pass one parameter to your constructor using this method and I still say it's silly. Am I supposed to rewrite all of my classes such that their constructor takes only one array parameter? What is the rationale for this subversion of PHP's power by limiting my constructors to one parameter? Silly, silly, silly. Also, what about static classes that are never supposed to be instantiated?

(12-27-2014, 07:57 PM)includebeer Wrote: Maybe I'm too old school, but I don't understand why people have trouble doing simple things just because they use a framework. What would you do in plain PHP? If CI doesn't provide what you're trying to do then do it in plain PHP.
I'm old school in certain ways too. Personally, I think the automatic instantiation of a loaded library is a convenience I don't need and don't want -- especially if I must rewrite all my library classes to extract constructor parameters from a single parameter. I do want an autoloader. That way, I can get rid of those 2000+ require/include statements and get to the actual coding.
Reply
#22

(12-28-2014, 01:07 PM)sneakyimp Wrote: I do want an autoloader. That way, I can get rid of those 2000+ require/include statements and get to the actual coding.

Then write an autoloader! What can I say?

The original question is "what's the correct place to put a plain object class file?" and right now there's no way to load a class without creating a singleton and there's no autoloader in CI. That's why I use require and that's why I say that if the framework doesn't provide what you need, code it yourself.

This is turning into a debate on autoloaders...
Reply
#23

Yes sorry for the kvetching and moaning. The autoloader question does relate to the 'where do I put stuff' question. One could easily suffer problems if a) lots of require statements start appearing in one's code or b) the autoloader function is scanning too many directories for every class it tries to instantiate.

I'm still a little puzzled by the first responses in this thread:
Rufnex Wrote:You have to put it into /application/library because its your own class.
dmyers Wrote:Rufnex is correct, just as a side note thou:
You would of course use $this->load->library('PlainObject'); to load this class and of course this would automatically attach it to the CI super object as a singleton. $this->plainobject->method(); etc...

Such certitude in that statement! Does this mean I'm never supposed to put my own classes in Model? I have a MY_data_object class that all my db classes inherit from which prevents me from having to write fetch/update/insert/delete functions for every single model class I have. That is my own class but seems like a very good candidate for the model directory.
Reply
#24

Quote:Does this mean I'm never supposed to put my own classes in Model?
Of course not! The Libraries directory is for general classes not directly linked to the database model.

For your data_object class, you can extend the CI_Model class by renaming it MY_Model and putting it in application/core.
 
PHP Code:
MY_Model extends CI_Model 
Reply
#25

I could extend CI_Model, I suppose, but why would I do this? The class doesn't look especially feature-rich. All it does is write a log message when constructed and then define a __get magic method that refers to the CodeIgniter singleton. I could be completely missing something, but I wonder why I would want to have my DataObjects coughing up properties of the CI singleton object as if those properties were its own? What happens when my DataObject defines a property that already belongs to the CI singleton?
Code:
class CI_Model {

    /**
     * Class constructor
     *
     * @return    void
     */
    public function __construct()
    {
        log_message('debug', 'Model Class Initialized');
    }

    // --------------------------------------------------------------------

    /**
     * __get magic
     *
     * Allows models to access CI's loaded classes using the same
     * syntax as controllers.
     *
     * @param    string    $key
     */
    public function __get($key)
    {
        // Debugging note:
        //    If you're here because you're getting an error message
        //    saying 'Undefined Property: system/core/Model.php', it's
        //    most likely a typo in your model code.
        return get_instance()->$key;
    }

}
Reply
#26

@sneakyimp

Offtopic a little, anyway:

"I could extend CI_Model, I suppose, but why would I do this?" - an example: https://github.com/jamierumbelow/codeigniter-base-model

"What happens when my DataObject defines a property that already belongs to the CI singleton?" - I have never hit such case, but if it happens, it could be easily resolved. Most probable candidate is the 'config' property, so within the constructor you can write $this->ci_config = get_instance()->config;
Reply
#27

(12-28-2014, 08:40 PM)sneakyimp Wrote: I could extend CI_Model, I suppose, but why would I do this?

Because it would become your base model with the commons functions available to all your models.
Reply
#28

(12-29-2014, 05:26 AM)includebeer Wrote: Because it would become your base model with the commons functions available to all your models.

You apparently missed this in my prior post:
sneakyimp Wrote:All it does is write a log message when constructed and then define a __get magic method that refers to the CodeIgniter singleton. I could be completely missing something, but I wonder why I would want to have my DataObjects coughing up properties of the CI singleton object as if those properties were its own? What happens when my DataObject defines a property that already belongs to the CI singleton?
Reply
#29

(12-29-2014, 09:33 AM)sneakyimp Wrote: All it does is write a log message when constructed and then define a __get magic method that refers to the CodeIgniter singleton.

What's your point? You don't want to use the CI_Model class at all?


Quote:I could be completely missing something, but I wonder why I would want to have my DataObjects coughing up properties of the CI singleton object as if those properties were its own? What happens when my DataObject defines a property that already belongs to the CI singleton?

Why would it cough up CI properties?
Reply
#30

(12-30-2014, 10:11 AM)includebeer Wrote: Why would it cough up CI properties?

Code:
    public function __get($key)
    {
        // Debugging note:
        //    If you're here because you're getting an error message
        //    saying 'Undefined Property: system/core/Model.php', it's
        //    most likely a typo in your model code.
        return get_instance()->$key;
    }

That's what this code does. The primary purpose of extending CI_Model is more or less to utilize this function, usually for the purposes of accessing $this->db from within your model.
Reply




Theme © iAndrew 2016 - Forum software by © MyBB