2012-12-01 23 views
7

Mam problem z uchwyceniem najbardziej odpowiedniego sposobu obsługi adresów URL REST.Obsługa adresu URL RESTful URL

Mam url takie jak:

http://localhost/products 
http://localhost/products/123 
http://localhost/products/123/color 

Oryginalnie:

http://localhost/index.php?handler=products&productID=123&additional=color 

Jak na razie używam mod_rewrite:

RewriteRule ^([^/]*)([/])?([^/]*)?([/])?(.*)$ /index.php?handler=$1&productID=$3&additional=$5 [L,QSA] 

A potem ja zastanawiające razem żądania w index.php, coś w stylu:

if ($_GET['handler'] == 'products' && isset($_GET['productID'])) { 
    // get product by its id. 
} 

Widziałem niektóre tworząc Get-maila jako jeden ciąg jak:

if ($_GET['handler'] == 'products/123/color') 

Następnie prawda na przykład użyć wyrażeń regularnych, aby uzyskać wartości z kwerendy-string?

Czy jest to lepsze podejście do obsługi tych adresów URL? Jakie są plusy i minusy z tymi różnymi podejściami? Czy jest jakiś lepszy sposób?

+0

'' Dlatego nie lubię tego typu adresów URL.Takie pozycje nie są tak łatwe w obsłudze, jak pity z nazwami/wartościami. ''. –

Odpowiedz

6

Można zastosować inne podejście zamiast dopasowywania wszystkich parametrów przy użyciu przeróbek apache, które można dopasować do pełnej ścieżki żądania w PHP za pomocą preg_match. Stosując wyrażenie regularne PHP wszystkie parametry zostaną przeniesione do tablicy $args.

$request_uri = @parse_url($_SERVER['REQUEST_URI']); 
$path = $request_uri['path']; 
$selectors = array(
    "@^/products/(?P<productId>[^/]+)|/[email protected]" => 
      (array("GET" => "getProductById", "DELETE" => "deleteProductById")) 
); 

foreach ($selectors as $regex => $funcs) { 
    if (preg_match($regex, $path, $args)) { 
     $method = $_SERVER['REQUEST_METHOD']; 
     if (isset($funcs[$method])) { 
      // here the request is handled and the correct method called. 
      echo "calling ".$funcs[$method]." for ".print_r($args); 
      $output = $funcs[$method]($args); 
      // handling the output... 
     } 
    } 
} 

Takie podejście ma wiele zalet:

  • Nie ma przepisać dla każdej usługi REST jesteś rozwijającego. Lubię przepisywać, ale w tym przypadku potrzebujesz dużo swobody i przy przepisywaniu musisz zmienić konfigurację Apache za każdym razem, gdy wdrażasz/utrzymujesz nową usługę.
  • Możesz mieć jedną klasę frontendu PHP dla wszystkich przychodzących żądań. Frontend wysyła wszystkie żądania do właściwego kontrolera.
  • Możesz zastosować iteracyjnie tablicę wyrażeń regularnych do przychodzących żądań, a następnie wywołać odpowiednią funkcję lub kontroler/metodę klasy odpowiednio do pomyślnego dopasowania
  • Kiedy w końcu kontroler jest instancjonowany do obsługi żądania, tutaj możesz sprawdzić metoda HTTP używany do żądania http
+0

nadal nie potrzebuje mapowania w htaccess, aby wskazywać na plik kontrolny php, lub jak to jest podłączone? –

+1

@NickHumphrey Biorąc pod uwagę, że każde żądanie może być obsługiwane przez index.php (domyślny plik w 'DirectoryIndex'), naprawdę nie musisz mapować niczego na' .htaccess '. Cóż ... twój serwer powinien przynajmniej mieć możliwość uruchamiania stron php. Wszystko, co musisz zrobić, to osadzić ten kod w pliku index.php i wysłać żądanie do właściwego programu obsługi. – freedev

3

Ten wpis .htaccess wyśle ​​wszystko oprócz istniejących plików index.php:

RewriteCond %{REQUEST_FILENAME} !-f 
RewriteCond %{REQUEST_FILENAME} !-d 
RewriteRule . /index.php 

Następnie można zrobić coś takiego przekonwertować url do Tablica:

$url_array = explode('/', $_SERVER['REQUEST_URI']); 
array_shift($url_array); // remove first value as it's empty 
array_pop($url_array); // remove last value as it's empty 

Następnie można użyć przełącznika wygląda następująco:

switch ($url_array[0]) { 

    case 'products' : 
     // further products switch on url_array[1] if applicable 
     break; 

    case 'foo' : 
     // whatever 
     break; 

    default : 
     // home/login/etc 
     break; 

} 

To co ogólnie zrobić tak.