如何在浏览器地址栏中保留我的 REST API 地址但调用不同的 PHP 页面?

How do I keep my REST API address in the browser address bar but call a different PHP page?

我有一个 PHP 页面,通过像这样传递产品代码来显示产品详细信息:

mywebsite/product.php?id=1234

这包含所有 HTML 来生成有问题的页面,少量 PHP 和一些 Javascript 调用 AJAX 来获取产品详情。

我还使用 Silex / PHP 编写了 REST API,Javascript 调用它从我的数据库中获取产品信息,如下所示:

<?php
session_start();
require_once __DIR__.'/vendor/autoload.php';    

$app = new Silex\Application();
$app['debug'] = true;


$app->get('/product/{productId}', function($productId) use($app) { 

    $result = getProductDetails($productId);    
    return json_encode($result, JSON_NUMERIC_CHECK);
}); 

$app->run();

?>

(函数 getProductDetails 在包含的另一个 PHP 文件中)

但是,我想将主页转换为 REST API,看起来像这样:

mywebsite/product/1234

我试过包含 product.php 页面,但这根本不起作用。我也试过这样重定向:

$app->get('/product/{productid}', function($productid) use($app) { 

    Header('Location: /product.php?id='.$productid);
    die();
}); 

但是 product.php?id= 出现在地址栏中。

任何人都可以指出正确的方向,以便我可以输入: mywebsite/product/1234 这就是浏览器显示的内容,但我可以使用在不同 PHP 文件中定义的页面 ?

你想要的是 Symfony 世界中所谓的 "sub-request"(因此 Silex 也是如此)。您可以检查 Silex's documentation for sub-request 但基本上:

<?php
// if not using it, you must tell PHP to use this class
use Symfony\Component\HttpFoundation\Request;

$app->get('/product/{productid}', function($productid) use($app) { 
  $subRequest = Request::create('/product.php?id='.$productid);
  $response = $app->handle($subRequest, HttpKernelInterface::SUB_REQUEST, false);        

  return $response;
}); 

请注意,使用 Silex,this approach has its limitations(主要是由于 Pimple 的范围不足)。

但我担心您的 product.php 是一个真正的 PHP 文件,因此 Silex 无法自行处理,在这种情况下,我将直接包含该文件:

$app->get('/product/{productid}', function($productid) use($app) { 
  $_GET['id'] = $productid;
  ob_start();
  require PATH_TO . '/product.php';
  $response = ob_get_clean();

  // now do whatever you want with the response
  return new Response($response);
}); 

如果您想 return Json 数据检查 Silex Application class 上的 json 方法。

PD:我还建议您阅读 HttpFoundation's documentation as you should never use Location(...); die(); but a RedirectResponse