Jump to content


Check out our Community Blogs

Register and join over 40,000 other developers!


Recent Status Updates

View All Updates

- - - - -

PHP: Ping with Pear

php

  • Please log in to reply
17 replies to this topic

#1 Guest_Jordan_*

Guest_Jordan_*
  • Guest

Posted 02 October 2008 - 12:09 PM

I had to write a ping utility at work and based on the ping results from three different locations I had to present the user with a different website (front-page). Being a fan of PEAR packages I found Pear::Net_Ping. Within minutes I had a working ping program but I thought I would present the information to you.

This tutorial assumes you have a working installation of Pear and it is updated. At the time of this witting I will be using Net_Ping 2.4.3. You can find the documentation for Net_Ping here: PEAR :: Package :: Net_Ping

Installing Net_Ping
As always, installation of PEAR packages is extremely simple. Drop to your command prompt, open up a terminal, or SSH into your box and issue the command:

# pear install net_ping
If all goes well you should see results similar to this:

downloading Net_Ping-2.4.3.tgz ...
Starting to download Net_Ping-2.4.3.tgz (9,634 bytes)
.....done: 9,634 bytes
install ok: channel://pear.php.net/Net_Ping-2.4.3
You now have PEAR::Net_Ping installed.

Alternatively:
If your host is running cPanel you can install PEAR modules using the cPanel GUI.


Using the Module
Using the PEAR Package is as easy as including it.


require ("Net/Ping.php");
Now you will need to create the Object:


$pingObj = Net_Ping::factory();
And ping the IP or Hostname of your choice:


$response = $pingObj->ping('codecall.net');
print_r($response);
The complete script looks like this:


<?php
require ("Net/Ping.php");

$pingObj = Net_Ping::factory();
$response = $pingObj->ping('codecall.net');
print_r($response);

?>
Now this example is the most basic of examples and doesn't even check if the PEAR Object was created. Using the isError function of the PEAR class we can determine if the object thrown back is actually an error message.

isError() examines whether a variable is a PEAR_Error object and - optional - contains a specific error message or code. Read More: PEAR Manual - PEAR::isError()

Adding that to our code it becomes:


<?php
require ("Net/Ping.php");

$pingObj = Net_Ping::factory();

if(PEAR::isError($ping)) {
echo $ping->getMessage();
} else {
$response = $pingObj->ping('codecall.net');
print_r($response);
}
?>
If you execute the code above you will get some nasty results:

Net_Ping_Result Object ( [_icmp_sequence] => Array ( [0] => 114 [1] => 139 [2] => 101 ) [_target_ip] => 67.205.118.30 [_bytes_per_request] => 32 [_bytes_total] => 96 [_ttl] => 50 [_raw_data] => Array ( [0] => [1] => Pinging codecall.net [67.205.118.30] with 32 bytes of data: [2] => Reply from 67.205.118.30: bytes=32 time=114ms TTL=50 [3] => Reply from 67.205.118.30: bytes=32 time=139ms TTL=50 [4] => Reply from 67.205.118.30: bytes=32 time=101ms TTL=50 [5] => [6] => Ping statistics for 67.205.118.30: [7] => Packets: Sent = 3, Received = 3, Lost = 0 (0% loss), [8] => Approximate round trip times in milli-seconds: [9] => Minimum = 101ms, Maximum = 139ms, Average = 118ms ) [_sysname] => windows [_round_trip] => Array ( [min] => 101 [max] => 139 [avg] => 118 ) [_transmitted] => 3 [_received] => 3 [_loss] => 0 )

You can fix this by adding <pre> </pre> tags around the array dump:


<?php
require ("Net/Ping.php");

$pingObj = Net_Ping::factory();

if(PEAR::isError($ping)) {
echo $ping->getMessage();
} else {
$response = $pingObj->ping('codecall.net');

echo "<pre>";
print_r($response);
echo "</pre>";
}
?>
Which will now produce a more aesthetic result:

Net_Ping_Result Object
(
    [_icmp_sequence] => Array
        (
            [0] => 95
            [1] => 152
            [2] => 118
        )

    [_target_ip] => 67.205.118.30
    [_bytes_per_request] => 32
    [_bytes_total] => 96
    [_ttl] => 50
    [_raw_data] => Array
        (
            [0] => 
            [1] => Pinging codecall.net [67.205.118.30] with 32 bytes of data:
            [2] => Reply from 67.205.118.30: bytes=32 time=95ms TTL=50
            [3] => Reply from 67.205.118.30: bytes=32 time=152ms TTL=50
            [4] => Reply from 67.205.118.30: bytes=32 time=118ms TTL=50
            [5] => 
            [6] => Ping statistics for 67.205.118.30:
            [7] =>     Packets: Sent = 3, Received = 3, Lost = 0 (0% loss),
            [8] => Approximate round trip times in milli-seconds:
            [9] =>     Minimum = 95ms, Maximum = 152ms, Average = 121ms
        )

    [_sysname] => windows
    [_round_trip] => Array
        (
            [min] => 95
            [max] => 152
            [avg] => 121
        )

    [_transmitted] => 3
    [_received] => 3
    [_loss] => 0
)
Arguments
The code above isn't very useful, has no comments, and doesn't do anything. For my purpose I needed to check the the Packet _loss amount and I needed to limit the ping attempts to 1.

