[英]PHP/OOP - Using parent class to run child functions
我正在尋找一種可以將單個子類擴展為多個子類的方法,一次只能選擇其中一個子類。 一個非常基本的例子:
class API_Base {
public $context;
public function __construct() {
$this->init()
}
}
class Mailchimp_API extends API_Base {
public function init() {
$this->context = 'mailchimp';
$this->enabled = false;
}
public function add_contact($email_address) {
// mailchimp API for adding contact
}
}
class Infusionsoft_API extends API_Base {
public function init() {
$this->context = 'infusionsoft';
$this->enabled = true;
}
public function add_contact($email_address) {
// infusionsoft API for adding contact
}
}
每個孩子都會初始化自己並注冊為選項供用戶選擇。 用戶選擇了要使用的集成后,它將保存到數據庫中。 我希望以后訪問API_Base類似於:
$api = new API_Base();
$api->context; // should be "infusionsoft"
$api->add_contact($email_address);
因此,運行$api->add_contact()
,它僅運行add_contact()
函數以進行活動的API集成。
最終我想以某種方式使用get_class_methods();
返回僅活動API的功能,因此訪問API的功能可以知道可能的情況(即某些API支持電子郵件列表,而其他API不支持,或支持創建自定義字段等)。
我通過調用parent::set_context($context);
獲得了一些成功parent::set_context($context);
從啟用的類中,但我仍然不知道如何讓父級僅執行“已啟用”子類中的方法。
繼承不是這樣工作的。 子子類從其父類繼承。
為了解決您的問題,您可以向API_Base添加一個工廠方法,該方法將通過其類型創建API實現:
class API_Base {
public static function createByType($type)
{
switch ($type) {
case 'mailchimp': return new Mailchimp_API();
case 'infusionsoft': return new Infusionsoft_API();
default: throw new \InvalidArgumentException(spintf('Invalid API type "%s"', $type));
}
}
// other methods
}
並像這樣使用它:
$api = API_Base::createByType($user->selectedApi);
$api->context; // should be "infusionsoft"
$api->add_contact($email_address);
您可以考慮抽象類實現。 抽象類的作用是,擴展抽象類的人可以執行它擁有的方法。
abstract class Something{
function __construct(){
// some stuff
}
function my_func(){
$this->myTest ;
}
abstract function my_func();
}
class Some extends Something{
function __construct(){
parent::__construct() ;
}
function my_test(){
echo "Voila" ;
}
}
多虧了Ihor的建議,我的工作方式對我來說非常完美。 我最終要做的是:
在主插件文件中,有一個可過濾的功能,其他開發人員可以在需要時添加新的集成。 第一個參數是slug(對於我的自動裝帶器),第二個參數是類名。
public function get_apis() {
return apply_filters( 'custom_apis', array(
'infusionsoft-isdk' => 'MYPLUGIN_Infusionsoft_iSDK',
'infusionsoft-oauth' => 'MYPLUGIN_Infusionsoft_oAuth',
'activecampaign' => 'MYPLUGIN_ActiveCampaign'
) );
}
每個集成都包含段和類名。 然后在我的API_Base類中,我在構造函數中有這個:
class API_Base {
public $available_apis = array();
public $api;
public function __construct() {
$configured_apis = main_plugin()->get_apis();
foreach( $configured_apis as $slug => $classname ) {
if(class_exists($classname)) {
$api = new $classname();
$api->init();
if($api->active == true)
$this->api = $api;
$this->available_apis[$slug] = array( 'name' => $api->name );
if(isset($api->menu_name)) {
$this->available_apis[$slug]['menu_name'] = $api->menu_name;
} else {
$this->available_apis[$slug]['menu_name'] = $api->name;
}
}
}
}
}
然后,在我的主文件中,運行所有包含項:
self::$instance->api_base = new API_Base();
self::$instance->api = self::$instance->api_base->api;
現在我可以叫self::$instance->api->add_contact($email);
它將觸發當前活動的API中的任何一個。
這似乎是最好的方法,因為這樣一來,插件加載時我只能旋轉一次API,而不必每次使用時都必須創建一個新實例。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.