PHP 致命错误:未捕获的异常“异常”和消息

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1165122/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 01:18:44  来源:igfitidea点击:

PHP fatal error: Uncaught exception 'Exception' with message

phperror-handling

提问by Paul M

I have a PHP script that connects to an api and posts information to their systems, but when its trying to connect it throws a fatal error:

我有一个 PHP 脚本,它连接到一个 api 并将信息发布到他们的系统,但是当它尝试连接时会抛出一个致命错误:

Fatal error: Uncaught exception 'Exception' with message 'Problem with
'http://apitestserver.co.uk:9000/Service.svc/Items' in
/var/www/html/e/connect_test.php:17 Stack trace: #0 
/var/www/html/e/connect_test.php(39): 
do_http_request('http://apitest....', 'hello') #1 {main} thrown in 
/var/www/html/e/connect_test.php on line 17

If I send it to a PHP script which just grabs the IP then it works, but if I send it to the API it doesn't. My PHP script creates XML and then forwards to the server. I was getting errors so I just created the following smaller script purely to test the connection:

如果我将它发送到一个只获取 IP 的 PHP 脚本,那么它就可以工作,但是如果我将它发送到 API,它就不会。我的 PHP 脚本创建 XML,然后转发到服务器。我遇到了错误,所以我只是创建了以下较小的脚本,纯粹是为了测试连接:

function do_http_request($url, $data, $method = 'POST', 
    $optional_headers = 'Content-Type: application/atom+xml') {

  $params = array(
    'http' => array(
        'method' => $method,
        'content' => $data
    )
  );

  if ($optional_headers !== null) {
    $params['http']['header'] = $optional_headers;
  }

  $ctx = stream_context_create($params);
  $fp = fopen($url, 'rb', false, $ctx);
  if (!$fp) {
    throw new Exception("Problem with $url");
  }

  $response = @stream_get_contents($fp);
  if ($response === false) {
    throw new Exception("Problem reading data from $url");
  }

  $metaData = stream_get_meta_data($fp);
  fclose($fp);

  if(!preg_match('~^HTTP.*([0-9]{3})~', 
    $metaData['wrapper_data'][0], $matches)){
    throw new Exception('MALFORED RESPONSE - COULD NOT UNDERSTAND HTTP CODE');
  }
  if (substr($matches[1], 0, 1) != '2') {
    throw new Exception('SERVER REPORTED HTTP ERROR ' . $matches[1]);
  }
  return $response;
}
$data = 'hello';
$paul = 
  do_http_request('http://apitestserver.co.uk:9000/Service.svc/Items',$data);

echo $paul;

If I change the URL to a simple script on another one of our servers which just grabs the IP of the incoming connection and returns it:

如果我将 URL 更改为我们另一台服务器上的简单脚本,该脚本只是获取传入连接的 IP 并返回它:

 $ip=$_SERVER['REMOTE_ADDR'];
 echo 'IP equals = ' . $ip;

Then it works fine with no errors.

然后它工作正常,没有错误。

Update -

更新 -

with errors on it throws the following warning, probably because the script is not sending the correct info to the API

有错误会抛出以下警告,可能是因为脚本没有向 API 发送正确的信息

Warning: fopen(http://apitestserver.co.uk:9000/Service.svc/Items) 
[function.fopen]: failed to open stream: HTTP request failed! HTTP/1.1 
500 Data at the root level is invalid. Line 1, position 1.

Also note that I can access the api server fine using fiddler to send manually created items across, its just when this script tries to connect and send data there is an issue. I wrote another quick script which connects and prints out the default response (an rss feed of submitted items)

另请注意,我可以使用 fiddler 很好地访问 api 服务器以发送手动创建的项目,就在此脚本尝试连接和发送数据时出现问题。我编写了另一个快速脚本,它连接并打印出默认响应(提交项目的 rss 提要)

When I run the 'main' connector script it throws the following two errors

当我运行“主”连接器脚本时,它会引发以下两个错误

Warning: fopen() [function.fopen]: php_network_getaddresses: 
getaddrinfo failed: Name or service not known in 
/var/www/html/e/sequence.php on line 65

Warning: fopen(http://apitestserver.co.uk:9000/Service.svc/Items) 
[function.fopen]: failed to open stream: Operation now in progress 
in /var/www/html/e/sequence.php on line 65

采纳答案by acrosman

I would suggest using curlinstead of fopen(). curl is both more flexible, and more secure. Many servers disable allow_url_fopen, curl also fails more gracefully when there are problems on the remote server.

我建议使用curl而不是fopen(). curl 更灵活,更安全。许多服务器禁用allow_url_fopen,当远程服务器出现问题时,curl 也会更优雅地失败。

回答by Greg

I just tested the URL in my browser and got a connection error.

我刚刚在浏览器中测试了 URL 并出现连接错误。

Maybe the problem is with their server (or you have the wrong URL)?

也许问题出在他们的服务器上(或者你有错误的 URL)?

Edit:

编辑:

Looks like ther server is throwing a 500 error - maybe because the data you're posting is invalid.

看起来服务器抛出了 500 错误 - 可能是因为您发布的数据无效。

You could use a packet sniffer and check the exact data you're sending to the server (or use cURL as suggested by @acrosman)

您可以使用数据包嗅探器并检查您发送到服务器的确切数据(或按照@acrosman 的建议使用 cURL)

回答by Torandi

apitestserver.co.uk doesn't respond to ping and the url is inaccessable. The API-server doesn't seem to be up.

apitestserver.co.uk 不响应 ping 并且 url 无法访问。API 服务器似乎没有启动。

回答by leafnode

First error message suggests problems with apitestserver - it returns error code 500, which states for "Internal server error".

第一条错误消息表明 apitestserver 存在问题 - 它返回错误代码 500,表示“内部服务器错误”。

Second one informs that PHP can't resolve host name into IP address - I'd look into DNS configuration and/or hosts file.

第二个通知 PHP 无法将主机名解析为 IP 地址 - 我会查看 DNS 配置和/或主机文件。



Apparently 'fopen' function does not return proper stream. There can be many possibilities when that happens, but according to PHP manual, fopen function on fail should present E_WARNING message with proper commentary. It is possible that you have errors of that class silenced - call error_reporting(E_ALL) at the beginning of your script and look for some relevant error messages.

显然 'fopen' 函数没有返回正确的流。发生这种情况时可能有很多可能性,但根据 PHP 手册,失败时的 fopen 函数应显示带有适当注释的 E_WARNING 消息。有可能您已经消除了该类的错误 - 在脚本开头调用 error_reporting(E_ALL) 并查找一些相关的错误消息。

回答by nothingchen

or You can change the headers:

或者您可以更改标题:

$optional_headers = 'Content-Type: application/json')