如何在 Apache2 和 PHP 中启用和使用 HTTP PUT 和 DELETE?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2934554/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 08:11:01  来源:igfitidea点击:

How to enable and use HTTP PUT and DELETE with Apache2 and PHP?

phpapacherest

提问by Andreas Jansson

It should be so simple. I've followed every tutorial and forum I could find, yet I can't get it to work. I simply want to build a RESTful API in PHP on Apache2.

它应该如此简单。我遵循了我能找到的每个教程和论坛,但我无法让它工作。我只是想在 Apache2 上用 PHP 构建一个 RESTful API。

In my VirtualHost directive I say:

在我的 VirtualHost 指令中,我说:

<Directory />
    AllowOverride All
    <Limit GET HEAD POST PUT DELETE OPTIONS>
        Order Allow,Deny
        Allow from all
    </Limit>
</Directory>

Yet every PUT request I make to the server, I get 405 method not supported.

然而,我向服务器发出的每个 PUT 请求,都会得到不支持的 405 方法。

Someone advocated using the Script directive, but since I use mod_php, as opposed to CGI, I don't see why that would work.

有人提倡使用 Script 指令,但由于我使用的是 mod_php,而不是 CGI,我不明白为什么会这样。

People mention using WebDAV, but to me that seems like overkill. After all, I don't need DAV locking, a DAV filesystem, etc. All I want to do is pass the request on to a PHP script and handle everything myself. I only want to enable PUT and DELETE for the clean semantics.

人们提到使用 WebDAV,但对我来说这似乎有点矫枉过正。毕竟,我不需要 DAV 锁定、DAV 文件系统等。我想做的就是将请求传递给 PHP 脚本并自己处理所有事情。我只想为干净的语义启用 PUT 和 DELETE。

采纳答案by Artefacto

You don't need to configure anything. Just make sure that the requests map to your PHP file and use requests with path info. For example, if you have in the root a file named handler.phpwith this content:

您不需要配置任何东西。只需确保请求映射到您的 PHP 文件并使用带有路径信息的请求。例如,如果您在根目录中有一个以handler.php以下内容命名的文件:

<?php

var_dump($_SERVER['REQUEST_METHOD']);
var_dump($_SERVER['REQUEST_URI']);
var_dump($_SERVER['PATH_INFO']);

if (($stream = fopen('php://input', "r")) !== FALSE)
    var_dump(stream_get_contents($stream));

The following HTTP request would work:

以下 HTTP 请求将起作用:

Established connection with 127.0.0.1 on port 81
PUT /handler.php/bla/foo HTTP/1.1
Host: localhost:81
Content-length: 5
?
boo
HTTP/1.1 200 OK
Date: Sat, 29 May 2010 16:00:20 GMT
Server: Apache/2.2.13 (Win32) PHP/5.3.0
X-Powered-By: PHP/5.3.0
Content-Length: 89
Content-Type: text/html
?
string(3) "PUT"
string(20) "/handler.php/bla/foo"
string(8) "/bla/foo"
string(5) "boo
"
Connection closed remotely.

You can hide the "php" extension with MultiViewsor you can make URLs completely logical with mod_rewrite.

您可以使用MultiViews隐藏“php”扩展名,或者您可以使用mod_rewrite使 URL 完全合乎逻辑。

See also the documentation for the AcceptPathInfodirective and this question on how to make PHP not parse POST data when enctype is multipart/form-data.

另请参阅AcceptPathInfo指令的文档以及有关如何在 enctype 为 时使 PHP 不解析 POST 数据的问题multipart/form-data

回答by MSharq

AllowOverride AuthConfig

允许覆盖 AuthConfig

try this. Authentication may be the problem. I was working with a CGI script written in C++, and faced some authentication issues when passed DELETE. The above solution helped me. It may help in your case too.

尝试这个。身份验证可能是问题所在。我正在使用用 C++ 编写的 CGI 脚本,并且在通过 DELETE 时遇到了一些身份验证问题。上述解决方案帮助了我。它也可能对您的情况有所帮助。



