2011-11-22 102 views
11

我对PHP中的构造函数如何工作有点困惑。PHP的构造函数和静态函数

我有一个构造函数,当我实例化一个新的对象时被调用的类。

$foo = new Foo($args); 

__construct($params)是所谓的类Foo并执行相应的初始化代码。

但是,当我使用该类来调用一个静态函数时,再次调用该构造函数。

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

这将导致构造函数执行,运行,我只打算当我创建一个新的Foo对象的对象初始化代码。

我错过了构造函数的工作原理吗?或者当我使用该类进行静态函数调用时,有没有办法阻止__construct()执行?

我应该用“工厂”函数来做对象初始化吗?如果是这样,那么构造函数的重点是什么?

::编辑:: 我有一个表格,用户可以上传照片到相册(create_photo.php)和他们可以查看专辑(view_photos.php)的区域。表格提交后:

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

Photo构造函数创建并保存照片。然而在view_photo.php中,当我打电话时:

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

这是造成Photo的构造函数运行!

+8

这是不对的。请提供构造函数被静态调用调用的完整代码! – mAu

+0

显示您的真实代码。你写的东西看起来不正确。 –

+0

构造函数的外观如何,您认为它运行的是什么行为? – markus

回答

16

我没有看到任何复制你的问题。

见演示:http://codepad.org/h2TMPYUV

代码:

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

echo Foo::bar(); //output: "there" 
+2

不应该是'__construct()'?结果是一样的,虽然... – jeroen

+0

@ jeroen固定^ _ ^很好的捕获 – Neal

6

假设 PHP 5。因为我们创建了一个新的对象PHP调用X

不同的目标,不同的路径

  1. 创建一个类(对象)的新实例

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

    __construct($par);

    新对象的

    ,所以:

    $a->lv == 11 
    
    $b->lv == 63 
    
  2. 使用类

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

    的功能现在$rf == "Hi."

    功能或variabiles必须定义的静态由::访问,没有创建任何对象调用“psf”,“类变量”sv hasl在课堂内部1个实例。

  3. 使用由工厂创建一个单身(myClassA以上)

    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"; 
    

使用工厂(的getInstance)第一次,我们构造具有$ PAR集到一个新的对象gino

第二次使用该工厂$单身已经有一个我们返回的值。没有创建新对象(没有调用__construct,使用更少的内存& cpu)。

课程的值是一个对象}这种 myClassA不要忘记:

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

讲究单身:

What is so bad about singletons?

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

通过我的答案如果我不想提升/降级单身人士。只需从问题中的单词,我做了这个计算:

“static”+“__ construct”=“singleton”!

+0

你应该添加关于singletons ans tatic类的免责声明:http://stackoverflow.com/questions/137975/what-is-so-bad -about-singletons和http://www.youtube.com/watch?v=-FRm3VPhseI –

+0

只是为了澄清$ g = myClassC :: getInstance(“gino”);然后$ p = myClassC :: getInstance(“pino”); ,$ g-> lv和$ p-> lv值是相同的=“gino”。不是gine和pino,因为构造函数只运行一次! – Miguel

1

这里是我的解决办法

我把方法construct()在静态类。请注意,它与我在常规课程中使用的__construct()不同。

每个类都在自己的文件中,所以我首次使用类时会延迟加载该文件。这给了我第一次使用类的事件。

spl_autoload_register(function($class) { 

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

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