Configuring Zend Framework apps for Windows Azure
Building web applications is nothing new anymore, as we've been
doing it since the early days of the internet, but we've always
done this on a single system. Even when Zend Framework came round,
we kept doing the same thing and build apps for a single
environment.
But as I've discussed already in my previous article, developing for the cloud requires another
approach.
With Zend Framework
developing applications running on these separate compontents
becomes really easy. It's like having your cloud toolbox right in
your pocket.
Databases
With Zend Framework,
connecting to databases is really easy and swapping out a database
brand is just a matter of modifying your configuration
application/configs/application.ini.
resources.db.adapter = "pdo_mysql"
resources.db.params.host = "10.20.30.40"
resources.db.params.username = "user1"
resources.db.params.password = "secret"
resources.db.params.dbname = "db1"
resources.db.isDefaultTableAdapter = true
Even if you need to connect to multiple databases, you can just
pile them up as configuration setting and be done with it.
resources.multidb.server1.adapter = "pdo_mysql"
resources.multidb.server1.host = "10.20.30.40"
resources.multidb.server1.username = "user1"
resources.multidb.server1.password = "secret1"
resources.multidb.server1.dbname = "db1"
resources.multidb.server1.default = true
resources.multidb.server2.adapter = "pdo_pgsql"
resources.multidb.server2.host = "10.20.30.41"
resources.multidb.server2.username = "user2"
resources.multidb.server2.password = "secret2"
resources.multidb.server2.dbname = "db2"
resources.multidb.server3.adapter = "pdo_sqlite"
resources.multidb.server3.dbname = APPLICATION_PATH "/files/db/project.db"
But this is just the basics. When dealing with the cloud you
often get a connection string for the host, so it's real easy to
hook up to an relational database in the cloud. Here's an example
to connecting to SQL Azure.
resources.db.adapter = "SQLSRV"
resources.db.params.host = "abcdefghijk.database.windows.net"
resources.db.params.port = 1234
resources.db.params.username = "user1"
resources.db.params.password = "secret"
resources.db.params.dbname = "db1"
resources.db.isDefaultTableAdapter = true
Bottom line, no worries connecting to a cloud database. Zend Framework has your
back!
Sessions
As you want to assist your visitors as much as possible, you
probably want to use sessions in your application. If you don't
configure anything, PHP stores session on your filesystem by
default and so does Zend
Framework.
For the cloud, you don't want to write to your local filesystem,
so you set up session storage. I chose to use the SQL Azure server
I already had setup using the following settings.
resources.session.use_only_cookies = true
resources.session.gc_maxlifetime = 864000
resources.session.remember_me_seconds = 864000
resources.session.saveHandler.class = "Zend_Session_SaveHandler_DbTable"
resources.session.saveHandler.options.name = "session"
resources.session.saveHandler.options.primary = "id"
resources.session.saveHandler.options.modifiedColumn = "modified"
resources.session.saveHandler.options.dataColumn = "data"
resources.session.saveHandler.options.lifetimeColumn = "lifetime"
No further changes need to be done as all fields are defined and
this Zend_Session_SaveHandler_DbTable takes care of all the rest.
Caching
Just like databases, providing caching for your application
requires just a few simple configuration settings, this example
sets up a memcache service.
resources.cachemanager.memcached.frontend.name = Core resources.cachemanager.memcached.frontend.options.automatic_serialization = On resources.cachemanager.memcached.backend.name = Libmemcached resources.cachemanager.memcached.backend.options.servers.one.host = localhost resources.cachemanager.memcached.backend.options.servers.one.port = 11211 resources.cachemanager.memcached.backend.options.servers.one.persistent = On
Caching on the cloud requires a little different approach as most
cloud services offer their own flavor of caching, making it
difficult to find a PHP driver that is capable to access this
cloud caching layer. But don't let this stop you in moving to the
cloud. Windows Azure provides a superb caching platform, and I'll
show you later in these series how to modify your application as
it requires a little tweek on the configuration of your Windows
Azure installation.
Storage
Uploading and distributing files can be considered as an importan
part of any application, and with Zend Framework you can
manage file uploads relatively simple using Zend_Form and
Zend_File.
An example would be to upload a small image.
public function uploadAction()
{
$adapter = new Zend_File_Transfer_Adapter_Http();
$adapter->setDestination(APPLICATION_PATH '/files/upload');
if (!$adapter->receive()) {
$messages = $adapter->getMessages();
echo implode("\n", $messages);
}
$this->view->filename = $adapter->getFileName('avatar', false);
}
Saving into a specific location is done with
$adapter->setDestination(), but this still requires the usage
of a local location! And we know that in the cloud saving locally
has no use! Luckily for you, Zend
Framework has a bunch of components that will allow you to
store files onto a Windows Azure Storage instance.
public function uploadAction()
{
$config = new Zend_Config_Ini(APPLICATION_PATH . '/configs/api.ini', APPLICATION_ENV);
$azure = new My_Cloud_WindowsAzure_AzureStorage(
$config->azure->storage->account,
$config->azure->storage->primkey);
$container = $config->azure->storage->container;
$adapter = new Zend_File_Transfer_Adapter_Http();
$adapter->setDestination(APPLICATION_PATH '/files/upload');
if (!$adapter->receive()) {
$messages = $adapter->getMessages();
echo implode("\n", $messages);
}
$storageClient = new Zend_Service_WindowsAzure_Storage_Blob(
My_Cloud_WindowsAzure_AzureStorage::AZURE_STORAGE_HOST,
$azure->getAccountName(), $azure->getPrimaryKey());
$result = null;
if (!$storageClient->containerExists($container)) {
$result = $storageClient->createContainer($container);
$storageClient->setContainerAcl($container,
Zend_Service_WindowsAzure_Storage_Blob::ACL_PUBLIC_CONTAINER);
}
$fileName = $adapter->getFileName('resume', true);
$result = $storageClient->putBlob(
$container, basename($fileName), $fileName
);
$this->view->filename = basename($fileName);
$this->view->location = sprintf('http://%s.%s/%s/%s',
$azure->getAccountName(),
My_Cloud_WindowsAzure_AzureStorage::AZURE_STORAGE_HOST,
$config->azure->storage->container,
$result->Name);
}
As you can see, you only need to add a little more functionality
to the first example. But once you have everything in place,
nothing can stop you achieving your goals.
; These are local configuration settings
; Primarily used to access API's using credential tokens
[production]
...
azure.storage.account = "myblobstorageaccount1"
azure.storage.primkey = "fjldjljdlfjadladjsljdfljfdljd/akjddfjldfjjd22kajdajfei3234ajldjfjklajlajd=="
azure.storage.container = "myblobstoragecontainer"
...
[staging: production]
[testing: production]
[development: production]
In this example I used an api.ini which is very convenient to
store your most import settings like account names, api keys and
passwords to various api services. It's just a file containing
key-value pairs for easy configuration. In this case my INI
settings look like the following listing.
Next
Now that we've talked about the specific settings in your Zend Framework application
it's about time we set up our environment, download all the tools,
register for a Windows Azure account and get started with running
our Zend Framework app
in the cloud. So stay tuned for more.
This is a nice post in an interesting line of content, great way of bring this topic to discussion.
ReplyDeleteGreat breakdown, I've been looking to build some apps for Azure but I've been having some problems with it.
ReplyDelete