Когда я использую статические переменные / функции в php? - PullRequest
71 голосов
/ 11 августа 2009

Я обновляю себя в ООП с помощью PHP, и я видел пример установки функций и / или переменных как статических. Когда и почему я должен установить переменную / функцию в static? Я делал другие языки и никогда не вспоминал когда-либо используя static, я никогда не находил для него реальной цели. Я знаю, что он делает, но почему бы просто не использовать вместо него переменную?

Ответы [ 8 ]

54 голосов
/ 11 августа 2009

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

  • Нет связи с вашей целью и экземпляром (полезно для наборов инструментов в языках, которые не допускают ничего, кроме ООП, таких как Java, но бесполезно в PHP).

  • Вы хотите контролировать доступ к экземпляру. Чаще всего экземпляр, с которым вы хотите иметь дело, не определяется при написании кода, но будет при исполнении. Лучшим примером является Singleton pattern . Вы можете использовать статические методы как фабрики для создания объекта в соответствии с контекстом или совместного использования ресурсов с другими экземплярами. E.G: статический член может предоставить доступ к слою базы данных, поэтому часть приложения получает доступ к нему из любого места и открывается / закрывается без конфликтов.

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

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

Идеальный пример - анализатор строк:

class MyObject 
{
 static function parse($str)
 {
    $obj = new MyObject();
    // some parsing/setting happens here
    return $obj;
 }
}

// you create an object "MyObject" from a string, so it's more obvious
// to read it this way :
$new_obj = MyObject::parse("This a description of a super cool object");
22 голосов
/ 11 августа 2009

Статические функции и переменные используются для доступа к переменным / функциям в глобальной области видимости, например:

echo myClass::myVariable;
echo myClass::myFunction();

Когда что-то статично, к нему можно получить доступ где угодно, и оно очень похоже на функцию процедурного типа, за исключением того, что оно может использовать self и содержится в области видимости классов.

class myClass{
    static $myVariable = "myVar";
    static function myFunction()
    {
       return "myFunc";
    }
}

Один из способов использовать это - сохранить только один экземпляр класса или метод Singleton.

class myClass
   {
    static $class = false;
    static function get_connection()
    {
        if(self::$class == false)
        {
            self::$class = new myClass;
        }
        else
        {
            return self::$class;
        }
    }
    private function __construct()
    {
         // my constructor
    }
    // Then create regular class functions.
   }

Поскольку у него есть закрытый конструктор, его нельзя создать с помощью оператора new, поэтому вы вынуждены вызывать myClass::get_connection(), чтобы получить класс. Эта функция может создать новый класс (потому что он является членом класса). Затем он сохраняет класс в статической переменной, и если вы снова вызовете функцию, он просто вернет созданный класс.

В конце концов, ключевое слово static используется, чтобы держать вещи, ну, в общем, статичные, в отношении объема. Это означает, что вам не нужно ничего «менять» из-за текущей области видимости. Хотя метод Singleton немного растягивает это, он придерживается той же идеи, что у вас всегда есть «один и тот же» класс, независимо от того, в какой области вы находитесь.

PHP Документация
Статическое ключевое слово
Оператор разрешения области действия

StackOverflow Knowledge
Как избежать использования глобальных объектов PHP
Обмен переменными между функциями в PHP без использования глобальных переменных
Создание глобальной переменной, доступной для каждой функции внутри класса
Global или Singleton для подключения к базе данных
Классы PHP: когда использовать :: vs. ->?

10 голосов
/ 12 апреля 2012

Также очень полезно для кэширования, если метод будет вызываться очень часто и делать то же самое, например:

/**
 * Returns true if the user is logged in through shibboleth
 *
 * @return boolean true on success, else false
 */
protected function is_logged_in() {

    //Check shibboleth headers
    if (!empty($_SERVER['HTTP_SHIB_IDENTITY_PROVIDER']) || !empty($_SERVER['Shib-Identity-Provider'])) {
        if (!empty($_SERVER[$this->core->dbconfig("shib_auth", self::SHIB_AUTH_CONFIG_UID)])) {
            return true;
        }
    }
    return false;
}

Этот метод будет вызываться в моей среде очень часто, и там он будет делать для каждого вызова поиск в базе данных для моей конфигурации $ _SERVER key

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

/**
 * Returns true if the user is logged in through shibboleth
 *
 * @return boolean true on success, else false
 */
protected function is_logged_in() {
    static $logged_in = null;
    if($logged_in != null) {
        return $logged_in;
    }

    //Check shibboleth headers
    if (!empty($_SERVER['HTTP_SHIB_IDENTITY_PROVIDER']) || !empty($_SERVER['Shib-Identity-Provider'])) {
        if (!empty($_SERVER[$this->core->dbconfig("shib_auth", self::SHIB_AUTH_CONFIG_UID)])) {
            $logged_in = true;
            return true;
        }
    }
    $logged_in = false;
    return false;
}

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

Надеюсь, это поможет.

7 голосов
/ 11 августа 2009

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

Из должности:

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

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

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

3 голосов
/ 08 декабря 2015

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

1 голос
/ 20 декабря 2017

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

  1. Во-первых, они доступны в любом месте вашего скрипта (при условии, что у вас есть доступ к классу). Это означает, что вы можете получить доступ к функциональности без необходимости передавать экземпляр класса от объекта к объекту или, что еще хуже, сохранять экземпляр в глобальной переменной.

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

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

0 голосов
/ 27 июля 2016

Если вы хотите поделиться данными со всеми экземплярами, например, счетчик количества экземпляров, созданных при текущем выполнении.

0 голосов
/ 13 октября 2015

Визит: http://verraes.net/2014/06/when-to-use-static-methods-in-php/

Статические методы - не более чем глобальные функции с пространством имен. Пространство имен, я думаю, что мы все можем согласиться, отлично. Что касается глобальных функций: мы используем их постоянно. Нативные функции в PHP формируют наши основные строительные блоки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...