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

报告相同问题?

悬赏问题

  • ¥15 win2012磁盘空间不足,c盘正常,d盘无法写入
  • ¥15 用土力学知识进行土坡稳定性分析与挡土墙设计
  • ¥70 PlayWright在Java上连接CDP关联本地Chrome启动失败,貌似是Windows端口转发问题
  • ¥15 帮我写一个c++工程
  • ¥30 Eclipse官网打不开,官网首页进不去,显示无法访问此页面,求解决方法
  • ¥15 关于smbclient 库的使用
  • ¥15 微信小程序协议怎么写
  • ¥15 c语言怎么用printf(“\b \b”)与getch()实现黑框里写入与删除?
  • ¥20 怎么用dlib库的算法识别小麦病虫害
  • ¥15 华为ensp模拟器中S5700交换机在配置过程中老是反复重启