Reputation: 12857
I am trying to learn creating php wrappers for 3rd party apis. However I am confused on implementing multiple classes extended/implemented each other.
class Api {
protected $username;
protected $password;
protected $wsdl = "http://example.com"
protected $client;
protected $account;
public function __construct($username, $password)
{
$this->client = new SoapClient($this->wsdl);
$authData = [
"Credentials" => [
"Username" => $username,
"Password" => $password
]
];
$this->makeCall('AuthenticateUser', $authData);
$this->account = $this->makeCall('GetAccountInfo', ["Authenticator" => $this->authenticator]);
}
protected function makeCall($method, $data) {
$result = $this->client->$method($data);
$this->authenticator = $result->Authenticator;
return $result;
}
}
Until here, it makes sense. However, at this point I don't want to add all methods in this class. Thus, I decided to create a separate class for each method. And there, here problem begins.
class AddressValidator extends Api
{
public function validateAddress($data) {
$response = $this->makeCall('validateAddress', $data);
dd($response);
}
}
Logically, how I need to call the wrapper (in my controller) is like this below, right?
$api = new Api($username, $password);
$api->validateAddress($params); // but I can't call this line with this setup
Instead, this works:
$api = new ValidateAddress($username, $password);
$api->validateAddress($params);
Makes sense, but is this the good way of organising it?
What is the beautiful way of setting up api wrapper? By the way, maybe I am wrong with this approach completely. I'd be happy to hear what you think
Upvotes: 1
Views: 167
Reputation: 181
Maybe something like
class Api {
private $class;
.
.
public function __construct($username, $password, $class_name) {
.
.
$this->class = new $class_name();
}
public function ApiCall($func, ...$arguments) {
$this->class->$func($arguments);
}
}
I'm not sure if this makes things easier for you, but it works.
Upvotes: 1
Reputation: 480
Instead of extending your API class, you could use a trait to organize your methods.
class Api {
use ValidateAddressTrait;
...
}
Trait:
trait ValidateAddressTrait {
public function validateAddress($data) {
$response = $this->makeCall('validateAddress', $data);
dd($response);
}
}
Use:
$api = new Api($username, $password);
$api->validateAddress($params);
This isn't exactly the intent of a trait but I think it can give you the result you are looking for.
Upvotes: 1