Hi

I am not sure if this should go in the Newbies section or here shrug

I am fairly new to PHP, and have a problem with getting data from another website.

I wrote a script to send some POST data and get the return page for several sites, however when I tested it, I realized that it was slow as fsockopen() doesn't return until it has resolved the hostname and made a successful connection.

I then looked into it, and managed to find this page on how to make asynchronous connections. Great I though, get this to work, write in the changes on how to make it work with POST, and the sites I want etc.

I copied the script, and made the changes specified to convert it to PHP 4, unfortunately it doesn't work, and I cannot find out why. I also cannot find much alternative information on how to do this.

The script is here and the script output is here

My server is running PHP4.4.2

EDIT:
For a bit more obvious script:

 <?php
$hosts = array("yacoby.trap17.com", "yacoby.silgrad.com", "silgrad.com");
$timeout = 15;
$status = array();
$sockets = array();
/* Initiate connections to all the hosts simultaneously */
foreach ($hosts as $id => $host) {
    $s = non_blocking_connect("$host","80", $errno, $errstr, $timeout, 
        STREAM_CLIENT_ASYNC_CONNECT|STREAM_CLIENT_CONNECT);
    if ($s) {
        $sockets[$id] = $s;
        $status[$id] = "in progress";
    } else {
        $status[$id] = "failed, $errno $errstr";
    }
}
/* Now, wait for the results to come back in */
while (count($sockets)) {
    $read = $write = $sockets;
    /* This is the magic function - explained below */
    $n = socket_select($read, $write, $e = null, $timeout);
    if ($n > 0) {
        /* readable sockets either have data for us, or are failed
         * connection attempts */
        foreach ($read as $r) {
            $id = array_search($r, $sockets);
            $data = socket_read($r, 8192);
            if (strlen($data) == 0) {
                if ($status[$id] == "in progress") {
                    $status[$id] = "failed to connect";
                }
                socket_close($r);
                unset($sockets[$id]);
            } else {
                $status[$id] .= $data;
            }
        }
        /* writeable sockets can accept an HTTP request */
        foreach ($write as $w) {
            $id = array_search($w, $sockets);
            socket_write($w, "HEAD / HTTP/1.0\r\nHost: "
                . $hosts[$id] .  "\r\n\r\n");
            $status[$id] = "waiting for response";
        }
    } else {
        /* timed out waiting; assume that all hosts associated
         * with $sockets are faulty */
        foreach ($sockets as $id => $s) {
            $status[$id] = "timed out " . $status[$id];
        }
        break;
    }
}
foreach ($hosts as $id => $host) {
    echo "Host: $host\n";
    echo "Status: " . $status[$id] . "\n\n";
}

// This value is correct for Linux, other systems have other values
define('EINPROGRESS', 115);
function non_blocking_connect($host, $port, &$errno, &$errstr, $timeout) {
    $ip = gethostbyname($host);
    $s = socket_create(AF_INET, SOCK_STREAM, 0);
    if (socket_set_nonblock($s)) {
        $r = @socket_connect($s, $ip, $port);
        if ($r || socket_last_error() == EINPROGRESS) {
            $errno = EINPROGRESS;
            return $s;
        }
    }
    $errno = socket_last_error($s);
    $errstr = socket_strerror($errno);
    socket_close($s);
    return false;
}
?> 

Does anyone know what is wrong with the script?

