I'm using the Amazon Simple Email Service and am trying to implement it as an abstract class so that I can simply use it throughout as needed.
Problem
The problem occurs with the use, I cannot work out how to require the files and classes needed to use Ses
as an abstract class without incurring errors.
require 'lib/aws/aws-autoloader.php';
use Aws\Common\Enum\Region;
use Aws\Ses\SesClient;
abstract class simpleemail {
function sendSesEmail($to, $subject, $body, $bodyHtml){
try {
$client = SesClient::factory(array(
'key' => "",
'secret' => "",
'region' => Region::US_EAST_1
));
$send = $client->sendEmail(array(
'Source' => 'Name <no-reply@contact.com>',
'Destination' => array('ToAddresses' => array($to)),
'Message' => array('Subject' => array('Data' => $subject), 'Body' => array('Html' => array('Data' => $bodyHtml)))));
return true;
}
catch(Exception $e){
echo $e->getMessage();
return false;
}
}
}
Error Messages
Fatal error: Class 'Aes\Ses\SesClient' not found in ....
I have tried changing the use
to require but then get:
require 'lib/aws/Aws/Common/Enum/Region.php';
require 'lib/aws/Aws/Ses/SesClient.php';
Fatal error: 'SesClient' not found in ...
Solution?
How can I use/require the files I need to get this working inside an abstract class?
This doesn't work:
abstract class simpleemail
{
public function sendSesEmail()
{
use Aws\Common\Enum\Region;
use Aws\Ses\SesClient;
//...
}
}
use
statements are, basically, imports, that are processed at compile-time, so they can't be scoped. They have to move to the outer scope (outside of the class).
If you want to scope them, you'll have to either, manually require
them, or use class_alias
.
Check my answer to this question for more details. Even more details can, as ever, be found on php.net
Side-notes:
public
, protected
and private
)$client = SesClient::factory
, assign them to a property, to only create the instance once. At the moment, each method call creates the same instance over and over again. That's badsendEmail
on an instance, and assign the return value to $send
. You don't check the return value, nor do you return it. Either ignore the return value, or return it, so it can be checked!require
, use require_once
if you have to. Using require
can cause errors when executing the same block of code twice: redeclaring functions/classes. If time is of the essence, you could opt for require
(as require_once
causes more overhead), but you have to know what you're doing.require
an autoloader, use spl_autoloader_register
final
So, the answer:
use Aws\Common\Enum\Region;
use Aws\Ses\SesClient;
abstract class simpleemail
{
protected $client = null;
final public function sendSesEmail()
{
$client = $this->getClient();//lazy-loads the client instance
return $client->sendEmail(/* ... */);//return the result
}
//lazy-loader
protected function getClient()
{
if ($this->client === null)
{
$this->client = SesClient::factory(array(
'key' => "",
'secret' => "",
'region' => Region::US_EAST_1
));
}
return $this->client;
}
}