Static concept

I’m fairly familiar with class instances and MVC, but I fear that I have been doing something kindof silly for a while, for example, this:


class Page
{
   function __construct()
   {
       require 'date.class.php';
       $this->date_obj = new Date;

       // other unrelated stuff
   }
}

// to do a date operation
$page = new Page;
$find_date = $page->date_obj->addTime($some_date, "1 week"); 

The bit I am concerned/confused about is the way I am accessing the Date object via the Page class. I generally will not access classes in this manner, however I wanted the date methods accessible everywhere, and I know that $page is accessible virtually everywhere.

What I have suspected for awhile, and just got around to confirming today is that:

$find_date = $page->date_obj->addTime($some_date, "1 week");

is equivalent to

$find_date = Date::addTime($some_date, "1 week");

My assumption was always that :: indicates accessing a static method, however this seems to be completely wrong. The only difference is that if I had a constructor on Date it would not run without instantiating the class.

So now that I can trim a few thousand characters out of of my files (I love you Find and Replace), just curious whether, for example, my Date class would be a candidate for static methods - which is another concept I am struggling to grasp. The Date class just performs a bunch of operations using php time stamps, it doesn’t need to know about the rest of the application.

This quote I read is kindof flipping my head around:

it’s unnecessary to create an object instance for no other reason than to call a method and then throw away the object.

ding - I think a little light bulb in my head lit up!

great example thanks.

Let me shine some light on this for you :slight_smile:

You want to have classes with static methods and properties when the methods that interact with each other are used only on ONE set of data at the same time

A good example would be:


<?php

// Very simple profiler that calculates how many 'full seconds'
// elapse between startTime and endTime
// Useless in real life but works fine for here!
class StaticProfiler{
        private static $start;
        public static function startTime(){
                self::$start = time();
        }

        public static function endTime(){
                $start = self::$start;
                self::$start = false;
                return $start - time();
        }
}

// The same class as above, except it works on multiple sets of
// data because it's instantialized
class Profiler{
        private $start;
        public function startTime(){
                $this->start = time();
        }

        public function endTime(){
                return $this->start - time();
        }
}

// Let's profile a million queries
StaticProfiler::startTime();
for($i=0; $i<1000000; $i++){
        $result = mysql_fetch_assoc(mysql_query( "..." ));
        // Let's assume we're also doing some sort of action
        // over here that needs to be profiled
        //
        // StaticProfiler::startTime();
        //
        // Using the static profiler here would be WRONG
        // as it will reset the timer!!! Instead we want
        // to use the non-static profiler to profile
        // individual iterations seperately :-)
        $profiler = new Profiler()->startTime();

        [...]

        echo $profiler->endTime();
}
echo StaticProfiler::endTime();

The comments give details on when and why to use the instantialized class rather than the static class.

I hope this helps you understand all of this :slight_smile: