您可以使用從 app.yaml 參照的 PHP 指令碼模擬基本 Apache mod_rewrite 功能,該指令碼會依序載入所需指令碼。本範例模擬常見的 PHP 模式;此模式預期 $_GET['q'] 變數會包含要求路徑。
關於「mod_rewrite.php」
如要啟用 mod_rewrite 功能,應用程式必須包含 mod_rewrite.php,這是向應用程式提出執行要求轉送的所有要求將會叫用這個指令碼。如同註解所述,指令碼會檢查根層級 PHP 指令碼是否存在,並在 $_SERVER['REQUEST_URI'] 的路徑部分放入 $_GET['q'] 變數時叫用這些指令碼。
<?php /** * @file * Provide basic mod_rewrite like functionality. * * Pass through requests for root php files and forward all other requests to * index.php with $_GET['q'] equal to path. The following are examples that * demonstrate how a request using mod_rewrite.php will appear to a PHP script. * * - /install.php: install.php * - /update.php?op=info: update.php?op=info * - /foo/bar: index.php?q=/foo/bar * - /: index.php?q=/ */ $path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH); // Provide mod_rewrite like functionality. If a php file in the root directory // is explicitly requested then load the file, otherwise load index.php and // set get variable 'q' to $_SERVER['REQUEST_URI']. if (dirname($path) == '/' && pathinfo($path, PATHINFO_EXTENSION) == 'php') { $file = pathinfo($path, PATHINFO_BASENAME); } else { $file = 'index.php'; // Provide mod_rewrite like functionality by using the path which excludes // any other part of the request query (ie. ignores ?foo=bar). $_GET['q'] = $path; } // Override the script name to simulate the behavior without mod_rewrite.php. // Ensure that $_SERVER['SCRIPT_NAME'] always begins with a / to be consistent // with HTTP request and the value that is normally provided. $_SERVER['SCRIPT_NAME'] = '/' . $file; require $file;
範例應用程式
以下是為了預期 $_GET['q'] 而編寫的簡單應用程式。
app.yaml
如您從這個 app.yaml 檔案看到的,這個應用程式會提供兩個根層級 PHP 指令碼,並從名為 downloads 的目錄提供靜態檔案。
application: mod_rewrite_simulator version: 1 runtime: php55 api_version: 1 handlers: # Example of handler which should be placed above the catch-all handler. - url: /downloads static_dir: downloads # Catch all unhandled requests and pass to mod_rewrite.php which will simulate # mod_rewrite by forwarding the requests to index.php?q=... (or other root-level # PHP file if specified in incoming URL. - url: /.* script: mod_rewrite.php
index.php
index.php 是路由器樣式的 index.php,可讀取 $_GET['q'] 來判斷要求路徑。
<?php if ($_GET['q'] == '/help') { echo 'This is some help text.'; exit; } echo 'Welcome to the site!';
other.php
以下是可直接呼叫的根層級指令碼範例。許多 PHP 架構都會使用 install.php 或 update.php 這類的動作指令碼,因此會產生類似的行為。
<?php echo 'Welcome to the other site.';
要求範例
依據上述的應用程式範例,下列要求會依所示方式處理。
/會透過$_GET['q'] = '/'轉譯為index.php/help會透過$_GET['q'] = '/help'轉譯為index.php/other.php會透過$_GET['q'] = null轉譯為other.php/downloads/foo_17.png會轉譯為downloads/foo_17.png
避免需要使用 mod_rewrite.php
許多 PHP 架構不再依附於 $_GET['q']。而是使用 $_SERVER['REQUEST_URI'],無論是否搭配 mod_rewrite 皆可運作。因此,後者是 App Engine 的首選方法。
如同用於 mod_rewrite.php,使用 REQUEST_URI 的乾淨方法如下所示:
<?php $path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH); if ($path == '/help') { echo 'This is some help text.'; exit; } echo 'Welcome to the site!';