I looked through the documentation and searched on the web a bit but could not find an argument list anywhere. At face value it looks like the above code is as much as you can control the Ping object so I dug through the Net/Ping.php file and discovered a setArgs() function and a _createArgList() function. In the _createArgList() function is a list of paramters you can pass to setArgs:

timeout
iface
ttl
count
quiet
size
seq
deadline
As you can see from above, most ping options are available as pass through arguments.

Setting the Arguments
To set the arguments you need to pass an associative array to the setArgs() method. Here is how:


$pingObj->setArgs(array('count' => 1, 'ttl' => 50, 'timeout' => 100));


Here is our complete script:


<?php

/**
* Include the PEAR Ping Class
*
* @uses Pear::Net_Ping
*
*/
require ("Net/Ping.php");

/**
* Create the Ping Object/Class
*/
$pingObj = Net_Ping::factory();

/**
* If there is no error in creating the
* ping class then ping our source
*/
if(PEAR::isError($ping)) {
echo $ping->getMessage();
} else {
// Set the arguments
$pingObj->setArgs(array('count' => 1, 'ttl' => 50, 'timeout' => 100));

// Ping the Host
$response = $pingObj->ping('codecall.net');

print "<pre>";
print_r($response);
print "</pre>";
}


?>
For my needs at work I've added several more functions that aren't relevant here. Below I will show you a better need for the system.

A Practical Need
Justin from AmpHosted.com needed a ping script which emailed him on failure. It will run on the CodeCall server every 5 minutes (via cron job) and send him an alert if his server is down. Here are his requirements:


  • 10 Pings @ 5 Minute Intervals (controlled via cron)
  • Email @ 90% failure alert (9/10 pings fail)
  • Server IP: 74.55.90.58 (AmpHosted.com)
  • Information Requested - Times Failed, Ping Responses
Taking the job information above we can create a simple ping script:


<?php

// {{{ Header
/**
* AmpHosted.com Ping Test Script
*
* Pings AmpHosted.com 9 times and determines fail rate.
*
* PHP versions 4 and 5
*
* LICENSE:
*
* Copyright (c) 2008 CodeCall.net
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted under the terms of the BSD License.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @category Reports
* @author Jordan (CodeCall.net)
* @date 10-2-2008
* @version 1.0
* @link http://www.codecall.net
* @copyright 2008 CodeCall.net
* @uses PEAR::Net_Ping and Beyond
*/

// }}}
// {{{ Includes
/**
* Include the PEAR Ping Class
*
*/
require ("Net/Ping.php");

// }}}
// {{{ PHP Time Limit

/**
* If the server is unresponsive
* the script may take longer to
* respond than the default 30 seconds
*
*/
set_time_limit(200);

// }}}
// {{{ Defines

/**
* Define our paramters
*/
define('FAILURE_RATE', 9);
define('PING_RATE', 10);
define('HOST_NAME', '74.55.90.58');
define('TIMEOUT', 200);

// }}}
// {{{ Variables

/**
* Common Email Variables
*/
$emailBody = FAILURE_RATE
. " or more pings failed!"
. PHP_EOL
. "Ping Results: "
;
$emailSubject = "Ping Respinse Failed - AmpHosted01";
$emailAddress = "some@email.com";

// }}}
// {{{ Content

/**
* Create the Ping Object/Class
*/
$pingObj = Net_Ping::factory();

/**
* If there is no error in creating the
* ping class then ping our source
*/
if(PEAR::isError($ping)) {
echo $ping->getMessage();
} else {
// Set the arguments
$pingObj->setArgs(array('count' => PING_RATE, 'timeout' => TIMEOUT));

// Ping the Host
$response = $pingObj->ping(HOST_NAME);

// Determine the fail rate
if ($response->getLoss() >= FAILURE_RATE) {
foreach($response->getRawData() as $data) {
$emailBody .= $data . PHP_EOL;
}

// Send email
mail($emailAddress, $emailSubject, $emailBody);

// Print Error
echo "Error, sending Email!" . PHP_EOL;
}

}

// }}}

?>
Note
If you are under a cPanel host and you install your PEAR scripts via cPanel or via SSH you will need to use the full include path. You can find your full PEAR include path by going to "cPanel/PHP PEAR Packages". For CodeCall the PEAR location is "/home/codecall/php" so my Net_Ping Require would look like this:


