¿Es posible crear clases estáticas en PHP (como en C#)?


Quiero crear una clase estática en PHP y que se comporte como lo hace en C#, así que

  1. Constructor se llama automáticamente en la primera llamada a la clase
  2. No se requiere instanciación

Algo de este tipo...

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

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

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

Hello::greet(); // Hello There!
Author: aleemb, 2009-01-22

6 answers

Puede tener clases estáticas en PHP pero no llaman al constructor automáticamente (si intenta llamar a self::__construct() obtendrá un error).

Por lo tanto, tendría que crear una función initialize() y llamarla en cada método:

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


?>
 181
Author: Greg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-23 23:23:51

Además de la respuesta de Greg, recomendaría establecer el constructor privado para que sea imposible crear instancias de la clase.

Así que en mi humilde opinión este es un ejemplo más completo basado en el de Greg:

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


?>
 43
Author: Phil,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-07 10:31:39

Puedes tener esas clases "estáticas". pero supongo que falta algo realmente importante: en php no tienes un app-cycle, por lo que no obtendrás una estática real (o singleton) en toda tu aplicación...

Ver Singleton en PHP

 22
Author: Andreas Niedermair,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:02:38
final Class B{

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

La estructura de b es calld a singeton handler también se puede hacer en a

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

Este es el uso de singleton $a = a::getA(...);

 3
Author: borrel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-12-09 09:54:38

Generalmente prefiero escribir clases regulares no estáticas y usar una clase factory para crear instancias individuales ( sudo estáticas ) del objeto.

De esta manera, el constructor y el destructor funcionan de manera normal, y puedo crear instancias no estáticas adicionales si lo deseo ( por ejemplo, una segunda conexión de base de datos )

Uso esto todo el tiempo y es especialmente útil para crear manejadores de sesión personalizados de DB store, ya que cuando la página termina, el destructor empujará la sesión al base.

Otra ventaja es que puede ignorar el orden en el que llama las cosas, ya que todo se configurará a pedido.

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

La clase DB...

class clsDB {

    $regular_public_variables = "whatever";

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

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

En cualquier lugar que desee usarlo simplemente llame...

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

Entonces solo trata todos los métodos como no estáticos (porque lo son)

echo $static_instance->getvar();
 2
Author: dave.zap,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-12-30 21:43:21

El objeto no se puede definir de forma estática pero esto funciona

final Class B{
  static $var;
  static function init(){
    self::$var = new A();
}
B::init();
 1
Author: borrel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-11-29 15:46:27