[英]Class methods access control in PHP
當在不同的上下文(系統中的API)中使用對象方法時,我需要組織對對象方法的某種訪問控制。 這是代碼示例:
class A
{
public function doA(){}
public function doB(){}
}
class APIAClient
{
public function getA()
{
return new A();
}
}
class APIBClient {
public function getA()
{
return new A();
}
}
在APIAClient中,對象A應該同時具有doA()和doB()方法,但在APIBClient中,則不應具有doB()方法。
目前,我已經實現了APIBClientAProxy(由APIBCleint-> getA()返回)
class APIBClientAProxy
{
private $a = new A;
public function doA()
{
$this->a->doA()
}
}
但是可能有一種更好的模式可以解決我的問題,而無需為每個上下文(即API)使用額外的代理對象。 我正在考慮魔術__call方法以及在特定上下文中允許使用的方法的列表,但是魔術調用很難做文檔,而文檔是我應用程序中的重點(API的文檔應該很好地記錄下來)
謝謝!
除了繼承,您還可以通過特征使用組合(PHP 5.4中引入)。
首先定義特征
trait A {
public function doA() {
// do something here
}
}
trait B {
public function doB() {
// do something here
}
}
然后在類聲明中使用這些特征
class APIAClient {
use A, B
}
class APIBClient {
use A
}
您可以在此處使用繼承,如下所示:
class A {
public function doA() {
// do something here
}
}
class B extends A {
public function doB() {
// do something here
}
}
class APIAClient
{
public function getObj() {
return new B();
}
}
class APIBClient {
public function getObj() {
return new A();
}
}
這樣,當你調用getObj()
上APIAClient,它會返回一個實例B
同時具有這doA()
和doB()
但是,當在APIBClient
上調用它時,您將返回A
的實例,該實例僅具有doA()
。
您不能根據創建實例的時間和方式來更改類(嗯,不是真的)。
您可以使用一種變通的解決方法(但我建議您反對)
class A
{
private $_canDoB = null;
public function __construct($doB = true)
{
$this->_canDoB = !!$doB;//force bool
}
public function doB()
{
if ($this->_canDoB === false)
{
throw new LogicError('You can\'t doB');
}
}
}
因此,如果將假值傳遞給A(在APIBClient
)的構造函數,則doB
將引發錯誤。 但是,我也建議您使用繼承:
class AB
{
public function doA()
{
//both B and B share this method
}
}
class B
{//nothing atm
}
class A
{
public function doB()
}
並讓您的APIAClient
返回一個new A()
,而APIBClient
返回一個B
類的新實例。
使用類型提示時,您只需檢查AB
實例:
public function doSomething(AB $instance)
{
if ($instance instanceof A)
{
return $instance->doB();
}
return $instance->doA();
}
或者,當不依賴於類型提示和類型檢查時,您始終可以使用許多方法之一,例如method_exists
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.