当我对代码重构进行单元测试时,为了防止不必要的方法使用,我发现在cygwin以及Git bash中,php都可以访问扩展类的私有方法,并且从逻辑上讲,不是来自阿帕奇(he!)是虫子吗?还是穿夹克的虫子?
<?php
// Note: implementation greatly simplified for the POC
namespace Name\Space;
abstract class Db implements Db_Interface
{
protected $LastQueryResult = null;
abstract public function query($sql);
abstract protected function getRow();
/** connection to a database is made here, through a Singleton method */
...
}
final class MyDb extends Db
{
public function query($sql)
{
$this->LastQueryResult = Library::db_query($sql);
return $this->LastQueryResult;
}
private function getRow()
{
return Library::db_fetch_assoc($this->LastQueryResult);
}
}
客户电话:
// (instantiation not shown)
$sql = "SELECT login, firstname FROM user ORDER BY login";
$MyDb->query($sql);
while($row = $MyDb->getRow()) {
echo $row["login"], ", ", $row["firstname"], PHP_EOL;
}
从Apache获得的行为:
“致命错误:对Name \ Space \ MyDb :: getRow()的访问级别必须是公共的(如xxx行上的/path/to/class/MyDb.php中的类Name \ Space \ MyDb中一样)
从php cli获得的行为:
(正确的登录名/名字列表!)
上下文:Windows 10,从cygwin运行php cli,但也从Git bash运行:一些行为。 Apache2也在本地计算机上的WAMP服务器中运行。
刚刚找到原因!对不起,茶杯里的暴风雨...
照原样,父Db类实际上实现了一个接口,并且在该接口中,getRow()签名仍被声明为public:public function getRow();
嗯,php cli
对此非常热情,以至于它会很高兴并且不会看起来更深,与Apache相反,它将进一步挖掘。
现在我们知道...
显然,此修复程序是从接口中删除getRow(),因为它现在是私有的。