简体   繁体   English

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

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

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. 人们提到使用WebDAV,但对我来说这似乎有些过分。 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. 毕竟,我不需要DAV锁定,DAV文件系统等。我想要做的就是将请求传递给PHP脚本并自己处理所有事情。 I only want to enable PUT and DELETE for the clean semantics. 我只想为干净的语义启用PUT和DELETE。

You don't need to configure anything. 您不需要配置任何东西。 Just make sure that the requests map to your PHP file and use requests with path info. 只需确保请求映射到您的PHP文件并使用带有路径信息的请求。 For example, if you have in the root a file named handler.php with this content: 例如,如果您在根目录中有一个名为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 MultiViews or you can make URLs completely logical with mod_rewrite . 您可以使用MultiViews隐藏“php”扩展名,也可以使用mod_rewrite使URL完全符合逻辑。

See also the documentation for the AcceptPathInfo directive and this question on how to make PHP not parse POST data when enctype is multipart/form-data . 另请参阅AcceptPathInfo指令的文档以及当enctype为multipart/form-data如何使PHP不解析POST multipart/form-data

AllowOverride AuthConfig AllowOverride 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. 我正在使用用C ++编写的CGI脚本,并在通过DELETE时面临一些身份验证问题。 The above solution helped me. 以上解决方案帮助了我。 It may help in your case too. 它也可能对你的情况有所帮助。


Also even if you don't get the solution for your problem of PUT and DELETE, do not stop working rather use "CORS". 即使你没有得到PUT和DELETE问题的解决方案,也不要停止工作而是使用“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. 显然,您不能要求您的客户启用“CORS”来运行您的解决方案,因为它可能会危及系统安全性。

IIRC the purpose of the form method attribute was to define different transport methods. IIRC表单方法属性的目的是定义不同的传输方法。 Consequently, HTML 5.2 only defines GET, POST, and DIALOG methods for transport and dialog action, not how the server should process the data. 因此,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. Ruby-on-rails通过对所有内容使用POST / GET并添加定义实际ReST方法的隐藏表单变量来解决此问题。 This approach is more clumsy and error-prone, but does remove the burden from both the HTML standard and browser developers. 这种方法更加笨拙且容易出错,但确实消除了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. 表单方法是在ReST之前定义的,因此即使在启用Apache和PHP之后也无法在HTML中定义ReST,因为浏览器符合HTML,因此默认为所有非HTML定义值的GET / POST。 That means, when you send a form to the browser with a PUT method, the browser changes that to GET and uses that instead. 这意味着,当您使用PUT方法将表单发送到浏览器时,浏览器会将其更改为GET并使用它。 The hidden variable, however, passes through everything unchanged, so you can use that to customise your form handling process. 但是,隐藏变量会传递所有未更改的内容,因此您可以使用它来自定义表单处理过程。

Hope that helps 希望有所帮助

您可以在服务器上发布要删除的文件名delete.php,这样可以轻松取消链接()文件。

On linux, /etc/apache2/mods-enabled/php5.conf dans php5.load exists. 在linux上,/ /etc/apache2/mods-enabled/php5.conf dans php5.load存在。 If not, enables this modules (may require to sudo apt-get install libapache2-mod-php5 ). 如果没有,启用此模块(可能需要sudo apt-get install libapache2-mod-php5 )。

The technical limitations with using PUT and DELETE requests does not lie with PHP or Apache2; 使用PUT和DELETE请求的技术限制不在于PHP或Apache2; it is instead on the burden of the browser to sent those types of requests. 相反,它是浏览器发送这些类型请求的负担。

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). 简单地说<form action =“”method =“PUT”>将无效,因为没有支持该方法的浏览器(并且它们只是默认为GET,处理PUT与处理像FDSFGS这样的乱码一样)。 Sadly those HTTP verbs are limited to the realm of non-desktop application browsers (ie: web service consumers). 遗憾的是,这些HTTP动词仅限于非桌面应用程序浏览器领域(即:Web服务使用者)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM