Использование _call для защищенных методов в PHP

0

Я защитил методы (Set_SelectedElementStyle и Set_SelectedElementAttribute), которые принимают некоторые (ровно 4 - но последние не требуются) аргументы.

Этими аргументами являются:

  • order - number, который означает индекс элемента, который получит некоторые атрибуты или стили
  • элемент - элемент
  • name - имя атрибута или стиля
  • value - значение атрибута или стиля (не требуется - тогда стиль игнорируется, а атрибут может быть пустым)

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

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

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

$this -> Person_Style('font-family', 'Arial');

Но я читал в другом месте в Stackoverflow, что приводит к ошибке FATAL.

Итак, какой еще способ использовать эти защищенные функции так, как я думал.

Редактировать:

один из двух защищенных методов с четырьмя аргументами

protected function Set_SelectedElementStyles($Order, $Element, $Name, $Value="")
{
    try
    {
        if(empty($Order) && $Order != 0)
        {
            throw new MarC_Exception(UniCAT::UNICAT_EXCEPTIONS_MAIN_CLS, UniCAT::UNICAT_EXCEPTIONS_MAIN_FNC, UniCAT::UNICAT_EXCEPTIONS_MAIN_PRM, UniCAT::UNICAT_EXCEPTIONS_SEC_PRM_MISSING);
        }
    }
    catch(MarC_Exception $Exception)
    {
        $Exception -> ExceptionWarning(get_called_class(), __FUNCTION__, $Exception -> Get_Parameters(__CLASS__, __FUNCTION__)[0]);
    }

    try
    {
        if(!is_integer($Order))
        {
            throw new MarC_Exception(UniCAT::UNICAT_EXCEPTIONS_MAIN_CLS, UniCAT::UNICAT_EXCEPTIONS_MAIN_FNC, UniCAT::UNICAT_EXCEPTIONS_MAIN_PRM, UniCAT::UNICAT_EXCEPTIONS_SEC_PRM_WRONGVALTYPE);
        }
    }
    catch(MarC_Exception $Exception)
    {
        $Exception -> ExceptionWarning(get_called_class(), __FUNCTION__, $Exception -> Get_Parameters(__CLASS__, __FUNCTION__)[0], gettype($Order), 'integer');
    }

    try
    {
        if($Order < 0)
        {
            throw new MarC_Exception(UniCAT::UNICAT_EXCEPTIONS_MAIN_CLS, UniCAT::UNICAT_EXCEPTIONS_MAIN_FNC, UniCAT::UNICAT_EXCEPTIONS_MAIN_PRM, UniCAT::UNICAT_EXCEPTIONS_SEC_PRM_LOWNUMBER1);
        }
    }
    catch(MarC_Exception $Exception)
    {
        $Exception -> ExceptionWarning(get_called_class(), __FUNCTION__, $Exception -> Get_Parameters(__CLASS__, __FUNCTION__)[0], 0);
    }

    try
    {
        if(empty($Element))
        {
            throw new MarC_Exception(UniCAT::UNICAT_EXCEPTIONS_MAIN_CLS, UniCAT::UNICAT_EXCEPTIONS_MAIN_FNC, UniCAT::UNICAT_EXCEPTIONS_MAIN_PRM, UniCAT::UNICAT_EXCEPTIONS_SEC_PRM_MISSING);
        }
    }
    catch(MarC_Exception $Exception)
    {
        $Exception -> ExceptionWarning(get_called_class(), __FUNCTION__, $Exception -> Get_Parameters(__CLASS__, __FUNCTION__)[1]);
    }

    try
    {
        if(empty($Name))
        {
            throw new MarC_Exception(UniCAT::UNICAT_EXCEPTIONS_MAIN_CLS, UniCAT::UNICAT_EXCEPTIONS_MAIN_FNC, UniCAT::UNICAT_EXCEPTIONS_MAIN_PRM, UniCAT::UNICAT_EXCEPTIONS_SEC_PRM_MISSING);
        }
    }
    catch(MarC_Exception $Exception)
    {
        $Exception -> ExceptionWarning(get_called_class(), __FUNCTION__, $Exception -> Get_Parameters(__CLASS__, __FUNCTION__)[2]);
    }

    /*
     * sets styles;
     * Element - element name;
     * Order - number of position of element that will get style;
     * Name - style name;
     * Value - style value
    */
    $this -> ElementStyles_Selected[$Element][$Order][$Name] = $Value;
}

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

