web-dev-qa-db-ja.com

静的クラスをPHP(C#のように)で作成することは可能ですか?

PHPに静的クラスを作成し、C#のように動作させたいので、

  1. コンストラクターは、クラスの最初の呼び出しで自動的に呼び出されます
  2. インスタンス化は不要

この種の何か...

static class Hello {
    private static $greeting = 'Hello';

    private __construct() {
        $greeting .= ' There!';
    }

    public static greet(){
        echo $greeting;
    }
}

Hello::greet(); // Hello There!
134
aleemb

PHPに静的クラスを含めることはできますが、コンストラクターは自動的に呼び出されません(self::__construct()を呼び出そうとするとエラーが発生します)。

したがって、initialize()関数を作成し、各メソッドで呼び出す必要があります。

<?php

class Hello
{
    private static $greeting = 'Hello';
    private static $initialized = false;

    private static function initialize()
    {
        if (self::$initialized)
            return;

        self::$greeting .= ' There!';
        self::$initialized = true;
    }

    public static function greet()
    {
        self::initialize();
        echo self::$greeting;
    }
}

Hello::greet(); // Hello There!


?>
195
Greg

Gregの答えに加えて、コンストラクターをprivateに設定して、クラスをインスタンス化できないようにすることをお勧めします。

私の謙虚な意見では、これはグレッグのものに基づいたより完全な例です:

<?php

class Hello
{
    /**
     * Construct won't be called inside this class and is uncallable from
     * the outside. This prevents instantiating this class.
     * This is by purpose, because we want a static class.
     */
    private function __construct() {}
    private static $greeting = 'Hello';
    private static $initialized = false;

    private static function initialize()
    {
        if (self::$initialized)
            return;

        self::$greeting .= ' There!';
        self::$initialized = true;
    }

    public static function greet()
    {
        self::initialize();
        echo self::$greeting;
    }
}

Hello::greet(); // Hello There!


?>
50
Phil

これらの「静的な」クラスを持つことができます。しかし、本当に重要なものが欠けていると思います:phpではアプリサイクルがないため、アプリケーション全体で本当の静的(またはシングルトン)を取得することはできません...

PHPのシングルトン を参照してください

24
final Class B{

    static $staticVar;
    static function getA(){
        self::$staticVar = New A;
    }
}

bの構造はシングルトンハンドラーと呼ばれます。

Class a{
    static $instance;
    static function getA(...){
        if(!isset(self::$staticVar)){
            self::$staticVar = New A(...);
        }
        return self::$staticVar;
    }
}

これはシングルトン使用$a = a::getA(...);

4
borrel

私は通常、通常の非静的クラスを記述し、ファクトリクラスを使用してオブジェクトの単一(Sudo static)インスタンスをインスタンス化することを好みます。

このようにコンストラクタとデストラクタは通常どおり動作し、必要に応じて追加の非静的インスタンスを作成できます(たとえば、2番目のDB接続)

私はこれを常に使用しており、ページが終了するとデストラクタがデータベースにセッションをプッシュするため、カスタムDBストアセッションハンドラを作成するのに特に役立ちます。

別の利点は、すべてがオンデマンドでセットアップされるので、物事を呼び出す順序を無視できることです。

class Factory {
    static function &getDB ($construct_params = null)
    {
        static $instance;
        if( ! is_object($instance) )
        {
            include_once("clsDB.php");
            $instance = new clsDB($construct_params);   // constructor will be called
        }
        return $instance;
    }
}

DBクラス...

class clsDB {

    $regular_public_variables = "whatever";

    function __construct($construct_params) {...}
    function __destruct() {...}

    function getvar() { return $this->regular_public_variables; }
}

あなたがそれを使用したいところはどこでも呼び出します...

$static_instance = &Factory::getDB($somekickoff);

次に、すべてのメソッドを非静的として扱います(なぜなら、それらは)

echo $static_instance->getvar();
3
dave.zap

オブジェクトを静的に定義することはできませんが、これは機能します

final Class B{
  static $var;
  static function init(){
    self::$var = new A();
}
B::init();
2
borrel