Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 6 of 6

Thread: Static fever?

  1. #1
    Regular Coder
    Join Date
    Nov 2006
    Posts
    247
    Thanks
    13
    Thanked 26 Times in 24 Posts

    Static fever?

    I find myself using "static method classes" whenever possible, and I find that I can a lot of the time. This is usually when dealing with a database. I'll usually create a static method class full of methods aimed at doing specific things to a specific section of a website: grabbing, inserting, updating, deleting, creating forms, validating forms, etc.. There's really 2 reasons for me doing it this way. The first is that it simply sounds easier and looks cleaner, but more importantly, these classes can end up getting knotted; as in, using one another. For that reason, I usually also use a static Database class, as oppose to a singleton or other. This way I don't have to worry about if I'm someday gonna be hit with going from one database to two or more. I don't find this to be a bad thing, despite what you see a lot of articles on the internet saying about static method classes. I've always just been curious as to what others opinions are on "overusing static classes."

  • #2
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,994
    Thanks
    4
    Thanked 2,662 Times in 2,631 Posts
    There are no static classes in PHP, only static methods and members. Exception to this goes against static scoped variables within a function/method in which case it refers to persistency instead. Unlike C, static cannot be used in global scope to create private variables.

    Static should only be used where an instance of a class is illogical or where you can return an instance of a class without altering the initial class instance(s). In the event that data should be contained and altered on unique instances, then static should not be used. Keep in mind that static members reflect across all instances of a class, and are not contained to a single class instance. For this reason, you can never have a static User if a User can also look up information about another User (otherwise the User will always be either 1 or the other, but never both).
    In the event that you have created a class with only static members and static methods, you have essentially created a singleton anyway, except that a Singleton is a multiple usage of a single instance instead of single usage of a single class. Every single use of such a class is always reflective of any other use of the same class. If you have a single MySQLDriver class for example thats completely static, you can never incorporate 2 or more MySQL databases in the same application with this specific driver without altering connectivity on the fly. This seems like a huge waste, leaving these classes open for instance creation would allow me to make use of 2, 3, 4, 10, or however many different MySQL databases I want.

    Static variables are resolved at compile-time, and I'd assume the same goes for members though probably not methods. This could explain deterioration with your execution times. Another thing to consider is that PHP < 5.3.0 suffers from lack of late static binding, so you cannot make use of a parent static override by a child. This is a huge turnoff.

    If I had to guess it, I'd say that an average class I write contains 5 - 8% static members and methods, except with collections which are more towards the 10 - 15% for merging techniques. Other than that, chances are I don't need that many static methods or members.
    PHP Code:
    header('HTTP/1.1 420 Enhance Your Calm'); 
    Been gone for a few months, and haven't programmed in that long of a time. Meh, I'll wing it ;)

  • #3
    Regular Coder
    Join Date
    Nov 2006
    Posts
    247
    Thanks
    13
    Thanked 26 Times in 24 Posts
    I think my biggest confusion that threw me down this road is not really having a good answer to creating an instance of a Database class and having access to it on a global scale. I don't wanna have to create multiple connections to a single database, so my solution was, "I'll create a class with a bunch of static methods and call one connection in the global.php file like Database::connect('host', 'user', 'pass', 'db'); and then be able to call query and result methods anywhere like Database::query('SELECT * FROM wherever');." This seems like a BAD way of doing it, and does limit you to one connection.

    Is there a better way of doing this; where I can create an instance of a Database object, and be able to access it whenever like I do now, so I can do something like:

    PHP Code:
    class Articles
    {
        public static function 
    getArticleForId($id)
        {
            
    $result Database::result('SELECT * FROM articles WHERE id = '.$id.' LIMIT 1');
            return 
    $result;
        }

    I think it makes sense to have selecting methods like this accessible on the fly, without needing to create an instance of the class.

    I'd also appreciate a bit of insight on the difference between using the "static" keyword and not using it, as well static methods being accessed in a created instance of a class.
    Last edited by Majoracle; 06-22-2010 at 10:01 PM.

  • #4
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,994
    Thanks
    4
    Thanked 2,662 Times in 2,631 Posts
    What your goal is in OOP is to contain only as much as a class itself needs. So, with what you have here, I'd pass Articles your desired storage. I myself use an interface for storage that I simply call IStorage that reflects SQL handling through part building (fields, conditions and whathaveyous).
    Then, if I have an Articles class, I'd simply do:
    PHP Code:
    class Articles
    {
        private 
    $is;
        public function 
    __construct(IStorage $is)
        {
            
    $this->is $is;
        }

        public function 
    getArticleForId($id)
        {
            return 
    $this->is->result('SELECT * FROM articles WHERE id = ' $id ' LIMIT 1');
        }
    }

    $s = new DatabaseStorage('host''user''pass''db''whatever'); // Typeof IStorage
    $a = new Articles($s);

    print_r($a->getArticleForId(1));

    // Change it up to a different IStorage:
    $s = new XMLStorage('pathtofile.xml');
    $a = new Articles($s);

    print_r($a->getArticleForId(1));

    // ... and so forth 
    Swapping of storage engine isn't something you can do easily with static members and methods.
    PHP Code:
    header('HTTP/1.1 420 Enhance Your Calm'); 
    Been gone for a few months, and haven't programmed in that long of a time. Meh, I'll wing it ;)

  • #5
    Regular Coder
    Join Date
    Nov 2006
    Posts
    247
    Thanks
    13
    Thanked 26 Times in 24 Posts
    Alright, that makes sense. I don't really get this IStorage thing though.

  • #6
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,994
    Thanks
    4
    Thanked 2,662 Times in 2,631 Posts
    IStorage is just an interface I made up to represent all my storage methods. Its something like this:
    PHP Code:
    interface IStorage
    {
        public function 
    open();
        public function 
    close();
        public function 
    select();
        
    // ... and so forth
    }

    class 
    MySQLDriver implements IStorage
    ....
    class 
    XMLDriver implements IStorage
    ....
    class 
    SQLServerDriver implements IStorage
    .... 
    And so forth. Since each driver implements IStorage, any application making use of it doesn't care its implementation details. I have a wrapping class thats job is to provide a build for each of these types, so running a select works find since it requires each part provided through the destinct query builder.
    PHP Code:
    header('HTTP/1.1 420 Enhance Your Calm'); 
    Been gone for a few months, and haven't programmed in that long of a time. Meh, I'll wing it ;)


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •