Yii provides many excellent solutions with which you can build an application. Still, you probably will need more. One of the best places to look is Zend Framework classes. These are of high quality and solve many tasks, such as using Google APIs or working with e-mails.
In this recipe, we will see how to use the Zend_Mail
package to send e-mails from the Yii application. We will use both a simple approach of using the whole framework and will also implement a custom autoloader that will allow us to use only Zend_Mail
and its dependencies.
Before we begin this recipe, we need to have a few things in place.
yiic webapp
.http://framework.zend.com/downloads/latest
In this recipe, we have used Version 1.11.6.
library/Zend
from the downloaded archive to protected/vendors/Zend
.Carry out the following steps:
protected/controllers/MailtestController.php
as follows:<?php class MailtestController extends CController { public function actionIndex() { $mail = new Zend_Mail('utf-8'), $mail->setHeaderEncoding(Zend_Mime::ENCODING_QUOTEDPRINTABLE); $mail->addTo("[email protected]", "Alexander Makarov"); $mail->setFrom("[email protected]", "Robot"); $mail->setSubject("Test email"); $mail->setBodyText("Hello, world!"); $mail->setBodyHtml("Hello, <strong>world</strong>!"); $mail->send(); echo "OK"; } }
mailtest/index
and verify that it doesn't work:Zend_Mail
class. This is expected because it knows nothing about the Zend Framework's naming convention. So logically, we have the following two solutions to this:require_once
statements for all dependencies. These statements rely on adding an additional PHP include
path and look like the following:require_once 'Zend/Mail/Transport/Abstract.php';
Yii::import
to import a directory, it works the same way as adding a directory into the PHP include
path, so we can solve our problem as follows:class MailtestController extends CController { public function actionIndex() { Yii::import('application.vendors.*'), require "Zend/Mail.php"; $mail = new Zend_Mail('utf-8'), $mail->setHeaderEncoding(Zend_Mime::ENCODING_QUOTEDPRINTABLE); // change to your email $mail->addTo("[email protected]", "Alexander Makarov"); $mail->setFrom("[email protected]", "Robot"); $mail->setSubject("Test email"); $mail->setBodyText("Hello, world!"); $mail->setBodyHtml("Hello, <strong>world</strong>!"); $mail->send(); echo "OK"; } }
Zend_Loader_Autoloader
to achieve this.index.php
bootstrap. This way, you will be able to autoload classes during the whole execution flow:// change the following paths if necessary $yii=dirname(__FILE__).'/../framework/yii.php'; $config=dirname(__FILE__).'/protected/config/main.php'; // remove the following lines when in production mode defined('YII_DEBUG') or define('YII_DEBUG',true); // specify how many levels of call stack should be shown // in each log message defined('YII_TRACE_LEVEL') or define('YII_TRACE_LEVEL',3); require_once($yii); $app = Yii::createWebApplication($config); // adding Zend Framework autoloader Yii::import('application.vendors.*'), require "Zend/Loader/Autoloader.php"; Yii::registerAutoloader(array('Zend_Loader_Autoloader','autoload'), true); $app->run();
MailtestController
:Yii::import('application.vendors.*'), require "Zend/Mail.php";
And it will still work fine without any errors, meaning that Zend Framework autoloading now works.
Let's review what is going on behind the scenes and how it works, starting with the first way. We have used Yii::import
, which, when used like Yii::import('path.alias.*')
, behaves like adding another PHP include
path. As there was no autoloader in Zend Framework originally, it has all the necessary require_once
calls. So, if you use a single component, such as Zend_Mail
, you don't need more than one require_once
.
The second method doesn't force you to use a single require
statement. As Yii allows using multiple autoloaders and in the latest versions Zend Framework has its own autoloader, we can use it in our application. The best time to do this is right after the application bootstrap was loaded, but the application was not run. To achieve this, we break Yii::createWebApplication($config)->run()
into two separate statements in index.php
and insert an autoloader initialization between these:
Yii::import('application.vendors.*'), require "Zend/Loader/Autoloader.php"; Yii::registerAutoloader(array('Zend_Loader_Autoloader', 'autoload'), true);
We still need Yii::import('application.vendors.*')
because Zend Framework classes will continue to use require_once
. Then, we require an autoloader class and add it to the end of the PHP autoloading stack by using Yii::registerAutoloader
with the second argument set to true
.
18.224.73.125