使用中间件来跨语言

除了在不同版本的 PHP 之间进行通信的情况下,PSR-7 中间件的作用很小。回忆一下这个缩写代表什么。PHP 标准建议。因此,如果你需要向一个用其他语言编写的应用程序发出请求,就像对待任何其他 Web 服务的 HTTP 请求一样。

如何做…

1.在 PHP 4 的情况下,实际上有机会,因为对面向对象编程的支持是有限的。因此,最好的方法是将前三个示例中描述的基本PSR-7类降级。没有足够的篇幅来涵盖所有的变化,但是我们介绍一个潜在的PHP 4版本的Application\MiddleWare\ServerRequest。首先要注意的是没有命名空间!因此,我们使用了一个类名。因此,我们使用带下划线的类名 _ 来代替命名空间分隔符。

  1. class Application_MiddleWare_ServerRequest
  2. extends Application_MiddleWare_Request
  3. implements Psr_Http_Message_ServerRequestInterface
  4. {
  1. 在PHP 4中,所有的属性都是用关键字var来识别的。
  1. var $serverParams;
  2. var $cookies;
  3. var $queryParams;
  4. // not all properties are shown
  1. initialize()方法几乎是一样的,只是在PHP 4中不允许使用$this->getServerParams()['REQUEST_URI']这样的语法。因此,我们需要将其拆分为一个单独的变量。
  1. function initialize()
  2. {
  3. $params = $this->getServerParams();
  4. $this->getCookieParams();
  5. $this->getQueryParams();
  6. $this->getUploadedFiles;
  7. $this->getRequestMethod();
  8. $this->getContentType();
  9. $this->getParsedBody();
  10. return $this->withRequestTarget($params['REQUEST_URI']);
  11. }
  1. 所有的 $_XXX 超级全局都在 PHP 4 的以后版本中出现。
  1. function getServerParams()
  2. {
  3. if (!$this->serverParams) {
  4. $this->serverParams = $_SERVER;
  5. }
  6. return $this->serverParams;
  7. }
  8. // not all getXXX() methods are shown to conserve space
  1. null coalesce 操作符在 PHP 7 中才被引入,我们需要使用代替 isset(XXX) ? XXX : ""
  1. function getRequestMethod()
  2. {
  3. $params = $this->getServerParams();
  4. $method = isset($params['REQUEST_METHOD'])
  5. ? $params['REQUEST_METHOD'] : '';
  6. $this->method = strtolower($method);
  7. return $this->method;
  8. }
  1. JSON扩展直到PHP 5才被引入,因此,我们需要满足于原始输入。我们也可以使用 serialize()unserialize()来代替json_encode()json_decode()
  1. function getParsedBody()
  2. {
  3. if (!$this->parsedBody) {
  4. if (($this->getContentType() ==
  5. Constants::CONTENT_TYPE_FORM_ENCODED
  6. || $this->getContentType() ==
  7. Constants::CONTENT_TYPE_MULTI_FORM)
  8. && $this->getRequestMethod() ==
  9. Constants::METHOD_POST)
  10. {
  11. $this->parsedBody = $_POST;
  12. } elseif ($this->getContentType() ==
  13. Constants::CONTENT_TYPE_JSON
  14. || $this->getContentType() ==
  15. Constants::CONTENT_TYPE_HAL_JSON)
  16. {
  17. ini_set("allow_url_fopen", true);
  18. $this->parsedBody =
  19. file_get_contents('php://stdin');
  20. } elseif (!empty($_REQUEST)) {
  21. $this->parsedBody = $_REQUEST;
  22. } else {
  23. ini_set("allow_url_fopen", true);
  24. $this->parsedBody =
  25. file_get_contents('php://stdin');
  26. }
  27. }
  28. return $this->parsedBody;
  29. }
  1. withXXX()方法在PHP 4中的工作原理基本相同。
  1. function withParsedBody($data)
  2. {
  3. $this->parsedBody = $data;
  4. return $this;
  5. }
  1. 同样,withoutXXX()方法也是一样的。
  1. function withoutAttribute($name)
  2. {
  3. if (isset($this->attributes[$name])) {
  4. unset($this->attributes[$name]);
  5. }
  6. return $this;
  7. }
  8. }
  1. 对于使用其他语言的网站,我们可以使用PSR-7类来制定请求和响应,但这时需要使用HTTP客户端与其他网站进行通信。作为一个例子,请回忆一下本章的 “开发PSR-7请求类的示例 “中讨论的Request的演示。下面是如何做…部分的例子。
  1. $request = new Request(
  2. TARGET_WEBSITE_URL,
  3. Constants::METHOD_POST,
  4. new TextStream($contents),
  5. [Constants::HEADER_CONTENT_TYPE =>
  6. Constants::CONTENT_TYPE_FORM_ENCODED,
  7. Constants::HEADER_CONTENT_LENGTH => $body->getSize()]
  8. );
  9. $data = http_build_query(['data' =>
  10. $request->getBody()->getContents()]);
  11. $defaults = array(
  12. CURLOPT_URL => $request->getUri()->getUriString(),
  13. CURLOPT_POST => true,
  14. CURLOPT_POSTFIELDS => $data,
  15. );
  16. $ch = curl_init();
  17. curl_setopt_array($ch, $defaults);
  18. $response = curl_exec($ch);
  19. curl_close($ch);