19

I'm a bit confused on how constructors work in PHP.

I have a class with a constructor which gets called when I instantiate a new object.

$foo = new Foo($args);

__construct($params) is called in the class Foo and it executes the appropriate initialization code.

However when I use the class to call a static function, the constructor is called again.

$bar = Foo::some_function(); //runs the constructor from Foo

This causes the constructor to execute, running the object initialization code that I intended only for when I create a new Foo object.

Am I missing the point of how constructors work? Or is there a way to prevent __construct() from executing when I use the class to make static function calls?

Should I use a "factory" function instead to do the object initialization? If so, what's the point of the constructor then?

::EDIT:: I have a form where users can upload photos to an album (create_photo.php) and an area where they can view the album (view_photos.php). Upon form submit:

$photo = new Photo($_FILES['photo'], $_POST['arg1'], ect..);

The Photo constructor creates and saves the photo. However in view_photo.php, when I call:

$photo = Photo::find_by_id($_POST['id']) //user-defined function to query database

This is causing Photo's constructor to run!

6
  • 8
    That can't be right. Please provide the full code where the constructor gets called by a static call! Commented Nov 22, 2011 at 17:43
  • Show your real code. What you're writing doesn't look correct. Commented Nov 22, 2011 at 17:43
  • How does the constructor look like, from what behaviour do you conclude that it runs? Commented Nov 22, 2011 at 18:02
  • "Show your code" means "show us all the code that is relevant to the situation". At the very least this includes the class definition, of the offending class, or at least the relevant function definitions inside the class definition. Commented Nov 22, 2011 at 18:07
  • 2
    The Photo::find_by_id static method is probably creating new Photo object. Commented Nov 22, 2011 at 18:31

4 Answers 4

26

I see nothing that replicates your question.

See Demo: http://codepad.org/h2TMPYUV

Code:

class Foo {
    function __construct(){ 
        echo 'hi!';
    }
    static function bar(){
        return 'there';
    }
}

echo Foo::bar(); //output: "there"
Sign up to request clarification or add additional context in comments.

Comments

6

Assumption PHP 5.x

Different goals, different path

  1. create a new instance of a class (object)

    class myClassA
    {
       public $lv;
    
       public function __construct($par)
       {
           echo "Inside the constructor\n";
           $this->lv = $par;
       }
    }
    
    $a = new myClassA(11);
    $b = new myClassA(63);
    

    because we create a new object PHP calls:

    __construct($par);

    of the new object, so:

    $a->lv == 11 
    
    $b->lv == 63
    
  2. use a function of a class

    class myClassB
    {
        public static $sv;
    
        public static function psf($par)
        {
            self::$sv = $par;
        }
    }
    
    myClassB::psf("Hello!");
    $rf = &myClassB::$sv;
    myClassB::psf("Hi.");
    

    now $rf == "Hi."

    function or variabiles must defined static to be accessed by ::, no object is created calling "psf", the "class variable" sv has only 1 instance inside the class.

  3. use a singleton created by a Factory (myClassA is above)

    class myClassC
    {
    
        private static $singleton;
    
        public static function getInstance($par){
    
            if(is_null(self::$singleton)){
    
                self::$singleton = new myClassA($par);
    
            }
    
            return self::$singleton;
    
        }
    
    }
    
    $g = myClassC::getInstance("gino");
    echo "got G\n";
    
    $p = myClassC::getInstance("pino");
    echo "got P\n";
    

Using the factory (getInstance) the first time we construct a new object having $par set to gino.

Using the factory the second time $singleton has already a value that we return. No new object is created (no __construct is called, less memory & cpu is used).

The value of course is an object instanceOf myClassA and don't forget:

myClassC::$singleton->lv == "gino"

Pay attention to singletons:

What is so bad about singletons?

http://www.youtube.com/watch?v=-FRm3VPhseI

By my answer I don't want promote/demote singleton. Simply from the words in the question, I made this calc:

"static"+"__construct"="singleton"!

2 Comments

you should have added a disclaimer regarding singletons ans tatic classes : stackoverflow.com/questions/137975/… and youtube.com/watch?v=-FRm3VPhseI
just to clarify $g = myClassC::getInstance("gino"); and then $p = myClassC::getInstance("pino"); , $g->lv and $p->lv values are the same = "gino". not gine and pino, because the constructor only run once!
2

Here is my workaround:

I put method construct() in static class. Notice, it is different than __construct() which I use in regular classes.

Each class is in own file, so I lazy load that file on first use of class. This gives me event of first use of class.

spl_autoload_register(function($class) {

    include_once './' . $class . '.php';

    if (method_exists($class, 'construct')) {
        $class::construct();
    }
});

1 Comment

If you want to call __construct method, it will be new $class()
0

I define class properties as array in a static method and call them via the method. I'm not sure if it's the best solution or not but works great.

Example:

    class Foo
    {
      private static construct_method()
      {
        return [
          'one' => 1,
          'two' => 2
        ];
      }

      public static any_method()
      {
        return self::construct_method()['one'] + self::construct_method()['two'];
      }

    }

    echo Foo::any_method(); // 3

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.