try {
$fp = fsockopen($site, $port, $errno, $errstr, 2);
}
catch(Exception $ex) {
echo 'error';
}
Why is the catch not working, while I'm see that warnings are given for fsockopen
Warning: fsockopen(): php_network_getaddresses: getaddrinfo failed: No such host is known.
and
Warning: fsockopen(): unable to connect to www.myrandsitedf.net:80 (php_network_getaddresses: getaddrinfo failed: No such host is known. )
I know that I can use # to suppress the error/warning messages, but I don't think that this is the right way to handle an error.
Also the Cronjob at my host doesn't allow PHP files with errors in it, # doesn't solve it.
You have to use the exception with global namespace.
Try this code:
try {
$fp = fsockopen($site, $port, $errno, $errstr, 2);
}
catch(\Exception $ex) { //used back-slash for global namespace
echo 'error';
}
This will work in php 5.3 or later.
Thanks.
You have to make the difference between exceptions and errors.
If you want errors (warning, etc...) to be transformed into exception such that they can be caught in the catch, you should register a error_handler that converts the error into an exception:
function error_handler($errno, $errstr, $errfile, $errline)
{
if( ($errno & error_reporting()) > 0 )
throw new ErrorException($errstr, 500, $errno, $errfile, $errline);
else
return false;
}
set_error_handler('error_handler');
The easy and proper way to do this
try {
$fp = #fsockopen($ip, $port, $errno, $errstr, 5);
#fclose($fp);
return true;
} catch (\Exception $th) {
// return "error";
return $th;
}
Related
I want to escape the error generated by fsockopen and it works like this.
if ($fp = #fsockopen($host,$port,$errCode,$errStr,$waitTimeoutInSeconds)) { //... }
but i have been trying other things to avoid # and I have not managed.
Is there a code that I can use that is equivalent to this?
I have tried as well something like this just for testing purposes:
try{
if ($fp = fsockopen($host,$port,$errCode,$errStr,$waitTimeoutInSeconds)) {
/...
}
//..
} catch (Exception $e){
echo 'Error';
}
It does not work.
Warning: fsockopen(): unable to connect to localhost:79 (A connection
attempt failed because the connected party did not properly respond after a period of time or established
connection failed because connected host has failed to respond.
Use set_error_handler() an convert all the errors to an exception you can catch afterwards:
set_error_handler(function($errno, $errstr, $errfile, $errline, array $errcontext) {
if(0 === error_reporting())
return false;
throw new PHPException($errno, $errstr, $errfile, $errline, $errcontext);
});
So now you can catch the PHP error:
try {
if ($fp = fsockopen($host,$port,$errCode,$errStr,$waitTimeoutInSeconds)) {
//...
}
//..
} catch (\Exception $e){
echo 'Connection failed: ' , $e->getMessage();
}
echo 'Don\'t worry... go on!';
You can disable notices and warnings in production systems (instead write to a log):
error_reporting(E_ERROR);
In development environments you'd probably want all errors, notices and warnings on though:
error_reporting(E_ALL);
check out the error reporting levels here: http://php.net/manual/en/errorfunc.configuration.php#ini.error-reporting
EDIT: To check for an error:
$fp = #fsockopen("www.example.com", 80, $errno, $errstr, 30);
if (!$fp) {
echo "$errstr ($errno)<br />\n";
} else {
...
}
I think if you are handling failure scenarios then consciously suppressing a warning using # is ok.
I'm trying to check a servers UDP port using PHP. here is my code:
<?php
set_error_handler('my_error_handler');
function my_error_handler($errno, $errstr, $errfile, $errline) {}
function checkUDP($host,$port=80){
$fp = fsockopen("udp://".$host, $port, $errno, $errstr,1.0);
if (!$fp) {
return false;
} else {
fclose($fp);
return true;
}
}
if(checkUDP($MyIP,9)){
echo $MyIP.' is open';
}else{
echo $MyIP.' is closed';
}
echo '<br />';
?>
But I always get True result (port is open). This code works on TCP port but why I couldn't get the UDP port results?
I'm trying to create a library for a personal project using php sockets. For that I started using phpUnit, to learn and to write a (more or less) qualitative library.
When i don't provide the try/catch block in the testConnection method, php gives an error that the connection has timed out (wich is normal, 'cause the device isn't connected). But php should handle the exception in the execute method below, not in the testConnection method. And I can't seem to figure this out.
This is the error:
PHPUnit_Framework_Error_Warning : stream_socket_client(): unable to connect to tcp://x.x.x.x:* (A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.)
Testclass with method and try/catch that should not be there:
public function testConnection() {
$adu = new Adu();
$adu->setPort('AS0');
$adu->setData('?');
$command = new Command('x.x.x.x', *);
$command->setAduSent($adu);
try
{
$command->execute();
}
catch (Exception $e)
{
echo $e->getMessage();
}
}
This (the execute method) is where the Exception should be handled:
public function execute()
{
try {
$this->stream = $this->createStream($this->address, $this->port, $this->timeout);
}
catch(Exception $e) {
$this->logger->error('Exception (' . $e->getCode() . '): ' . $e->getMessage() . ' on line ' . $e->getLine(), $e);
}
$this->send($this->stream, $this->aduSent);
$this->aduReceived = $this->receive($this->stream);
}
private function createStream($address, $port, $timeout = 2)
{
$stream = stream_socket_client('tcp://' . $address . ':' . $port, $errorCode, $errorMessage, $timeout);
if(!$stream) {
throw new Exception('Failed to connect(' . $errorCode . '): ' . $errorMessage);
}
return $stream;
}
Solution
Because a try/catch won't catch errors/warnings I had to suppress the warnings triggered by the stream_socket_client. An then check if the return value is false or a stream object. If false, throw an appropriate Exception.
$stream = #stream_socket_client('tcp://' . $address . ':' . $port, $errorCode, $errorMessage, $timeout);
The stream_socket_client sentence produces a warning, not an Exception, and warnings are not captured by try / catch blocks.
But PHPUnit do capture warnings, and throws an Exception in that case, so an error is triggered. You can configure PHPUnit not to consider warnings as errors, although I would not recommend it. Your code should be warnings free. PHPUnit docs.
I'm setting up reporting on my PHP script with etsy's open source statsd library.
I'm basing my connection on their given example, but I'm running into an issue where it seems like fsockopen is ignoring try/catch and is printing its errors.
Everything works grand when the statsd server is up and running - but if it's down or the php script cannot connect to it:
Warning: fsockopen(): php_network_getaddresses: getaddrinfo failed:
Name or service not known
I even attempted adding # in front of fsockopen, but no dice. It also seems to be completely ignoring the timeout setting, as it takes about 20 seconds to return the error:
try {
$host = 'stats.thisserverisdown.com';
$port = '8125';
if ( $fp = #fsockopen("udp://$host", $port, $errno, $errstr, 1) ) {
if (!(get_resource_type($fp) == 'stream')) { return false; }
stream_set_timeout($fp,1);
stream_set_blocking($fp,false);
foreach ($sampledData as $stat => $value) {
#fwrite($fp, "$stat:$value");
}
#fclose($fp);
}
return true;
} catch (Exception $e) {
return false;
}
fsockopen is not throwing the error. Because fsockopen has to resolve the hostname you provided, it calls getaddinfo(), which is failing.
Try supplying an IP address, or:
fsockopen( #"udp://$host", ...
I am using fsockopen to get information from a UDP address, the only problem being that some of the UDP addresses may not still be active.
I create the socket by
$fp = fsockopen($tracker, $port, $errno, $errstr, 1);
If the address is valid everything works fine, but if the address is invalid it generates this error
Warning: fsockopen(): php_network_getaddresses: getaddrinfo failed: Name or service not known in
I tried doing this but it still generates the error,
if(!$fp = fsockopen($tracker, $port, $errno, $errstr, 1)) {
// ERROR
} else {
// CONTINUE
}
I can error suppress it and all is good but I do not like error suppressing in my code.
How can I make sure any given UDP address is still active with php?
Thanks
Instead of suppressing the error # which you could do, you could implement your own error handler. set_error_handler
<?php
//Simple Blank error handler
set_error_handler('my_error_handler');
function my_error_handler($errno, $errstr, $errfile, $errline) {}
function checkUDP($host,$port=80){
//look no suppression
$fp = fsockopen("udp://".$host, $port, $errno, $errstr,1.0);
if (!$fp) {
return false;
} else {
fclose($fp);
return true;
}
}
$good = 'tracker.publicbt.com';
$bad = 'trjjacker.publicbt.com';
if(checkUDP($good)){
echo $good.' Good';
}else{
echo $good.' Bad';
}
echo '<br />';
if(checkUDP($bad)){
echo $bad.' Good';
}else{
echo $bad.' Bad';
}
//tracker.publicbt.com Good
//trjjacker.publicbt.com Bad
?>