Php 如何从库类重写私有方法
下面给出了类Php 如何从库类重写私有方法,php,overriding,private,Php,Overriding,Private,下面给出了类A来自的类,因此我无法更改它: class A { public function test () { $this->privateMethod(); } private function privateMethod () { echo('A'); } } class B extends A { private function privateMethod () { echo('B');
A
来自的类,因此我无法更改它:
class A {
public function test () {
$this->privateMethod();
}
private function privateMethod () {
echo('A');
}
}
class B extends A {
private function privateMethod () {
echo('B');
}
}
$b = new B();
$b->test();
这导致A
由A::privateMethod
而不是B::privateMethod
打印出来,因为后者对A::test
不可见
否则,我如何才能以最干净的方式修改此私有库方法的行为(例如,复制整个类并对其进行更改时不会出现代码重复)?这是因为
private
仅在类本身的范围内。如果您使用了protected
,您会重写该函数,因为protected
方法意味着它可用于子类。您可以使用以下方法更改类方法的可访问性:
考虑到此代码将是“脆弱的”,因为库的作者不会考虑库的用户依赖于私有函数的结果。自己复制函数的代码可能比搞乱库本身要好。您可以间接操纵行为。这是您感兴趣的代码片段
$allCss = $this->css;
if ($this->isStyleBlocksParsingEnabled) {
$allCss .= $this->getCssFromAllStyleNodes($xpath);
}
查看类设置器,您可以调用disablestyleblocksparing
来防止调用该函数
$allCss
变量直接取自$this->css
,该变量仅由setCss
方法修改
所以你有两个选择:
- 扩展该类,使
false和immutable,然后重写IsStyleBlocksParSingabled
方法以执行您想要执行的setCss
操作getCssFromAllStyleNodes
- 调用
并使用预处理文本调用disablestyleblocksparing
setCss
class MyEmogrifier extends Emogrifier
{
public function __construct($html = '', $css = '')
{
parent::__construct($html, $css);
$this->disableStyleBlocksParsing();
}
public function setCss($css)
{
// Preprocess CSS here.
parent::setCss($css);
}
}
因此,不需要进行枪战手术,也不需要进行反思
不过说实话。我甚至不太愿意使用像这样一个具体的图书馆。我几乎所有的私有方法都使用
受保护的。您可以通过
这是它的一部分
将属性设置为可访问。例如,它可能允许受保护的
以及要访问的私有属性
这是危险的但在某些情况下,您可以使用它。有几种解决方案,如果您使用的是开源库,了解您使用的库可能会很有用。是的。我需要更改getCssFromAllStyleNodes
。我知道它为什么不起作用,但我正在寻找一种不同的方法来实现我在问题中所述的目标。在库类中将private
更改为protected
。它不会影响库中使用的任何代码,但它允许您重写它。我认为这并不能回答问题。OP说这是一个库,所以他不能更改访问修饰符。如果它不能更改,你就不能。
class MyEmogrifier extends Emogrifier
{
public function __construct($html = '', $css = '')
{
parent::__construct($html, $css);
$this->disableStyleBlocksParsing();
}
public function setCss($css)
{
// Preprocess CSS here.
parent::setCss($css);
}
}