public function __call($Function, array $Parameters)
{


    $Options = array('Element_Style', 'Element_Attribute');

    try
    {
        if(!in_array($Function, $Options))
        {
            throw new MarC_Exception(UniCAT::UNICAT_EXCEPTIONS_MAIN_CLS, UniCAT::UNICAT_EXCEPTIONS_MAIN_FNC, UniCAT::UNICAT_EXCEPTIONS_MAIN_PRM, UniCAT::UNICAT_EXCEPTIONS_SEC_PRM_DMDOPTION);
        }
    }
    catch(MarC_Exception $Exception)
    {
        $Exception -> ExceptionWarning(get_called_class(), __FUNCTION__, $Exception -> Get_Parameters(__CLASS__, __FUNCTION__)[0], $Options);
    }

    if($Function == $Options[0])
    {
        $Element = split('_', $Function)[0];

        if($Element == $this -> Elements['top'])
        {
            call_user_func_array(array($this, 'Set_SelectedElementStyles'), array_unshift($Parameters, 0, $Element));
        }
        else
        {
            call_user_func_array(array($this, 'Set_SelectedElementStyles'), array_unshift($Parameters, array_flip($this -> Elements['sub'])[$Element], $Element));
        }
    }
    else
    {
        $Element = split('_', $Function)[0];

        if($Element == $this -> Elements['top'])
        {
            call_user_func_array(array($this, 'Set_SelectedElementAttributes'), array_unshift($Parameters, 0, $Element));
        }
        else
        {
            call_user_func_array(array($this, 'Set_SelectedElementAttributes'), array_unshift($Parameters, array_flip($this -> Elements['sub'])[$Element], $Element));
        }
    }
}

или (и в другом месте - в другом классе) общедоступный метод использования защищенного, написанный выше. Это принимает три аргумента.

