Каковы веские причины использования статических методов в PHP?

Есть ли у кого-нибудь хорошие примеры использования статических методов вместо динамических?

Ответ 1

Singleton:

class SingletonClass {
    private static $instance;
    private function __construct() { }
    public function __clone() {
        trigger_error('Clone is not allowed.', E_USER_ERROR);
    }
    public static function init() {
        if (!isset(self::$instance)) {
            $c = __CLASS__;
            self::$instance = new $c;
        }
        return self::$instance;
    }
    // other public, dynamic methods for singleton
}

$singleton = SingletonClass::init();

Количество следов экземпляров:

class CountMe {
    public static $instances = 0;
    public function __construct() {
        CountMe::$instances++;
    }
    public function __destruct() {
        CountMe::$instances--;
    }
}
$a = new CountMe();
$b = new CountMe();
echo CountMe::$instances; // outputs 2

Ответ 2

Если вам не нужен доступ к членам экземпляра.

Ответ 3

Соединение с базой данных будет полезно использовать для статической функции. Вам не нужен прямой доступ ко всему объекту БД, вам просто нужен доступ к ресурсу подключения. Поэтому вы можете позвонить

 $connection = new DatabaseConnection();
 StaticClass::setDatabase($connection);
 $result = StaticClass::getDatabaseConnection()->query();

Но если вам нужен доступ к классу для хранения позже или несколько экземпляров одного и того же объекта, вы не захотите статически ставить.

Ваш класс также теперь живет в глобальной области действия, поэтому вы можете получить к нему доступ из любого класса в любой области в любом месте вашей кодовой базы.

function getUsers()
{
     $users = StaticClass::getDatabaseConnection()->query('SELECT * FROM users');
}

Ответ 4

В менее кодово-ориентированном характере, вот как я определяю статические методы (я буду использовать банк в качестве примера): Если у вас был банковский класс и вы хотели бы открыть новый банк, вы будете использовать:

$b = new Bank;

Теперь скажем, вы хотели добавить нового сотрудника в этот банк. Просто позвоните:

$b->addEmployee( 'Person' );

Поскольку вы применяете действие к банку, который вы создали, а не к компании, которой принадлежит банк в целом, вы используете метод участника. Теперь позвольте сказать, что компания торгует некоторыми активами и зарабатывает деньги. Чтобы обновить их общие деньги, вы бы назвали это:

Bank::addToCompanyBalance( 1000000 );

Обратите внимание, что, поскольку действие не просто применяется к банку, который мы создали, мы использовали вместо него статический метод.

Этот пример очень упрощен, но мне нравится аналогия. В более программном смысле статические члены хороши для:

Синглтоны

class Singleton
    private static $instance;

    private function __construct() {}
    private function __clone() {}

    public static function getInstance() {
        if( !isset( self::$instance ) ) self::$instance = new IamOne;
        return( self::$instance );
    }
}

Создание классов, которые могут выйти из строя
Ex. Класс обработчика файлов может не всегда создавать новый объект (скажем, что переданный файл не существует или не может быть открыт).

С абстрактными классами
Некоторые классы могут не иметь экземпляров (например, маршрутизатор, который интерпретирует запрос пользователя). Однако абстрактные классы можно назвать статически и поэтому могут использовать статические методы.

Ответ 5

Пример. Используйте статические методы для создания экземпляров объекта, которые могут принимать разные аргументы.

Class DBConnection
{
    public static function createFromConfiguration(Configuration $config)
    {
        $conn = new DBConnection();
        $conn->setDsn($config->getDBDsn());
        $conn->setUser($config->getDBUser());
        $conn->setPassword($config->getDBPass());

        return $conn;
    }

    public static function newConnection($dsn, $user, $password)
    {
        $conn = new DBConnection();
        $conn->setDsn($dsn);
        $conn->setUser($user);
        $conn->setPassword($password);

        return $conn;
    }
}