my PHP page currently doesnot have a mail server, instead of throwing an error, is it possible to catch this error and print it out to the user?
this is what I have so far, it just gives an error.
<?php
$foo = mail('test#test.com', 'subject', 'message');
if ( $foo == false )
{
echo "no mail server";
}
?>
thanks!
You could open a port to the mail server in question using fsockopen('servername/ipaddres', 25); If it returns content, it means the port is open and that you could ASSUME that there is a mail server.
$errno = 0;
$errstr = '';
$fp = fsockopen("localhost", 25, $errno, $errstr, 5);
if (!$fp) {
echo "No mail server responded on this server on port 25, validate your configuration";
}
This is by all means very experimental, you need to involve yourself in more work but it should get you started :)
mail() could fail for other reasons than just a non-existant mail server. I think the best you can do is fail gracefully and show the user the message you got, and even that has limitations.
In PHP 5.1 and above, you could catch the error in the following way:
error_reporting(0); // Don't display errors
$success = mail(....);
if (!$success)
{
echo "Mailing failed: Error message: ".error_get_last();
}
if you need to support older versions than that, I think you'll have no option than showing the raw error message from mail() - you could theoretically suppress it, but that will not show the user what exactly went wrong.
Related
I make a php page to send email. I will give this page to multiple users, but I have no control of the server they will use. And some of them should have no SMTP server. So I try to handle this error.
For example, on my own computer, if I deactivate my SMTP server, I receive a "PHP Warning: mail(): Failed to connect to mailserver at ..." error message.
My code :
try
{
$okmail=mail($to,$Subject,$texte,$headers);
}
catch (Exception $ex)
{
...
}
But this code doesn't throw an exception, it only write the error message (like an "echo(...)" statement).
I use this code in a xmlhttprequest page and use an xml type response. But the original page receive the error message before the xml text :
PHP Warning: mail(): Failed to connect to mailserver at ... \n1Email not send
How can I handle this "no SMTP" error ?
Thanks!
If I understand the problem correctly, the following directive will hide the warnings.
ini_set('display_errors', 0);
Instead of "try/catch" you can use the following approach.
set_error_handler("warningHandler", E_USER_WARNING);
// Trigger some warning here for testing purposes only (this is just an example).
trigger_error('This here is the message from some warning ...', E_USER_WARNING);
// If you need DNS Resource Records associated with a hostname.
// $result = dns_get_record($_SERVER['HTTP_HOST']);
// Restores the previous error handler function.
restore_error_handler();
// This is your custom warning handler.
function warningHandler($errno, $errstr) {
// Do what you want here ...
echo $errno, ' ::: ', $errstr;
}
Thanks for your answers, but nothing works :(
I find a solution by cleaning the output buffer by using ob_start(null,0,PHP_OUTPUT_HANDLER_CLEANABLE) and ob_clean() just after the mail() function.
I don't understand why the mail function writes an error into the output buffer
I'm in the process of creating my own service status script as both a chance to become more familiar with the PHP language and to design it from the ground up as being as efficient as possible for my needs.
A section of my code used in both my cron job and testing a connection parts queries the IP/Port of a service to make sure it is online. My issue is that the script simply queries whether the port is "Unblocked" on that IP so if for instance I was querying port 21 with an FTP server and that FTP server crashed my script would not detect any changes meaning its not doing what I want it to do. Instead I would be wanting the IP and port to be queried and for my script to see if there is actually something running on that port, if there is show online if not error out. I've had a look on google and it seems like I would have to send a packet/receive a response so PHP can tell there's something active? I'm not sure.
This is my current code below:
<?php
$host = $_POST['servip'];
$port = $_POST['servport'];
if (!$socket = #fsockopen($host, $port, $errno, $errstr, 3)) {
echo "Offline!";
} else {
echo "Online!";
fclose($socket);
}
?>
http://php.net/manual/en/function.fsockopen.php
fsockopen — Open Internet or Unix domain socket connection The socket
will by default be opened in blocking mode. You can switch it to
non-blocking mode by using stream_set_blocking(). The function
stream_socket_client() is similar but provides a richer set of
options, including non-blocking connection and the ability to provide
a stream context.
Since fsockopen will either connect or not connect (timeout) then that tells you whether or not a connection is available ("open") or being blocked (firewall, etc).
// Ping by website domain name, IP address or Hostname
function example_pingDomain($domain){
$starttime = microtime(true);
$file = #fsockopen($domain, 80, $errno, $errstr, 10);
$stoptime = microtime(true);
$status = 0;
if (!$file) {
$status = -1; // Site is down
} else {
fclose($file);
$status = ($stoptime - $starttime) * 1000;
$status = floor($status);
}
return $status;
}
If you really want to know if the FTP server is working or not, your best option is to actually send FTP commands through to it.
An FTP server, upon connect, should typically reply with the first three bytes "220" or "120". 220 is a "greeting". You can read more in RFC 959.
To be completely sure, you might be better off using ftp:// handling in PHP, e.g. actually authenticating a user (maybe user authentication is broken, but it's still able to send a greeting - does that count is "down"?)
Anyway, if you want better than "was I able to connect on that port?" or "did the connect succeed in a timely fashion?", you have to delve into actual communication over the socket. Ultimately, this means you have to do something special for each type of service (for some, read bytes, for others write bytes, etc.)
I'm trying to make tcp socket server to create and maintain persistent bidirectional communications, via PHP's stream_socket_server().
Short version of question:
how to have tcp server created with stream_socket_server() staying
alive - not failing to receive data after first successful data
reception which is in my case one single character typed in terminal after telnet
command?
Long version - what exactly I expect to achieve
Just for illustration, look at communication type when telneting some host with smtp server. You type in terminal telnet somehost 25 and get welcome response and (usually) smtp banner. And connection persists. Than you type hello command, and you get, again, response with option to proceed issuing further commands. Again, connection persists, you got response and option to continue. This is exact communication type I'm after.
What have I done so far
this code:
<?php
$server = stream_socket_server("tcp://0.0.0.0:4444", $errno, $errorMessage);
if ($server === false) throw new UnexpectedValueException("Could not bind to socket: $errorMessage");
for (;;) {
$client = stream_socket_accept($server);
if ($client)
{
echo 'Connection accepted from ' . stream_socket_get_name($client, false) . "\n";
echo "Received Out-Of-Band: " . fread($client, 1500) . "\n";
#fclose($client);
}
}
which works fine if you are just trying to send data (once per shot) via another PHP script i.e. stream_socket_client().
Server created by this script fails to maintain connection type I have described. After doing telnet localhost 4444 I'm switched into terminal mode to write message. When I do so, on the server side I got first typed character caught up and - nothing more. Whatever I've tried, I couldn't catch new packages sent from client side by typing. Like stream_socket_accept() blocks or ignores all after first character-data package received.
So, what am I doing wrong - how to solve this issue?
Your program is only doing a single read before it loops back to accept another incoming connection.
The documentation for fread states that it will return as soon as a packet has been received. That is, it won't wait for the full 1500 bytes.
Given the slow speed of human typing, you end up sending a packet with a single character to your server which is returned and then it goes on to accept another incoming connection.
Put a loop around your read as such:
for (;;) {
$client = stream_socket_accept($server);
if ($client) {
echo 'Connection accepted from ' . stream_socket_get_name($client, false) . "\n";
for (;;) {
$data = fread($client, 1500);
if ($data == '') break;
echo "Received Out-Of-Band: " . $data . "\n";
}
fclose($client);
}
}
I have a stream socket server written in PHP.
To see how many connections it can handle at a time,I wrote a simulator in C to create 1000 different clients to connect to the server.
stream_socket_accept was returning false a few times.
I need to find out the reason for this failure.
I tried socket_last_error() and socket_strerror() to get the error codes, but they returned 'Success'. These functions don't seem to be working on stream-sockets. Is there any way/ method to find out the actual error codes
My code:
$socket = #stream_socket_accept($this->master, "-1", $clientIp);
$ip = str_getcsv($clientIp, ":");
//socket accept error
if($socket === FALSE)
{
$this->logservice->log($this->module_name, "ERROR", "cannot accept the device connection");
***// Need to find error code here ***
}
I am able to see PHP level error messages in my logs now. # operator before stream_socket_accept was suppressing the error messages. (# symbol in php )
Could somebody help me with the php function fsockopen?
if I call the function like this :
$fp = fsockopen('xywqnda.com', 80, $errno, $errstr, 10);
With an unavailable host domain, it will never return false and I don't understand why!
Ah, you are using UDP. Your original example didn't show this. This changes things. From the PHP manual:
Warning
UDP sockets will sometimes appear to have opened without an error, even if the remote host is unreachable. The error will only
become apparent when you read or write data to/from the socket. The
reason for this is because UDP is a "connectionless" protocol, which
means that the operating system does not try to establish a link for
the socket until it actually needs to send or receive data.
try this
ini_set("display_errors","on")
it will show up a warning if the domain is invalid, other than that the function will return TRUE because the file pointer is returned, meaning file was created with success, FALSE will be returned only if it can't create the file.
// displays all warnings, notices and errors
ini_set('display_errors', 1);
error_reporting(E_ALL);
$fp = fsockopen('xywqnda.com', 80, $errno, $errstr, 10);
The connection attempt will timeout after 10 seconds.
You will get a warning because the domain is unavailable.
$errno and $errstr will contain the system error number and error message.
The function will return false, so $fp will be equal to false.
Documentation: fsockopen