Also even if you don't get the solution for your problem of PUT and DELETE, do not stop working rather use "CORS". It is a google chrome app, which will help you bypass the problem, but remember it is a temporary solution, so that your work or experiments doesn't remain freeze for long. Obviously, you cannot ask your client to have "CORS" enabled to run your solution, as it may compromise systems security.

此外,即使您没有得到 PUT 和 DELETE 问题的解决方案,也不要停止工作,而是使用“CORS”。这是一个谷歌浏览器应用程序,可以帮助您绕过问题,但请记住它是一个临时解决方案,因此您的工作或实验不会长时间冻结。显然,您不能要求您的客户启用“CORS”来运行您的解决方案,因为这可能会危及系统安全。

回答by Peter Gostelow

IIRC the purpose of the form method attribute was to define different transport methods. Consequently, HTML 5.2 only defines GET, POST, and DIALOG methods for transport and dialog action, not how the server should process the data.

IIRC 表单方法属性的目的是定义不同的传输方法。因此,HTML 5.2 只定义了传输和对话操作的 GET、POST 和 DIALOG 方法,而不是服务器应该如何处理数据。

Ruby-on-rails solves this problem by using POST/GET for everything and adding a hidden form variable that defines the actual ReST method. This approach is more clumsy and error-prone, but does remove the burden from both the HTML standard and browser developers.

Ruby-on-rails 通过对所有内容使用 POST/GET 并添加一个定义实际 ReST 方法的隐藏表单变量来解决这个问题。这种方法更笨拙且更容易出错,但确实减轻了 HTML 标准和浏览器开发人员的负担。

The form method was defined before ReST, so you cannot define ReST in HTML, even after enabling Apache and PHP because the browsers conform to HTML and therefore default to GET/POST for all non-HTML defined values. That means, when you send a form to the browser with a PUT method, the browser changes that to GET and uses that instead. The hidden variable, however, passes through everything unchanged, so you can use that to customise your form handling process.

form 方法是在 ReST 之前定义的,因此您不能在 HTML 中定义 ReST,即使在启用 Apache 和 PHP 之后也是如此,因为浏览器符合 HTML,因此对于所有非 HTML 定义的值默认为 GET/POST。这意味着,当您使用 PUT 方法向浏览器发送表单时,浏览器会将其更改为 GET 并使用它。但是,隐藏变量会原封不动地传递所有内容,因此您可以使用它来自定义表单处理过程。

Hope that helps

希望有帮助

回答by Vincent Godin

On linux, /etc/apache2/mods-enabled/php5.conf dans php5.loadexists. If not, enables this modules (may require to sudo apt-get install libapache2-mod-php5).

在 linux 上,/etc/apache2/mods-enabled/php5.conf dans php5.load存在。如果没有,请启用此模块(可能需要sudo apt-get install libapache2-mod-php5)。

回答by Junaid Malik

You can just post the file name to delete to delete.php on the server, which can easily unlink() the file.

您可以将要删除的文件名发布到服务器上的delete.php,这样就可以轻松地 unlink() 文件。

回答by Adrian

The technical limitations with using PUT and DELETE requests does not lie with PHP or Apache2; it is instead on the burden of the browser to sent those types of requests.

使用 PUT 和 DELETE 请求的技术限制不在于 PHP 或 Apache2;相反,发送这些类型的请求是浏览器的负担。

Simply putting <form action="" method="PUT"> will not work because there are no browsers that support that method (and they would simply default to GET, treating PUT the same as it would treat gibberish like FDSFGS). Sadly those HTTP verbs are limited to the realm of non-desktop application browsers (ie: web service consumers).

简单地放置 <form action="" method="PUT"> 是行不通的,因为没有支持该方法的浏览器(而且它们会默认为 GET,将 PUT 视为像对待 FDSFGS 这样的乱码一样对待)。遗憾的是,这些 HTTP 动词仅限于非桌面应用程序浏览器的领域(即:Web 服务消费者)。