PHP 构造函数和静态函数

发布于 2024-12-17 11:49:23 字数 867 浏览 0 评论 0原文

我对 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..);

照片构造函数创建并保存照片。但是在 view_photo.php 中,当我调用:

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

这导致 Photo 的构造函数运行!

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!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

甜妞爱困 2024-12-24 11:49:23

我没有看到任何与你的问题重复的内容。

请参阅演示:http://codepad.org/h2TMPYUV

代码:

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

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

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"
白色秋天 2024-12-24 11:49:23

假设
PHP 5.x

不同的目标,不同的路径

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

    类 myClassA
    {
       公共 $lv;
    
       公共函数 __construct($par)
       {
           echo "构造函数内部\n";
           $this->lv = $par;
       }
    }
    
    $a = new myClassA(11);
    $b = 新 myClassA(63);
    

    因为我们创建了一个新对象 PHP 调用:

    __construct($par);

    新对象,所以:

    <前><代码>$a->lv == 11

    $b->lv == 63

  2. 使用类的函数

    类 myClassB
    {
        公共静态$sv;
    
        公共静态函数 psf($par)
        {
            自我::$sv = $par;
        }
    }
    
    myClassB::psf("你好!");
    $rf = &myClassB::$sv;
    myClassB::psf("嗨。");
    

    现在$rf ==“嗨。”

    函数或变量必须定义静态才能被::访问,没有调用“psf”创建对象,“类变量”sv内部只有1个实例类。

  3. 使用工厂创建的单例(上面是myClassA)

    类 myClassC
    {
    
        私有静态$singleton;
    
        公共静态函数 getInstance($par){
    
            if(is_null(self::$singleton)){
    
                self::$singleton = new myClassA($par);
    
            }
    
            返回自我::$singleton;
    
        }
    
    }
    
    $g = myClassC::getInstance("gino");
    echo "得到G\n";
    
    $p = myClassC::getInstance("pino");
    echo "得到P\n";
    

第一次构造具有 $par 的新对象时使用工厂 (getInstance) > 设置为吉诺

第二次使用工厂 $singleton 已经有我们返回的值。没有创建新对象(没有调用__construct,使用更少的内存和CPU)。

当然,值是一个对象 instanceOf myClassA 并且不要忘记:

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

注意单例:

单例有什么不好?

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

通过我的回答我不想提升/降级单身人士。简单地根据问题中的文字,我进行了计算:

“static”+“__construct”=“singleton”!

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

む无字情书 2024-12-24 11:49:23

这是我的解决方法

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

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

spl_autoload_register(function($class) {

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

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

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();
    }
});
|煩躁 2024-12-24 11:49:23

我在静态方法中将类属性定义为数组,并通过该方法调用它们。我不确定这是否是最好的解决方案,但效果很好。

例子:

    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

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文