PHP объединил статический и нестатический классы с двумя отдельными классами

У меня есть класс PHP для создания тегов HTML. Каждый тег HTML становится новым экземпляром. У меня есть некоторые служебные методы, необходимые в классе для обработки определенных функциональных вещей, таких как экранирование атрибутов, и для настройки определенных параметров, влияющих на все экземпляры. Я объявляю утилиты и public static, а внутри класса я использую self:: для вызова служебных методов. Как вы думаете, лучше держать все методы в одном классе или создать отдельный статический класс для утилит и иметь его таким образом, чтобы основной класс расширял статический (чтобы я мог вызывать методы с self::)? Как лучше всего поступить в такой ситуации? (в PHP 5.2 и выше) Интерфейс класса выглядит следующим образом:

foo('div')->attr('id', 'example')->html('this is inner text')->get();

foo('img')->attr(array('src' => 'example.png', 'alt' => 'example'))->get();

Пример базового кода:

public function attr($name, $value = '')
{
    if (is_scalar($name))
    {
        if (empty($name) && !is_int($name)) $this->attrs[] = $value; 
        else $this->attrs[$name] = $value;
    }
    else
    {
        foreach ((array) $name as $k => $v)
        {
            $this->attr($k, $v);
        }
    }
    return $this;
}

// handler (doesn't get called until it's time to get)
public static function attr_encode($name, $value = '')
{
    if (is_scalar($name))
    {
        if (is_int($name)) return self::attr_encode($value, '');
        $name = preg_replace(self::ATTR_NAME_INVALIDS, '', $name);
        if ('' === $name)  return '';
        if (1 === func_num_args() || '' === $value) return $name;

        $value = is_null($value) ? 'null' : ( !is_scalar($value) ? (
                 self::supports('ssv', $name) ? self::ssv_implode($value) : json_encode($value)) : (
                 is_bool($value) ? (true === $value ? 'true' : 'false') : self::esc_attr($value)));

         return $name . "='" . $value . "'";     // Use single quotes for compatibility with JSON.
    }

    // Non-scalar - treat $name as key/value map:
    $array = array();
    foreach ((array) $name as $attr_name => $attr_value)
    {
        self::push($array, true, self::attr_encode($attr_name, $attr_value));
    }
    return implode(' ', $array);
}

person ryanve    schedule 04.05.2012    source источник
comment
Размещение всего кода в 1 классе — это не ООП. Можете ли вы показать код, в котором вы не уверены, что делать?   -  person Wouter Dorgelo    schedule 04.05.2012
comment
Добавлен пример @Mr.Palazzo. Если утилиты относятся к классу Foo, то разве они не относятся к классу Foo? Как это не ООП?   -  person ryanve    schedule 04.05.2012
comment
Статические методы следует использовать с осторожностью. Чрезмерное использование статики — это запах кода. Только представьте, что слово «статический» заменено на «глобальный», и вы должны понять, почему.   -  person GordonM    schedule 04.05.2012
comment
Каждый тег HTML становится новым экземпляром. - Если вы имеете в виду то, что я думаю, вы имеете в виду, ваши функции должны возвращать $this, а не создавать новый экземпляр.   -  person AndrewR    schedule 04.05.2012
comment
@AndrewR Они есть - посмотрите на мой пример выше.   -  person ryanve    schedule 04.05.2012
comment
@GordonM Зачем сравнивать статическое с глобальным?   -  person ryanve    schedule 05.05.2012
comment
Я также хотел бы получить ваши ответы на другой вопрос PHP здесь: static-contexts" title="методы php, которые работают как в созданном, так и в статическом контексте"> stackoverflow.com/questions/10442668/   -  person ryanve    schedule 05.05.2012


Ответы (3)


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

Когда использовать статические и созданные классы

Также.. Вы писали:

Интерфейс класса такой:

Интерфейсы в PHP/ООП — это нечто другое. Интерфейсы заставляют программиста использовать определенные методы в классах.

person Wouter Dorgelo    schedule 04.05.2012
comment
Я не сомневаюсь, что мне нужны статические методы. Я пытаюсь решить, лучше ли включить их в основной класс или создать отдельный класс, который будет чисто статическим, и расширить основной класс из него. - person ryanve; 05.05.2012
comment
Создайте отдельный класс, который является чисто статическим :-) В этом случае проще использовать этот статический код в другом месте, если это необходимо. - person Wouter Dorgelo; 05.05.2012
comment
Теперь они разделены, и да, я думаю, так будет лучше. У меня это так, что нестатический расширяет статический, так что я могу использовать self:: для вызова утилит оттуда. - person ryanve; 17.05.2012

Похоже, вы создаете что-то похожее на классы LINQ to XML: http://broadcast.oreilly.com/2010/10/understanding-c-simple-linq-to.html#example_1 или http://phphaml.sourceforge.net/

Возможно, есть какие-то стили интерфейса, которые вы можете адаптировать.

person Community    schedule 04.05.2012
comment
Круто - спасибо - приятно знать. То, что я делаю, немного проще. Я опубликую ссылку, когда она будет у меня на Github. - person ryanve; 08.05.2012

Я создаю собственный проект PHP5 HMVC, в котором использую некоторую библиотеку, используя STATIC с пространствами имен:

\Project\library\output::set_header_status(100);

Но представьте вашу проблему:

  • Я хочу добавить функции перед вызовом некоторых функций или избежать:

    $output = \Project\library\output->log(true, 'directory_log_of_header/');
    
    \Project\library\output::set_header_status(100);
    

Значит, была проблема. Эти примеры не работают. Вместо этого примера функции я буду избегать этого, используя STATIC, и буду использовать $this и вызывать новый экземпляр.

Если мне нужно добавить какую-то функцию, поместить некоторые переменные и подготовиться к вызову функции. Она должна использовать non-static использование экземпляра.


Я использую метод STATIC только для прямого вызова функции без предварительной функции подготовки, установки переменных или для счетчиков или установки переменной, которая действительно требует использования статики. Например, это может быть вызов данных GET/POST или прямой пример вызова CLEARING CACHE (например, удаление кеша из файлов напрямую без нестатического).

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

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

    Используйте STATIC, только если функции предлагают небольшие задачи, напрямую захватывая данные, которые не часто изменяются, или для небольших задач в качестве переменных, фиктивных данных (например, версии, проверки, счетчики, средства проверки), для алгоритмов HASH и тому подобное.

person Marin Sagovac    schedule 12.04.2013