Недавно я перенес свой код, который был полностью работоспособен на предыдущем сервере, но на новом сервере запросы POST не работают, но запросы GET работают нормально. Кроме того, проблема возникает, когда я отправляю запросы POST на конечные точки на одном сервере. Когда я отправляю POST-запросы на внешние серверы, код работает хорошо. Во время отладки данные, отправляемые через (POST), не принимаются на конечной точке, а данные отправляются через cURL.
Я использую эту функцию для вызова конечных точек API:
function CallAPI($method = "GET", $url = "", $data = false, $credentials = "") {
try {
if (isset($url) && !empty($url)) {
$curl = curl_init();
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
if (!empty($credentials)) {
curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($curl, CURLOPT_USERPWD, $credentials);
}
if ($method === "POST" || $method === "PUT") {
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl, CURLOPT_HTTPHEADER, ['Content-Type: application/x-www-form-urlencoded']);
} else if ($method === "GET") {
$url = sprintf("%s?%s", $url, http_build_query($data));
}
curl_setopt($curl, CURLOPT_TIMEOUT, 60);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
$response = curl_exec($curl);
if ($response === false) {
throw new Exception("cURL error: " . curl_error($curl));
}
$httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);
if ($httpCode < 200 || $httpCode >= 300) {
throw new Exception("HTTP error: " . $httpCode);
}
return $response;
} else {
return false;
}
} catch (Exception $e) {
// error_log("Error in CallAPI: " . $e->getMessage());
return false;
}
}
В целях отладки я создал простой скрипт для простого вывода отправляемых данных:
<?php
$response['status'] = "OK";
$data = !empty($_POST) ? $_POST : file_get_contents("php://input");
if (!empty($data)) {
$phpArray = json_decode($data, true);
$response['message'] = 'Data received successfully';
$response['data'] = $phpArray;
}
$response['status'] = 'Endpoint successfully reached.';
$response['method'] = $_SERVER['REQUEST_METHOD'];
$response['rawdata'] = $data;
echo json_encode($response);
exit;
?>
Детали сервера
Previous Server:
CentOS 8
cPanel WHM
PHP 8.1
New Server:
CentOS 8
CyberPanel
PHP 8.1
Что я пробовал:
РЕДАКТИРОВАТЬ После дальнейшей отладки и исследования выяснилось, что проблема связана с отправляемыми данными, которые не были изменены до, во время и после миграции. Вот пример данных:
$msg = "<h3>Hello ".ucwords($name).",</h3> We received your quotation request.<br/>Thank you for your interest in our services.<br/>Your quotation has been generated and attached to this email.<br/>We look forward to providing you with our services.<br/><hr/><small>Please note that a 60% upfront payment may be required before services are provided.</small><br/><small>Please note that this message is an automated response.</small><br/><p><p>You may need to download a PDF viewer program such as Adobe PDF Reader in order to view the attached document or you may simply download the document on your device and open the file using your browser.</p><strong><h5>Regards</h5>Support Team</strong><br/></p>";
$invoice = array(
"action" => "addQuote",
"type" => "document",
"ipaddress" => getIpAddress(),
"customer" => array(
"name" => $name,
"email" => $email,
"phone" => alphaNumeric($phone)
),
"products" => $cart,
"document" => array(
"name" => "quotation",
"date" => "",
"currency" => "",
"link" => ""
),
"mail" => array(
"subject" => $subject,
"to" => $email,
"bcc" => $info,
"text" => $msg,
"from" => $support,
"entity" => "Example Entity"
),
"sms" => array(
"to" => $phone,
"text" => "Hi ".ucwords($name).", Please find your quotation for requested services at $email. Thank you for your business.",
"token" => "f4eb27cea7255cea4d1ffabf593372e8"
),
"entity" => "5d14995453d10a56bd7c1d68"
);
$argv = json_encode(array("data" => $invoice));
$document = CallAPI("POST", "https://api.endpoint.com/", $argv);
print_r($document);
Я начал с использования простых строковых данных, чтобы проверить, работают ли POST и cURL, и получил ответ от сервера.
Затем я также попытался закомментировать часть свойств переменной $invoice. Я заметил, что когда я закомментирую либо msg в свойстве mail, либо text в свойстве sms, например, просто закомментирую любое из этих свойств, и сервер отправит ответ обратно.
Реализация: при входе в систему print_r(strlen($argv)); я понимаю, что мой код запускается и возвращает ответ только в том случае, если длина меньше или равна 1024.
Заставляет меня задаться вопросом:
json_encode/json_decode. (Я также пробовал комбинацию htmlentities и json_encode, но безуспешно)post_max_size в php.ini)кто-нибудь еще сталкивался с этим? Есть ли способ решить эту проблему?
Да, запрос отправляется, но ответ не отправляется.
Итак, простой скрипт в вашем вопросе получает запрос POST, но не отображает его в выводе JSON?
Я заметил странный заголовок: Content-Typex, который должен быть: Content-Type?
@KIKOSoftware Да, это опечатка, которой нет на сервере. Но также скрипт не работает и не возвращает ответ независимо от указанного заголовка типа контента.
Возможно, у вас есть ошибка в вашем простом тестовом сценарии. Например, когда $_SERVER['REQUEST_METHOD'] не определен. Вам также не нужен exit; в конце сценария. Вы можете проверить журнал ошибок PHP, чтобы увидеть, есть ли ошибки, или включить отчет об ошибках в выходных данных.
В журналах ошибок нет записей, и эти параметры также включены в код ini_set('display_errors', 1); ini_set('log_errors', 1); error_reporting(E_ALL);
but no response is sent back....какой код статуса возвращается?
Возвращенный код состояния — 200. При дальнейшем расследовании выясняется, что проблема не в коде, а в передаваемых данных. Кстати, пересылаемые данные после миграции не изменились. я внесу правку в вопрос.






Наконец я нашел ответ, и разница между серверами заключается в том, что на новом сервере, когда я POST-запрос с телом, клиент может включать заголовок «Ожидать: 100-продолжить». Этот заголовок сообщает серверу, что он должен ответить статусом «100 Продолжить» перед отправкой фактического тела запроса.
Чтобы решить эту проблему, я включил curl_setopt($curl, CURLOPT_HTTPHEADER, array('Expect:')); в свою функцию CallAPI.
Вот моя обновленная функция CallAPI:
function CallAPI($method = "GET", $url = "", $data = false, $credentials = "") {
try {
if (isset($url) && !empty($url)) {
$curl = curl_init();
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
if (!empty($credentials)) {
curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($curl, CURLOPT_USERPWD, $credentials);
}
if ($method === "POST" || $method === "PUT") {
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
} else if ($method === "GET") {
$url = sprintf("%s?%s", $url, http_build_query($data));
}
curl_setopt($curl, CURLOPT_TIMEOUT, 60);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Expect:'));
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
$response = curl_exec($curl);
if ($response === false) {
throw new Exception("cURL error: " . curl_error($curl));
}
$httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);
if ($httpCode < 200 || $httpCode >= 300) {
throw new Exception("HTTP error: " . $httpCode);
}
return $response;
} else {
return false;
}
} catch (Exception $e) {
// error_log("Error in CallAPI: " . $e->getMessage());
return false;
}
}
Вы можете использовать инструменты разработчика браузера, чтобы узнать, был ли отправлен POST-запрос. Если это так, вы знаете, что это проблема с получением.