Какие веские причины использовать статические методы в PHP? - PullRequest
14 голосов
/ 14 января 2011

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

Ответы [ 5 ]

8 голосов
/ 14 января 2011

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
4 голосов
/ 14 января 2011

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

3 голосов
/ 14 января 2011

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

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

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

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

function getUsers()
{
     $users = StaticClass::getDatabaseConnection()->query('SELECT * FROM users');
}
2 голосов
/ 14 января 2011

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

$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. Класс обработчика файлов может не всегда хотеть создать новый объект (скажем, переданный файл не существует или не может быть открыт).

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

0 голосов
/ 14 января 2011

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

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