dongxi0605 2015-01-05 23:07
浏览 47
已采纳

_call用于PHP中的受保护方法

I have protected methods (Set_SelectedElementStyle and Set_SelectedElementAttribute) that accept some (exactly 4 - but last is not demanded) arguments.

Those arguments are:

  • order - number that means index of element that will get some attributes or styles
  • element - element
  • name - name of attribute or style
  • value - value of attribute or style (not demanded - then style is ignored and attribute may be empty)

I thought that I would use not-existing function with name would containing name of element and word style or attribute (that would mean which of above called method will be used) to simplify their calling.

Argument order would be prepared and set inside method __call I wanted to use to call that not-existing method.

Calling of not-existing function could be (for example - but this is non-sense - because XML tag does not need formatting)

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

But I read elsewhere in Stackoverflow that this leads to FATAL error.

So, what else way to use to call those protected functions in a way I thought.

Edit:

one of two protected methods with four arguments

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

that is called by public method where two of four arguments are extracted from other conditions

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

or else (and elsewhere - in else class) public method for usage of protected one written above. This accept three arguments.

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);
    }
}
  • 写回答

1条回答 默认 最新

  • donglun2010 2015-01-05 23:51
    关注

    You can use __call here. But please be aware that in most cases there is no need of using methods with 4 arguments or more. Uncle Bob in "Clean Code" recommends max 3 parameters and 1 or 2 are the best. You can achieve this for example by encapsulating arguments to one object.

    Example code for your case:

    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')
    );
    

    Effect of var_dump will be as follow:

    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)
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥40 复杂的限制性的商函数处理
  • ¥15 程序不包含适用于入口点的静态Main方法
  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码