Building PHP Web Application in Windows Azure Cloud Service

在Windows Azure中,開發者可將PHP放置於兩種服務中,一個是Web Sites,另一個則是Cloud Services,兩者的差異是Web Sites無法使用memcached及較少的Scaling支援,Cloud Services雖然支援這些,

但相對的在開發及部署上也較為麻煩些,本文就針對Cloud Services上的PHP開發及部署做一個介紹。

 

 

 

/黃忠成

 

 

PHP Support in Windows Azure

 

  在Windows Azure中,開發者可將PHP放置於兩種服務中,一個是Web Sites,另一個則是Cloud Services,兩者的差異是Web Sites無法使用memcached及較少的Scaling支援,Cloud Services雖然支援這些,

但相對的在開發及部署上也較為麻煩些,本文就針對Cloud Services上的PHP開發及部署做一個介紹。

 

First PHP Web Application

 

  要在Cloud Services上使用PHP,開發者必須先下載Windows Azure SDK for PHP。

http://www.windowsazure.com/en-us/develop/php/common-tasks/download-php-sdk/

  由於PHP可在多種平台上開發,因此Microsoft也提供了Mac/Linux的版本,本文先就Windows版本介紹,之後的文章會補充Mac及Linux版本的工具介紹。

  安裝完成後,請開啟Windows Azure Powershell鍵入以下命令來建立第一個Windows Azure PHP應用程式。

圖1

 

完成後會得到以下的目錄結構。

圖2

請將你的PHP檔案放在WebRole1目錄下,例如下圖。

圖3

預設,Windows Azure Powershell會產生一個簡單的index.php,因此你可以直接執行Start-AzureEmulator來進行本機的測試。

圖4

 

一切無誤的話,應該可以開啟瀏覽器來查看。

圖5

很簡單吧,最後只要透過Publish-AzureServiceProject就可以部署到真實的Azure環境中,在這之前,你必須先取得與你的Azure帳號連結的憑證檔案,請使用Windows AzurePowershell下達以下命令。

圖6

這會開啟一個瀏覽器進入Windows Azure的入口網站,請登入你的帳號後,便會提示下載需要的憑證檔案,請將其存在找得到的地方。

圖7

完成後透過Windows Azure Powerhsll下達以下命令。

圖8

完成後就可以切換到MyFirstPHP目錄來進行Publish了。

圖9

 

部署的動作是先建立對應的Cloud Service(以此專案的目錄名稱),然後建立對應的Storage Account(以此專案的目錄名稱)來部署,如果你需要調整這些的話,可以透過deploymentSettings.json檔案來自訂。

 

deploymentSettings.json

{"Slot":"","Location":"","Subscription":"","StorageServiceName":"","AffinityGroup":""}

 

Slot指的是要部署到Cloud Services的哪個Slot,有Staging跟Production兩個選項,Location則是Service所在的區域,有East Asia、East US等選項。

StorageServiceName則是告訴Windows Azure Powershell要使用哪個Storage Account來存放部署期間的檔案,請直接鍵入名稱,如果該Storage Account不存在時,Windows Azure Powershell會新建一個。

 

 

Access Windows Azure Storage Services

 

  當然,在PHP中也可以存取Windows Azure Storage Services,但安裝Client Library的過程有點複雜,首先你得先安裝Git。

http://git-scm.com/book/en/Getting-Started-Installing-Git

然後在MyFirstPHP目錄中建立一個composer.json檔案。

 

Composer.json

{

    "require": {

        "microsoft/windowsazure": "*"

    },         

    "repositories": [

        {

            "type": "pear",

            "url": "http://pear.php.net"

        }

    ],

    "minimum-stability": "dev"

}

 

接著下載compposer.phar,存放到MyFirstPHP目錄下。

http://getcomposer.org/composer.phar

然後在MyFirstPHP目錄下達以下命令。

 

php .\composer.phar install

 

一切無誤的話,應該可以看到類似下圖的畫面。

圖10

 

這些Client Library存放在MyFirstPHP\vendor目錄下,通常我會把她們搬到WebRole1目錄下方便存取,下面是一個使用Windows Azure Storage的例子。

 


<html>


<head>

  <title>Registration</title>

  <style type="text/css">

    h2 div{

              width: 100%;

              margin: 0 auto;

              background-color:#0d2d80;

              color:white;

              }

           h3 div{

              width: 100%;

              margin: 0 auto;

              background-color:#e6c671;

              color:black;

              }

  </style> 

