为了账号安全,请及时绑定邮箱和手机立即绑定

重新定义类方法或类

重新定义类方法或类

皈依舞 2019-09-24 16:13:56
有没有不用典型继承就可以重新定义类或其某些方法的方法?例如:class third_party_library {    function buggy_function() {        return 'bad result';    }    function other_functions(){        return 'blah';    }}我该怎么做才能代替buggy_function()?显然这是我想做的class third_party_library redefines third_party_library{    function buggy_function() {        return 'good result';    }    function other_functions(){        return 'blah';    }}这是我的两难选择:我更新了破坏我的代码的第三方库。我不想直接修改该库,因为将来的更新可能会再次破坏代码。我正在寻找一种无缝的方法来替换类方法。我发现这个库说可以做到,但是我很警惕,因为它已经有4年的历史了。编辑:我应该澄清的是,由于框架的限制,我不能将类从重命名为third_party_libraryto magical_third_party_library或其他任何名称。就我的目的而言,是否可以向类中添加一个函数?我认为您可以在C#中使用“部分类”来完成此操作。
查看完整描述

3 回答

?
慕容3067478

TA贡献1773条经验 获得超3个赞

runkit似乎是一个不错的解决方案,但默认情况下未启用它,并且其中的一部分仍处于试验阶段。因此,我一起砍掉了一个小类,该小类替换了类文件中的函数定义。用法示例:


class Patch {


private $_code;


public function __construct($include_file = null) {

    if ( $include_file ) {

        $this->includeCode($include_file);

    }

}


public function setCode($code) {

    $this->_code = $code;

}


public function includeCode($path) {


    $fp = fopen($path,'r');

    $contents = fread($fp, filesize($path));

    $contents = str_replace('<?php','',$contents);

    $contents = str_replace('?>','',$contents);

    fclose($fp);        


    $this->setCode($contents);

}


function redefineFunction($new_function) {


    preg_match('/function (.+)\(/', $new_function, $aryMatches);

    $func_name = trim($aryMatches[1]);


    if ( preg_match('/((private|protected|public) function '.$func_name.'[\w\W\n]+?)(private|protected|public)/s', $this->_code, $aryMatches) ) {


        $search_code = $aryMatches[1];


        $new_code = str_replace($search_code, $new_function."\n\n", $this->_code);


        $this->setCode($new_code);


        return true;


    } else {


        return false;


    }


}


function getCode() {

    return $this->_code;

}

}

然后包括要修改的类并重新定义其方法:


$objPatch = new Patch('path_to_class_file.php');

$objPatch->redefineFunction("

    protected function foo(\$arg1, \$arg2)

    {   

        return \$arg1+\$arg2;

    }");

然后评估新代码:


eval($objPatch->getCode());

有点粗糙,但可以!


查看完整回答
反对 回复 2019-09-24
  • 3 回答
  • 0 关注
  • 499 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信