require ("/home/codecall/php/Net/Ping.php");
EOF
That is it! If you have any questions ask me. If you want to know how it works ask phpForFun (Justin from AmpHosted.com).

Edited by Jordan, 03 October 2008 - 04:28 AM.
Removed Justin's email

  • 0

#2 phpforfun

phpforfun

    Speaks fluent binary

  • Expert Member
  • PipPipPipPipPipPipPip
  • 1056 posts

Posted 02 October 2008 - 12:18 PM

Jordan has it pinging amphosted.com, I blocked Codecalls Ip to see if it would fail to respond to a ping, wiating 5 minuts to see if it will txt me
  • 0

#3 Xav

Xav

    CC Mentor

  • VIP Member
  • PipPipPipPipPipPipPipPip
  • 8356 posts

Posted 02 October 2008 - 12:21 PM

AmpHosted, eh? A marketing scam, I suppose?
  • 0
If you enjoy reading this discussion and are thinking about commenting, why not click here to register and start participating in under a minute?

#4 phpforfun

phpforfun

    Speaks fluent binary

  • Expert Member
  • PipPipPipPipPipPipPip
  • 1056 posts

Posted 02 October 2008 - 12:31 PM

does it looks like a marketing scam?

Jordan, 15 min, no ping email yet
  • 0

#5 Xav

Xav

    CC Mentor

  • VIP Member
  • PipPipPipPipPipPipPipPip
  • 8356 posts

Posted 02 October 2008 - 12:33 PM

Yes, it does. Using AmpHosted as the example. ;)
  • 0
If you enjoy reading this discussion and are thinking about commenting, why not click here to register and start participating in under a minute?

#6 phpforfun

phpforfun

    Speaks fluent binary

  • Expert Member
  • PipPipPipPipPipPipPip
  • 1056 posts

Posted 02 October 2008 - 12:37 PM

Yes, it does. Using AmpHosted as the example. ;)


He need a server to test, I was on chat with him... I have a server.

I suppose he should have purchased a new server to test it on, lol
  • 0

#7 Guest_Jordan_*

Guest_Jordan_*
  • Guest

Posted 02 October 2008 - 12:51 PM

AmpHosted, eh? A marketing scam, I suppose?


Yeah, because I earn commission from Amphosted.com on all of his $1 plans (he gives me a penny for each sale)? I'm ashamed that you would think of me as a scammer.

Justin wanted this script done several months ago but I never did it. My Boss (if you would read the tutorial) wanted a similar script so I made it, Justin's and this tutorial. I thought a practical example would benefit coders.

does it looks like a marketing scam?

Jordan, 15 min, no ping email yet


I probably setup the cron job wrong. I'll take a look in a minute. Keep CC blocked please.

Edited by Jordan, 03 October 2008 - 03:56 AM.

  • 0

#8 phpforfun

phpforfun

    Speaks fluent binary

  • Expert Member
  • PipPipPipPipPipPipPip
  • 1056 posts

Posted 02 October 2008 - 01:37 PM

ok ok! now im getting flooded with emials

unblocking
  • 0

#9 morefood2001

morefood2001

    CC Leader

  • Expert Member
  • PipPipPipPipPipPipPip
  • 1011 posts

Posted 03 October 2008 - 04:34 AM

I don't think this is a scam because a script like this would be useful to me because I have my own servers (although I have paid monitoring services).

Great Job Jordan! Thanks.
  • 0
If you enjoy reading this discussion and are thinking about commenting, why not click here to register and start participating in under a minute?

#10 Xav

Xav

    CC Mentor

  • VIP Member
  • PipPipPipPipPipPipPipPip
  • 8356 posts

Posted 03 October 2008 - 09:24 AM

Yeah, because I earn commission from Amphosted.com on all of his $1 plans (he gives me a penny for each sale)? I'm ashamed that you would think of me as a scammer.

Yes lol, you really need to be more sneaky when performing your dark marketing deeds.
  • 0
If you enjoy reading this discussion and are thinking about commenting, why not click here to register and start participating in under a minute?

#11 Guest_Jordan_*

Guest_Jordan_*
  • Guest

Posted 03 October 2008 - 09:32 AM

I believe you are trying to scam me. I'm hovering over the -rep button!
  • 0

#12 Xav

Xav

    CC Mentor

  • VIP Member
  • PipPipPipPipPipPipPipPip
  • 8356 posts

Posted 03 October 2008 - 10:04 AM

LOL no need to be so hasty! What do you mean, I'm trying to scam me? It was just a joke, nothing personal...
  • 0
If you enjoy reading this discussion and are thinking about commenting, why not click here to register and start participating in under a minute?





Also tagged with one or more of these keywords: php

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download