</head>


<body>

<h2>

   <div>Registration</div>

<h2>

<form action="accessTableStorage.php" method="post">

  <table>

  <tr>

  <td>Name:</td>

  <td><input type="text" name="txtname"/></td>

  </tr>

  <tr>

  <td>Email:</td>

  <td><input type="text" name="txtmail"/></td>

  </tr> 

  <td colspan="2"><input type="submit" name="submit" value="add"/></td>

  </tr>

  </table>

</form>


<h3>

   <div>List</div>

<h3>

<?php

require_once 'vendor\autoload.php';

use WindowsAzure\Common\ServicesBuilder;

use WindowsAzure\Common\ServiceException;

use WindowsAzure\Table\Models\Entity;

use WindowsAzure\Table\Models\EdmType;




$connectionString = "DefaultEndpointsProtocol=http;AccountName=<your acount >;AccountKey=<your account key>";


$tableRestProxy = ServicesBuilder::getInstance()->createTableService($connectionString);


try {

    // Create table.

    $tableRestProxy->createTable("customers");

}

catch(ServiceException $e){

    $code = $e->getCode();

           if($code != 409) {

              $error_message = $e->getMessage();

              echo $error_message;        

    }

}


if(isset($_REQUEST['submit'])){

  $entity = new Entity();

  $entity->setPartitionKey("rec"); 

  $entity->setRowKey($_REQUEST['txtname']);

  $entity->addProperty("email", null, $_REQUEST['txtmail']);

  try{

      $tableRestProxy->insertEntity("customers", $entity);

  }

  catch(ServiceException $e){

    // Handle exception based on error codes and messages.

    // Error codes and messages are here:

    // http://msdn.microsoft.com/en-us/library/windowsazure/dd179438.aspx

    $error_message = $e->getMessage();

           echo $error_message;

  }                     

}


?>


<table>

<tr>

<td>

    <b>Name</b>  

</td>

<td>

    <b>EMail</b>

</td>

<td></td>

<?php

    $filter = "PartitionKey eq 'rec'";

           try {

               $result = $tableRestProxy->queryEntities("customers", $filter);

    }

           catch(ServiceException $e){

    // Handle exception based on error codes and messages.

    // Error codes and messages are here:

    // http://msdn.microsoft.com/en-us/library/windowsazure/dd179438.aspx

      $code = $e->getCode();

      $error_message = $e->getMessage();

      echo $code.": ".$error_message."<br />";

    }


    $entities = $result->getEntities();

    foreach($entities as $entity){

             echo "<tr>";

             echo "<td>" . $entity->getRowKey() . "</td>";

             echo "<td>" . $entity->getPropertyValue("email") . "</td>";

             echo "</tr>";                  

           }

?>


</table>




</body>


</html>

 

特別注意一點,這個Client Librarys僅支援PHP 5.3以上版本。

 

 

Using Memcache – Windows Azure Caching

 

  如果你的PHP應用程式有使用到Session的話,那麼在網站Scaling之後,如何維持Session就是一個很大的問題,在這部分Windows Azure Caching提供了相當完善的支援,PHP應用程式可以透過

Memcache來與Windows Azure Caching溝通,然後把Session導向Windows Azure Caching,這樣一來,不管Scaling的Instance數量有多少,都不會影響Session的儲存。

  要做這個動作也很簡單,首先透過Windows Azure Powershell建立一個Cache Role。

 

PS D:\code\MyFirstPHP> Add-AzureCacheWorkerRole

 

接著下達啟用Cache Role的命令。

 

PS D:\code\MyFirstPHP> Enable-AzureMemcacheRole webrole1

 

正常的話會看到以下訊息。

 

詳細資訊: Memcache is enabled for role 'webrole1' using cache role 'WorkerRole1' to connect use server name

'localhost_webrole1' with port 11211.

 

接著請至以下網址下載PHP使用memcache的plug-in。

http://downloads.php.net/pierre/php_memcache-2.2.6-5.3-nts-vc9-x86.zip

接著放到MyFirstPHP\WebRole1\bin\php\ext目錄下,沒有的目錄請自行建立。

圖11

接著在MyFirstPHP\WebRole1\bin\php目錄下建立一個php.ini。

圖12

 

是的,這個php.ini就是常用來調整PHP環境的那個檔案,這裡我們調整了Session及Memcache的設定。

 

Php.ini

extension=php_memcache.dll

session.save_path=tcp://localhost_WebRole1:11211

session.save_handler=memcache