public function Set_SubLevelAttributes($Order="", $Name="", $Value="")
{
    try
    {
        if(empty($Order) && $Order != 0)
        {
            throw new MarC_Exception(UniCAT::UNICAT_EXCEPTIONS_MAIN_CLS, UniCAT::UNICAT_EXCEPTIONS_MAIN_FNC, UniCAT::UNICAT_EXCEPTIONS_MAIN_PRM, UniCAT::UNICAT_EXCEPTIONS_SEC_PRM_MISSING);
        }
    }
    catch(MarC_Exception $Exception)
    {
        $Exception -> ExceptionWarning(get_called_class(), __FUNCTION__, $Exception -> Get_Parameters(__CLASS__, __FUNCTION__)[0]);
    }

    try
    {
        if(!is_integer($Order))
        {
            throw new MarC_Exception(UniCAT::UNICAT_EXCEPTIONS_MAIN_CLS, UniCAT::UNICAT_EXCEPTIONS_MAIN_FNC, UniCAT::UNICAT_EXCEPTIONS_MAIN_PRM, UniCAT::UNICAT_EXCEPTIONS_SEC_PRM_WRONGVALTYPE);
        }
    }
    catch(MarC_Exception $Exception)
    {
        $Exception -> ExceptionWarning(get_called_class(), __FUNCTION__, $Exception -> Get_Parameters(__CLASS__, __FUNCTION__)[0], gettype($Order), 'integer');
    }

    try
    {
        if($Order < 0)
        {
            throw new MarC_Exception(UniCAT::UNICAT_EXCEPTIONS_MAIN_CLS, UniCAT::UNICAT_EXCEPTIONS_MAIN_FNC, UniCAT::UNICAT_EXCEPTIONS_MAIN_PRM, UniCAT::UNICAT_EXCEPTIONS_SEC_PRM_LOWNUMBER1);
        }
    }
    catch(MarC_Exception $Exception)
    {
        $Exception -> ExceptionWarning(get_called_class(), __FUNCTION__, $Exception -> Get_Parameters(__CLASS__, __FUNCTION__)[0], 0);
    }

    try
    {
        if(empty($Name))
        {
            throw new MarC_Exception(UniCAT::UNICAT_EXCEPTIONS_MAIN_CLS, UniCAT::UNICAT_EXCEPTIONS_MAIN_FNC, UniCAT::UNICAT_EXCEPTIONS_MAIN_PRM, UniCAT::UNICAT_EXCEPTIONS_SEC_PRM_MISSING);
        }
    }
    catch(MarC_Exception $Exception)
    {
        $Exception -> ExceptionWarning(get_called_class(), __FUNCTION__, $Exception -> Get_Parameters(__CLASS__, __FUNCTION__)[1]);
    }

    /*
     * checks attribute name;
     * sets attribute to chosen element;
     * sets order to list of used orders
     */
    if($this -> Check_AttributeName($Name))
    {
        $this -> Set_SelectedElementAttributes($Order, $this -> Elements['sub']['set'], $Name, $Value);
        $this -> Set_OrderToList($Order);
    }
}
  • 0
    Почему ты так много делаешь {} catch {}? Это не то, как вы должны управлять исключениями. И каков точный вопрос? Потому что я думал, что вам нужен способ для вызова метода, подобного этому, но вы уже сделали это. Так?
  • 0
    @Arius: Я спросил, потому что я не был уверен, допустимо ли использовать __call для вызова __call метода - и если нет, то как это сделать другим способом. Слишком много исключений? Я бы не сказал. По крайней мере, это намного лучше читается - чем если бы была последовательность исключений, заключенная в одну.
Показать ещё 2 комментария
Теги:
oop

1 ответ

1
Лучший ответ

Вы можете использовать __call здесь. Но имейте в виду, что в большинстве случаев нет необходимости использовать методы с 4 аргументами или более. Дядя Боб в " Чистом коде " рекомендует максимум 3 параметра, а 1 или 2 - лучшие. Вы можете достичь этого, например, путем инкапсуляции аргументов в один объект.

Пример кода для вашего случая:

class TestClass
{
    public function __call($name, $arguments)
    {
        $nameArguments = explode('_', $name);
        $methodName = 'Set_SelectedElement'.$nameArguments[1];

        if(method_exists($this, $methodName) && count($arguments) > 1) {
            return $this->$methodName($nameArguments[0], $arguments[0], $arguments[1]);
        }

        return 'Noooooo.';
    }

    protected function Set_SelectedElementStyle($element, $name, $value = null)
    {
        return 'Style for '.$element.': '.$name.': '.$value;
    }

    protected function Set_SelectedElementAttribute($element, $name, $value = null)
    {
        return 'Attribute for '.$element.': '.$name.'="'.$value.'"';
    }
}

$testClass = new TestClass();

var_dump(
    $testClass->Person_Style('font-family', 'Arial'),
    $testClass->Element_Attribute('name', 'CustomName'),
    $testClass->Person_Style('font-family'),
    $testClass->Super_No('test', 'test')
);

Эффект var_dump будет следующим:

string 'Style for Person: font-family: Arial' (length=36)
string 'Attribute for Element: name="CustomName"' (length=40)
string 'Noooooo.' (length=8)
string 'Noooooo.' (length=8)
  • 0
    Я знаю, что функции с 4 или более аргументами являются адом, и я стараюсь избегать их использования. И для этого я определил этот метод с четырьмя аргументами как защищенный.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню