如何使 CGIHTTPRequestHandler 使用 POST 数据执行我的 PHP 脚本
How to make CGIHTTPRequestHandler execute my PHP scripts with POST data
我目前正在尝试使用 Python 中的 http.server 模块来做一些简单的网络工作。
当我尝试将 POST 表单添加到我的脚本时,它没有收到 POST 数据,$_POST
是空的并且 file_get_contents('php://input')
也是如此。
这是我的 post_test.html
:
#!/usr/bin/php
<!DOCTYPE html>
<html>
<body>
<form method="post" action="post_test.html">
Name: <input type="text" name="fname">
<input type="submit">
</form>
<?php
if ($_SERVER["REQUEST_METHOD"] == "POST") {
// collect value of input field
echo "RAW POST: " . file_get_contents('php://input') . "<br>";
$name = $_POST['fname'];
if (empty($name)) {
echo "Name is empty";
} else {
echo $name;
}
}
?>
</body>
</html>
这是我的服务器脚本:
import urllib.parse
from http.server import CGIHTTPRequestHandler, HTTPServer
hostName = "localhost"
serverPort = 8080
handler = CGIHTTPRequestHandler
handler.cgi_directories.append('/php-cgi')
class MyServer(handler):
def do_GET(self):
# get path without first '/' and without anything besides path and filename
file = self.path[1:].split("?")[0].split("#")[0]
# if the file is in the script list, execute from php-cgi, else load from webapp
php_handle = ["post_test.html"]
if file in php_handle:
self.path = "/php-cgi" + self.path
else:
self.path = "/webapp" + self.path
CGIHTTPRequestHandler.do_GET(self)
def do_POST(self):
# get path without first '/' and without anything besides path and filename
file = self.path[1:].split("?")[0].split("#")[0]
# if the file is in the script list, execute from php-cgi
php_handle = ["post_test.html"]
if file in php_handle:
length = int(self.headers['Content-Length'])
post_data = urllib.parse.parse_qs(self.rfile.read(length).decode('utf-8'))
for key, data in post_data.items():
self.log_message(key + ": " + str.join(", ", data))
self.path = "/php-cgi" + self.path
CGIHTTPRequestHandler.do_POST(self)
def do_HEAD(self):
CGIHTTPRequestHandler.do_HEAD(self)
if __name__ == "__main__":
webServer = HTTPServer((hostName, serverPort), MyServer)
try:
webServer.serve_forever()
except KeyboardInterrupt:
pass
webServer.server_close()
print("Server stopped.")
好吧,我终于能够解决问题了:#!/usr/bin/php
是错误的,应该是#!/usr/bin/php-cgi
。
原因:php
没有使用 POST 数据,也无法将其提供给 php。
php-cgi
专为网络服务器而设计,可以处理。
Hwo 解决下一个问题: 要运行 php-cgi
成功你必须在当前目录下创建一个php.ini,有两个设置。
第一个允许直接执行它,第二个设置脚本所在的目录。如果您不设置它,您将收到 404 not found
.
php.ini:
cgi.force_redirect = 0
doc_root = /home/username/server-directory
其中 server-directory
文件夹是包含 php.ini 和 php-cgi
文件夹的文件夹。此外,文件夹的名称与 php-cgi 二进制文件无关,这只是我命名的错误。
如果您尝试重新创建它,它现在应该可以完美运行。
我目前正在尝试使用 Python 中的 http.server 模块来做一些简单的网络工作。
当我尝试将 POST 表单添加到我的脚本时,它没有收到 POST 数据,$_POST
是空的并且 file_get_contents('php://input')
也是如此。
这是我的 post_test.html
:
#!/usr/bin/php
<!DOCTYPE html>
<html>
<body>
<form method="post" action="post_test.html">
Name: <input type="text" name="fname">
<input type="submit">
</form>
<?php
if ($_SERVER["REQUEST_METHOD"] == "POST") {
// collect value of input field
echo "RAW POST: " . file_get_contents('php://input') . "<br>";
$name = $_POST['fname'];
if (empty($name)) {
echo "Name is empty";
} else {
echo $name;
}
}
?>
</body>
</html>
这是我的服务器脚本:
import urllib.parse
from http.server import CGIHTTPRequestHandler, HTTPServer
hostName = "localhost"
serverPort = 8080
handler = CGIHTTPRequestHandler
handler.cgi_directories.append('/php-cgi')
class MyServer(handler):
def do_GET(self):
# get path without first '/' and without anything besides path and filename
file = self.path[1:].split("?")[0].split("#")[0]
# if the file is in the script list, execute from php-cgi, else load from webapp
php_handle = ["post_test.html"]
if file in php_handle:
self.path = "/php-cgi" + self.path
else:
self.path = "/webapp" + self.path
CGIHTTPRequestHandler.do_GET(self)
def do_POST(self):
# get path without first '/' and without anything besides path and filename
file = self.path[1:].split("?")[0].split("#")[0]
# if the file is in the script list, execute from php-cgi
php_handle = ["post_test.html"]
if file in php_handle:
length = int(self.headers['Content-Length'])
post_data = urllib.parse.parse_qs(self.rfile.read(length).decode('utf-8'))
for key, data in post_data.items():
self.log_message(key + ": " + str.join(", ", data))
self.path = "/php-cgi" + self.path
CGIHTTPRequestHandler.do_POST(self)
def do_HEAD(self):
CGIHTTPRequestHandler.do_HEAD(self)
if __name__ == "__main__":
webServer = HTTPServer((hostName, serverPort), MyServer)
try:
webServer.serve_forever()
except KeyboardInterrupt:
pass
webServer.server_close()
print("Server stopped.")
好吧,我终于能够解决问题了:#!/usr/bin/php
是错误的,应该是#!/usr/bin/php-cgi
。
原因:php
没有使用 POST 数据,也无法将其提供给 php。
php-cgi
专为网络服务器而设计,可以处理。
Hwo 解决下一个问题: 要运行 php-cgi
成功你必须在当前目录下创建一个php.ini,有两个设置。
第一个允许直接执行它,第二个设置脚本所在的目录。如果您不设置它,您将收到 404 not found
.
php.ini:
cgi.force_redirect = 0
doc_root = /home/username/server-directory
其中 server-directory
文件夹是包含 php.ini 和 php-cgi
文件夹的文件夹。此外,文件夹的名称与 php-cgi 二进制文件无关,这只是我命名的错误。
如果您尝试重新创建它,它现在应该可以完美运行。