在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  |