宝塔618特惠活动,企业版999元/年,宝塔SSL证书买1送1!限时抢购!查看活动
当前位置:论坛首页 > Linux面板 > 求助

【已完成】php fsockopen() 发送请求的问题

发表在 Linux面板2024-7-6 16:39  关闭 [复制链接] 6 1265

面板、插件版本:免费版8.0.5
系统版本:Debian 12
问题描述:php fsockopen() 发送请求的问题,基本上可以排除代码本身的问题,请求同站点上的地址返回400
HTTP/1.1 400 Bad Request
Date: Sat, 06 Jul 2024 08:17:42 GMT
Server: Apache
Content-Length: 292
Connection: close
Content-Type: text/html; charset=iso-8859-1

Your browser sent a request that this server could not understand.
Apache Server at ssl.default.com Port 443
相关截图(日志、错误):

又cccccccccccc.png
使用道具 举报 只看该作者 回复
发表于 2024-7-6 16:45:15 | 显示全部楼层
  1. <?php

  2. /**
  3. * 异步请求
  4. * @author
  5. * @see
  6. * @version 1.0.1 2023-07-11
  7. */

  8. namespace Classes\Function;

  9. class AsynRequest
  10. {

  11.     /**
  12.      * 获取URL各参数
  13.      * @param string $url
  14.      * @return array
  15.      */
  16.     private static function getUrlInfo(string $url): array
  17.     {
  18.         $url_arr = parse_url($url);
  19.         $url_info = [
  20.             'hostname' => $url_arr['host'],
  21.             'host' => $url_arr['host'],
  22.             'port' => 80,
  23.             'path' => $url_arr['path'] ?? '/'
  24.         ];
  25.         if ('https' === $url_arr['scheme']) {
  26.             $url_info['hostname'] = 'ssl://' . $url_arr['host'];
  27.             $url_info['port'] = 443;
  28.         }
  29.         return $url_info;
  30.     }

  31.     /**
  32.      * GET请求
  33.      * @param string $url
  34.      * @param array $data = []
  35.      * @param int $timeout = 20
  36.      * @return bool
  37.      */
  38.     public static function get(string $url, array $data = [], int $timeout = 20): bool
  39.     {
  40.         $url_info = self::getUrlInfo($url);
  41.         $data = http_build_query($data);
  42.         $fp = fsockopen($url_info['hostname'], $url_info['port'], $errno, $errstr, $timeout);
  43.         if (!$fp) {
  44.             return false;
  45.         }
  46.         stream_set_blocking($fp, true);
  47.         stream_set_timeout($fp, $timeout);
  48.         $out = 'GET ' . $url_info['path'] . '?' . $data . ' HTTP/1.1' . PHP_EOL;
  49.         $out .= 'Host: ' . $url_info['host'] . PHP_EOL;
  50.         $out .= 'Content-Type: text/xml; charset=utf-8' . PHP_EOL;
  51.         $out .= 'Connection: Close' . PHP_EOL . PHP_EOL;
  52.         fputs($fp, $out);
  53.         while (!feof($fp)) {
  54.             echo fgets($fp, 128);
  55.         }
  56.         usleep(10000);
  57.         fclose($fp);
  58.         return true;
  59.     }

  60.     /**
  61.      * POST请求
  62.      * @param string $url
  63.      * @param array $data = []
  64.      * @param int $timeout = 20
  65.      * @param string $content_type = 'application/json'
  66.      * @return bool
  67.      */
  68.     public static function post(string $url, array $data = [], int $timeout = 20, string $content_type = 'application/json'): bool
  69.     {
  70.         $url_info = self::getUrlInfo($url);
  71.         $data = json_encode($data);
  72.         $fp = fsockopen($url_info['hostname'], $url_info['port'], $errno, $errstr, $timeout);
  73.         if (!$fp) {
  74.             return false;
  75.         }
  76.         stream_set_blocking($fp, true);
  77.         stream_set_timeout($fp, $timeout);
  78.         $out = 'POST ' . $url_info['path'] . ' HTTP/1.1' . PHP_EOL;
  79.         $out .= 'Host: ' . $url_info['host'] . PHP_EOL;
  80.         $out .= 'Content-Type: ' . $content_type . '; charset=utf-8' . PHP_EOL;
  81.         $out .= 'Content-Length: ' . strlen($data) . PHP_EOL;
  82.         $out .= 'Connection: Close' . PHP_EOL . PHP_EOL;
  83.         $out .= $data . PHP_EOL;
  84.         fwrite($fp, $out);
  85.         while (!feof($fp)) {
  86.             echo fgets($fp, 128);
  87.         }
  88.         usleep(10000);
  89.         fclose($fp);
  90.         return true;
  91.     }

  92. }
