PHP 7中有哪些策略用于从第二类A类中的方法修改一个类B类的受保护属性,即使这些类不相关?
在实现嵌套类的语言中,这根本不是问题。 B类可以(并且应该)嵌套在A类中。然后,B类可以是受保护的类,属性可以是公共的。
创意#1
如果B类是A类的孩子,这非常容易。但是,这两个类是无关的。因此,这甚至不是一种选择。
创意#2
我考虑在B类中使用公共方法来更改属性的值,这可以由A类调用。不幸的是,这允许任何人更改属性的值,而不是只是A级。
创意#3
我的下一个想法是获取一个指向受保护变量的指针,从A类中设置它,然后取消设置它。像这样:
<?php
class A {
protected $b;
public function __construct() {
$this->b = new B( $pointer );
// do processing that requires B to be instantiated but has
// not yet determined an appropriate value for the property
$pointer = 12;
unset( $pointer );
}
}
class B {
protected $value;
public function __construct( &$pointer ) {
$this->value =& $pointer;
}
}
var_dump( new A );
?>
这会使A级和B级紧密耦合吗?根据我的理解,它会,而且我想避免这种情况。我希望我的理解是错误的,这是一个可以接受的解决方案。
PHP 7中是否有其他可以在不破坏SOLID设计原则的情况下实现此目标的变通方法?
提前感谢大家的时间!
既然已经提出要求,这就是我要解决的实际问题。我有一个名为Client的类和一个名为Receipt的类。可以请求Client对象向服务器发送消息,它将返回一个Receipt对象。这是异步发生的,所以稍后在脚本中我可以使用Receipt对象来获取响应(使用getResponse()方法)。我还希望收据具有getTime()方法,以便您可以检查请求/响应周期完成的时间。这是我正在努力完成的一个淡化版本:
<?php
class Client {
protected $receipts = [];
public function sendRequest( $destination, $request ) {
// put response in database and get the inserted row ID
$this->receipts[] = [
'timeStart' => microtime( true ),
'receipt' => ($receipt = new Receipt( $rowID ))
];
return $receipt;
}
public function setSignal( $signal ) {
pcntl_signal( $signal, function() {
// while there is a new response in the database
// get the $receipt from $this->receipts that matches the response
$receipt->receipt->time = microtime( true ) - $receipt->timeStart;
unset( $this->receipts[$index] );
break;
// end while
} );
}
}
class Receipt {
protected $rowID, $time;
public function __construct( $rowId ) {
$this->rowID = $rowID;
}
public function getTime() {
return $this->time;
}
}
$client = new Client;
$client->setSignal( SIGIO );
$receipt = $client->sendRequest( 'some destination', 'my request' );
echo $receipt->getTime(); // NULL
sleep( 1 );
echo $receipt->getTime(); // NULL
sleep( 1 );
echo $receipt->getTime(); // NULL
sleep( 1 );
echo $receipt->getTime(); // NULL
sleep( 1 );
echo $receipt->getTime(); // 4.2
?>
所以问题就在于:
$ receipt-&gt;收据 - &gt; time = microtime(true) - $ receipt-&gt; timeStart;
因为“time”是Receipt对象的受保护属性。
答案 0 :(得分:0)
好的,我认为我已经提出了最好的解决方案,我可以提出原始问题(从另一个类更新受保护的变量)。我不确定这是如何与SOLID原则叠加的,但我认为它会相当不错。
在我看来,最好的解决方案是创建一个公共方法,允许对象从数据库中的行刷新本身,而不是公开方法来专门更新值取出后。像这样:
<?php
class A {
protected $database, $b;
public function __construct() {
$this->b = new B;
// do HALF of the processing that requires B to be instantiated
// but has not yet determined an appropriate value for the property
$this->b->refresh();
}
}
class B {
protected $database, $value;
public function refresh() {
// do the other half of the things
$this->value = 12;
}
}
var_dump( new A );
?>
对我原帖的评论指出我在问XY问题。在阅读完文章之后,它完全合情合理,我理解我的问题可能因为我的问题而难以回答。感谢所有尝试的人,无论如何!对于遇到类似问题的人,我会留在这里。