Menyimulasikan pemilihan rute mod_rewrite Apache

Fungsionalitas Apache mod_rewrite dasar dapat disimulasikan melalui penggunaan skrip PHP yang direferensikan dari app.yaml yang nantinya akan memuat skrip yang diinginkan. Contoh ini menyimulasikan pola PHP umum yang mengharapkan variabel $_GET['q'] berisi jalur permintaan.

Tentang mod_rewrite.php

Untuk mengaktifkan fungsi mod_rewrite, aplikasi Anda harus menyertakan mod_rewrite.php, yaitu skrip yang akan dipanggil untuk semua permintaan ke aplikasi Anda guna melakukan perutean permintaan. Seperti yang dijelaskan dalam komentar, skrip akan memeriksa keberadaan skrip PHP level root dan memanggilnya saat menempatkan bagian jalur $_SERVER['REQUEST_URI'] di variabel $_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;

Contoh aplikasi

Berikut ini menunjukkan aplikasi yang sangat sederhana yang ditulis untuk mengharapkan $_GET['q'].

app.yaml

Seperti yang Anda lihat dari file app.yaml ini, aplikasi ini akan menyediakan dua skrip PHP level root dan menyalurkan file statis dari direktori bernama 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 adalah index.php gaya router yang membaca $_GET['q'] untuk menentukan jalur permintaan.

<?php

if ($_GET['q'] == '/help') {
  echo 'This is some help text.';
  exit;
}

echo 'Welcome to the site!';

other.php

Berikut adalah contoh skrip level root yang dapat dipanggil secara langsung. Banyak framework PHP memiliki skrip seperti install.php atau update.php yang akan berperilaku serupa.

<?php

echo 'Welcome to the other site.';

Contoh permintaan

Dengan contoh aplikasi di atas, permintaan berikut akan ditangani seperti yang ditunjukkan.

  • / diterjemahkan ke index.php dengan $_GET['q'] = '/'
  • /help diterjemahkan ke index.php dengan $_GET['q'] = '/help'
  • /other.php diterjemahkan ke other.php dengan $_GET['q'] = null
  • /downloads/foo_17.png diterjemahkan ke downloads/foo_17.png

Menghindari kebutuhan akan mod_rewrite.php

Banyak framework PHP yang tidak lagi bergantung pada $_GET['q']. Sebagai gantinya, mereka menggunakan $_SERVER['REQUEST_URI'] yang berfungsi dengan dan tanpa mod_rewrite. Oleh karena itu, metode tersebut adalah metode yang direkomendasikan di App Engine.

Seperti yang digunakan di mod_rewrite.php, metode bersih penggunaan REQUEST_URI adalah sebagai berikut:

<?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!';