Many thanks,
~Yacoby

    Add

    error_reporting(E_ALL);

    to the top of the script and remove the @ from line 20 so you have

    $r = socket_connect($s, $ip, $port);

    and report back on the errors.

    I presume the socket connect works under normal conditions? If not, and you're just trying to ping then this thread may be of interest: http://www.phpbuilder.com/board/showthread.php?t=10331670

      sarahk wrote:

      Add

      error_reporting(E_ALL);

      to the top of the script and remove the @ from line 20 so you have

      $r = socket_connect($s, $ip, $port);

      and report back on the errors.

      The page with the errors is here

      The only warnings seem to be:

      Warning: socket_connect() unable to connect [115]: Operation now in progress in /home/yacoby/public_html/soc/error.php on line 75

      Which was intentionaly ignored shrug

      I presume the socket connect works under normal conditions?

      I can use stuff like fsockopen() no problem if that is what you mean.

      If not, and you're just trying to ping then this thread may be of interest: http://www.phpbuilder.com/board/showthread.php?t=10331670

      No, although the specifed example is in effect just checking if the sever is up, I need to pull data from the specifed page. To do so I need to get this script working, so I can convert it to do what I want.

        I think your problem is that you don't have root access to the socket - given my recent experience mucking about with this - but I'm no socket expert.

        If you need to get the page and manipulate data I'd use curl. Works well, not socket issues.

          I looked at your Web hosts very revealing header for that server (the one with the errors)

          Server: Apache/1.3.36 (Unix) mod_fastcgi/2.4.2 mod_auth_passthrough/1.8 mod_log_bytes/1.2 mod_bwlimited/1.4 PHP/4.4.2 FrontPage/5.0.2.2635.SR1.2 mod_ssl/2.8.27 OpenSSL/0.9.7a

          It appears you are trying to use PHP 5 code from a server that only supports up to 4.4.2. I suggest trying the PHP 4 alternative in the article you posted.

            Well, it looks liek you have both examples in the same page perhaps as I see a error about EINPROGRESS not being defined. Please note that if you have a line:

            define('EINPROGRESS', 115); 

            that defines this constant you won't get that error. However if you are trying to use both examples at the same time...well...how 'bout you post your code.

              I think your problem is that you don't have root access to the socket - given my recent experience mucking about with this - but I'm no socket expert.

              🙁

              If you need to get the page and manipulate data I'd use curl. Works well, not socket issues.

              I will look into curl

              It appears you are trying to use PHP 5 code from a server that only supports up to 4.4.2. I suggest trying the PHP 4 alternative in the article you posted.

              I though I had done everything needed to convert it to PHP4 code shrug

              bretticus wrote:

              Well, it looks liek you have both examples in the same page perhaps as I see a error about EINPROGRESS not being defined. Please note that if you have a line:

              define('EINPROGRESS', 115); 

              that defines this constant you won't get that error.

              The error about EINPROGRESS was I think because it was defined outside the function, but if I move it inside the function, I get an error about how it is already defined.

              However if you are trying to use both examples at the same time...well...how 'bout you post your code.

              See the first post

                However if you are trying to use both examples at the same time...well...how 'bout you post your code.

                My bad. Somehow I missed that source code ;-)

                I though I had done everything needed to convert it to PHP4 code shrug

                Pardon me, but I may have misunderstood the article. For example, STREAM_CLIENT_ASYNC_CONNECT is a predefined constant available in PHP5 only it would appear. I suggest you find out what values those constants have and substitute your own with define()

                That is strange that EINPROGRESS isn't available inside the function. In PHP 4, which I'm still coding in, constants are available globally.

                Finally, as you have previously stated, since you are using

                  error_reporting(E_ALL); 

                most of those errors are in fact not errors just warnings and notices (however very useful as they let you know the constants are undefined.) To see what constants are defined natively try

                print_r(get_defined_constants());

                Unfortunately, I have no idea why you are getting the socket errors. However, I have a sneaking suspicion it may have to do with host lookup or service rejection by the following:

                Host: yacoby.trap17.com Status: failed

                Of course, I'm guessing. Like sarahk, I have limited experience with sockets...especially trying to make asynchronous socket calls. ANYONE ELSE OUT THERE HAVE MORE EXPERIENCE WITH SOCKET FUNCTIONS?

                  5 days later
                  bretticus wrote:

                  That is strange that EINPROGRESS isn't available inside the function. In PHP 4, which I'm still coding in, constants are available globally.

                  Finally, as you have previously stated, since you are using

                    error_reporting(E_ALL); 

                  most of those errors are in fact not errors just warnings and notices (however very useful as they let you know the constants are undefined.) To see what constants are defined natively try

                  print_r(get_defined_constants());

                  using get_defined_constants() I managed to find SOCKET_EINPROGRESS defined as 115. I then replaced references to EINPROGRESS with SOCKET_EINPROGRESS, and I seem to have got a valid output (link ). Why this happened, I don't have a clue. shrugs

                  Anyway, thanks for the help, I just hope it is working properly and isn't just my imagination 🙂

                    Write a Reply...