复制代码
使用道具 举报 回复 支持 反对
发表于 2024-7-6 17:20:13 | 显示全部楼层

您好,您这百年尝试使用以下方式来执行一下
  1. public static function get(string $url, array $data = [], int $timeout = 20): bool
  2. {
  3.     $url_info = self::getUrlInfo($url);
  4.     $data = http_build_query($data);
  5.     $fp = fsockopen($url_info['hostname'], $url_info['port'], $errno, $errstr, $timeout);
  6.     if (!$fp) {
  7.         return false;
  8.     }
  9.     stream_set_blocking($fp, true);
  10.     stream_set_timeout($fp, $timeout);
  11.     $out = 'GET ' . $url_info['path'] . '?' . $data . ' HTTP/1.1' . PHP_EOL;
  12.     $out .= 'Host: ' . $url_info['host'] . PHP_EOL;
  13.     $out .= 'Content-Type: application/x-www-form-urlencoded; charset=utf-8' . PHP_EOL; // 修改Content-Type
  14.     $out .= 'Connection: Close' . PHP_EOL . PHP_EOL;
  15.     fputs($fp, $out);
  16.     while (!feof($fp)) {
  17.         echo fgets($fp, 128);
  18.     }
  19.     usleep(10000);
  20.     fclose($fp);
  21.     return true;
  22. }
复制代码
使用道具 举报 回复 支持 反对
发表于 2024-7-6 17:24:12 | 显示全部楼层
运维技术阿闯 发表于 2024-7-6 17:20
您好,您这百年尝试使用以下方式来执行一下

你好,也是一样的,这个Content-Type尝试过不同的内容,任然是一样的,返回 400
  1. public static function get(string $url, array $data = [], int $timeout = 20): bool
  2.     {
  3.         $url_info = self::getUrlInfo($url);
  4.         $data = http_build_query($data);
  5.         $fp = fsockopen($url_info['hostname'], $url_info['port'], $errno, $errstr, $timeout);
  6.         if (!$fp) {
  7.             return false;
  8.         }
  9.         stream_set_blocking($fp, true);
  10.         stream_set_timeout($fp, $timeout);
  11.         $out = 'GET ' . $url_info['path'] . '?' . $data . ' HTTP/1.1' . PHP_EOL;
  12.         $out .= 'Host: ' . $url_info['host'] . PHP_EOL;
  13.         $out .= 'Content-Type: application/x-www-form-urlencoded; charset=utf-8' . PHP_EOL;
  14.         $out .= 'Connection: Close' . PHP_EOL . PHP_EOL;
  15.         fputs($fp, $out);
  16.         while (!feof($fp)) {
  17.             echo fgets($fp, 128);
  18.         }
  19.         usleep(10000);
  20.         fclose($fp);
  21.         return true;
  22.     }
复制代码
使用道具 举报 回复 支持 反对
发表于 2024-7-6 18:02:47 | 显示全部楼层
宝塔用户_ogyvui 发表于 2024-7-6 17:24
你好,也是一样的,这个Content-Type尝试过不同的内容,任然是一样的,返回 400
...

您好,您这边在这个贴子里边的尝试一下
https://blog.csdn.net/zjsfdx/article/details/89376176
使用道具 举报 回复 支持 反对
发表于 2024-7-6 18:22:39 | 显示全部楼层
运维技术阿闯 发表于 2024-7-6 18:02
您好,您这边在这个贴子里边的尝试一下
https://blog.csdn.net/zjsfdx/article/details/89376176 ...

谢谢,找到根本原因了,已解决。
PHP_EOL 替换成 \r\n 就可以了。
使用道具 举报 回复 支持 反对
发表于 2024-7-6 18:32:15 | 显示全部楼层
宝塔用户_ogyvui 发表于 2024-7-6 18:22
谢谢,找到根本原因了,已解决。
PHP_EOL 替换成 \r\n 就可以了。

好的,问题解决了就好,后续有问题可以在开新帖呢,这边就闭贴了,祝您生活愉快
使用道具 举报 回复 支持 反对
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

普通问题处理

论坛响应时间:72小时

问题处理方式:排队(仅解答)

工作时间:白班:9:00 - 18:00

紧急运维服务

响应时间:3分钟

问题处理方式:宝塔专家1对1服务

工作时间:工作日:9:00 - 18:30

宝塔专业团队为您解决服务器疑难问题

点击联系技术免费分析

工作时间:09:00至18:30

快速回复 返回顶部 返回列表