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

33

这应该很简单。我按照所有能找到的教程和论坛都尝试了,但仍然无法让它工作。我只想在Apache2上用PHP构建一个RESTful API。

在我的VirtualHost指令中,我说:

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

无论我向服务器发起的每个PUT请求,都会收到405方法不支持的错误。

有人建议使用Script指令,但由于我使用的是mod_php,而不是CGI,所以我不知道为什么那样做会奏效。

有人提到使用WebDAV,但在我看来,那似乎有些过度。毕竟,我不需要DAV锁定、DAV文件系统等等。我只想把请求传递给一个PHP脚本,并自己处理一切。我只想启用PUT和DELETE以实现干净的语义。

5个回答

18

您无需配置任何内容。只需确保请求映射到您的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));
以下 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.
您可以使用MultiViews隐藏“php”扩展名,或者您可以使用mod_rewrite完全逻辑化URL。

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


使用cURL命令行: "curl -X PUT --header "Content-Type: application/octet-stream" --data-binary "@1.gif" -v /handler.php/bla/foo",并在PHP文件中将内容转储到文件中。它运行得很好。 但是,我需要发送一些额外的信息,例如上传文件的令牌。我认为我应该使用POST。 - vivek.m
令牌也可以在头部中 ;) - Tomáš Fejfar
20
这并没有回答问题。@AndreasJansson,你做了什么来使它起作用?我有同样的问题,说“你不需要做任何事情,它已经工作了”是没有帮助的。 - Benubird
3
我有同样的问题。在到达.php页面之前,出现了405错误。因此我无法映射任何内容。 - vee
只需确保请求映射到您的PHP文件即可。好的...但是怎么做呢?同意,这不是一个有帮助的答案。 - Asteroids With Wings

-2

AllowOverride AuthConfig

尝试这个。身份验证可能是问题所在。我曾经使用C++编写的CGI脚本工作时,当传递DELETE时遇到了一些身份验证问题。上述解决方案帮助了我。它也可能对你有所帮助。


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

1
你为什么认为身份验证可能是根本原因,尽管所述问题是405而不是403?CORS与HTTP方法的可接受性或身份验证有什么关系?您能否澄清您的答案,以明确您正在谈论的这三个概念中的哪一个? - AnotherSmellyGeek

-3
在Linux上,/etc/apache2/mods-enabled/php5.conf dans php5.load 是存在的。如果不存在,需要启用这些模块(可能需要执行sudo apt-get install libapache2-mod-php5)。

你能否使用代码标签吗?这样会使得代码更易读。 - Styxxy

-4

如果我没记错,表单方法属性的目的是定义不同的传输方法。因此,HTML 5.2仅为传输和对话操作定义了GET、POST和DIALOG方法,而没有定义服务器应如何处理数据。

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

表单方法是在ReST之前定义的,因此即使启用了Apache和PHP,也无法在HTML中定义ReST,因为浏览器遵循HTML并默认将所有非HTML定义值设置为GET/POST。这意味着,当您向浏览器发送具有PUT方法的表单时,浏览器会将其更改为GET并使用它。然而,隐藏变量可以通过一切不变,因此您可以使用它来自定义您的表单处理过程。

希望这有所帮助


1
你确定你是指“HTML”吗? - Asteroids With Wings
1
好的,不是这样的 - Asteroids With Wings
1
点击我给你的链接。方法可以省略,默认为“GET”。 - Asteroids With Wings
1
无所谓,反正这个问题是关于HTTP服务器返回错误代码的,与HTML、Ruby-on-Rails、REST或其他你提到的东西无关。OP甚至没有提到<form>。 - Asteroids With Wings
2
这不是我的观点。我只是字面上链接到了标准文档,哈哈。 - Asteroids With Wings
显示剩余4条评论

-8

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

仅仅将<form action="" method="PUT">放置在代码中是无效的,因为没有浏览器支持该方法(它们会简单地默认为GET,并将PUT视为与FDSFGS等无意义字符相同)。遗憾的是,这些HTTP动词仅限于非桌面应用程序浏览器(即:Web服务消费者)的领域。


12
他说他希望有一个RESTful API,这可能与浏览器无关。无论如何,当前的浏览器可以通过XmlHttpRequest支持PUT、DELETE等操作。 - Artefacto

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接