Использование статических свойств в PHP> = 4.3.0? - PullRequest
5 голосов
/ 13 января 2010

Отказ от ответственности: Да, я вынужден поддерживать PHP 4.3.0.Я знаю, что он мертв.Нет, я не могу обновить его, потому что я имею дело с несколькими серверами, некоторые из которых не имеют доступа su.

Ну, поскольку я не могу использовать self::, так как это PHP5конкретно, как я должен идти о реализации статики в классе PHP4?Из моего исследования кажется, что я могу по крайней мере использовать ключевое слово static, кроме как только в контексте функции, я видел другой метод, использующий $ _GLOBALS, но я не думаю, что буду использовать это.

Просто для того, чтобы мы были на одной странице, мне нужно получить доступ к этой статистике PHP5 в 4:

public static $_monthTable = array(
     31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
public static $_yearTable = array(
     1970 => 0,            1960 => -315619200);

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

class DateClass {

    function statics( $name = null ) {

        static $statics = array();

        if ( count( $statics ) == 0 ) {
            $statics['months'] = array(
                'Jan', 'Feb'
            );
        }

        if ( $name != null && array_key_exists($name, $statics ) ) {
            return $statics[$name];
        }
    }

};

var_dump( DateClass::statics('months') );

Вопрос № 1: Возможно ли это?Должен ли я попробовать использовать другой метод?

Вопрос № 2: Как бы я ссылался на статику из метода в том же классе?Я пытался __CLASS__::statics, но я думаю, __CLASS__ - это просто строка, поэтому я не вызываю метод.

Примечание: Я буду реализовывать это в рамках, которые будутиспользоваться на Apache2 + / IIS6 +, PHP4.3.0 до PHP 5.2, OSX / Linux / Windows.

Ответы [ 2 ]

4 голосов
/ 13 января 2010

Отвечая на ваш первый вопрос, я думаю, что ваше решение хорошее. Я бы расширил его так, чтобы переменные также могли быть установлены и не установлены. Я бы также по-разному «заправил» статические $ statics, значение неустановленных переменных по умолчанию равно null.

<?php
class DateClass {
  function statics( $name, $value=null, $unset=null ) {
    static $statics;
    // better way to "prime" $statics, it's null by default
    if ( !$statics ) {
      $statics = array( "months" => array( "Jan", "Feb" ) );
    }
    if ( $value )
      $statics[ $name ] = $value;
    if ( $unset )
      unset( $statics[ $name ] );
    // don't worry about checking for existence
    // values of unset variables and array keys always are null
    // that's what you should return
    return $statics[ $name ];
  }
}

Что касается вашего второго вопроса, вы можете использовать DateClass::statics() где угодно, даже внутри других методов (статических или нет) из DateClass. PHP4 также позволяет вам вызывать DateClass::statics() как метод экземпляра, даже если вы не должны этого делать. (Можно также вызывать методы экземпляра статически, если во внешней области видимости есть $ this. Это не красиво, и вам определенно не следует этого делать; -)

Если вы действительно хотите, чтобы вызов DateClass был более динамичным, вы можете использовать call_user_func , это просто немного более многословно.

<?php
class DateClass {
  function statics( ... ) { ... }
  function anotherStaticFunc() {
    var_dump( DateClass::statics( 'months' ) );
    // using __CLASS__ and call_user_func
    var_dump(
      call_user_func( array( __CLASS__, 'statics' ), 'months' )
    );
  }
  function instanceMethod() {
    var_dump( $this->statics( 'months' ) );
  }
}
2 голосов
/ 13 января 2010

В общем, плохая идея эмулировать языковые функции. Поскольку PHP 4 не поддерживает статические свойства, я бы не рекомендовал вам использовать что-то умное, чтобы оно выглядело как-будто. Я бы сказал, что наиболее естественным является использование глобальных переменных. По сути, это и есть статическое свойство - оно просто в пространстве имен. Так что используйте соглашение о пространстве имен, чтобы минимизировать риск столкновения имен, и вы по сути будете иметь то же самое. Например. вместо:

class Foo {
  static $ninja = 42;
}

Вы можете использовать

$GLOBALS['foo_ninja'] = 42;
...