fsockopen

(PHP 4, PHP 5, PHP 7, PHP 8)

fsockopenOuvre un socket de connexion Internet ou Unix

Description

fsockopen(
    string $hostname,
    int $port = -1,
    int &$error_code = null,
    string &$error_message = null,
    ?float $timeout = null
): resource|false

Initialise une connexion par socket à la ressource spécifiée par hostname.

PHP supporte les cibles dans les domaines Internet et Unix comme décrit dans Liste des modes de transport de sockets disponibles. Une liste des types de transports peut également être trouvée en utilisant la fonction stream_get_transports().

Le socket sera ouvert par défaut en mode bloquant. Vous pouvez changer de mode en utilisant : stream_set_blocking().

La fonction stream_socket_client() est similaire mais fournit plus d'options, incluant la connexion non-bloquante et la possibilité de fournir un contexte de flux.

Liste de paramètres

hostname

Si le support OpenSSL est installé, vous pouvez préfixer hostname avec ssl:// ou tls:// pour utiliser une connexion cliente SSL ou TLS sur TCP/IP pour vous connectez à l'hôte distant.

port

Le numéro du port. Ce paramètre peut être omis et ignoré en utilisant la valeur -1 pour les transports qui n'utilisent pas les ports, comme unix://.

error_code

Si fourni, contient le numéro de l'erreur système qui survient lors de l'appel système à connect().

Si la valeur retournée par error_code est 0 et que la fonction retourne false, ce peut être une indication laissant penser que l'erreur est survenue avant l'appel à connect(). La plupart du temps, cela est du à un problème d'initialisation du socket.

error_message

Le message d'erreur, sous la forme d'une chaîne de caractères.

timeout

Le délai d'attente maximal, en secondes. Si null le paramètre php.ini default_socket_timeout est utilisé.

Note:

Si vous avez besoin de définir un délai limite pour lire/écrire des données à travers ce socket, utilisez la fonction stream_set_timeout(), car le paramètre timeout de la fonction fsockopen() est uniquement appliqué lors de la connexion du socket.

Valeurs de retour

fsockopen() retourne un pointeur de fichier qui peut être utilisé avec d'autres fonctions fichiers, telles fgets(), fgetss(), fputs(), fclose() et feof(). Si l'appel échoue, la fonction retourne false.

Erreurs / Exceptions

Lance une alerte de type E_WARNING si le paramètre hostname n'est pas un domaine valide.

Historique

Version Description
8.0.0 timeout est désormais nullable.

Exemples

Exemple #1 Exemple avec fsockopen()

<?php
$fp
= fsockopen("www.example.com", 80, $errno, $errstr, 30);
if (!
$fp) {
echo
"$errstr ($errno)<br />\n";
} else {
$out = "GET / HTTP/1.1\r\n";
$out .= "Host: www.example.com\r\n";
$out .= "Connection: Close\r\n\r\n";

fwrite($fp, $out);
while (!
feof($fp)) {
echo
fgets($fp, 128);
}
fclose($fp);
}
?>

Exemple #2 Utilisation d'une connexion UDP

L'exemple ci-dessous décrit comment lire la date et l'heure grâce à un service UDP "daytime" (port 13), sur votre propre machine.

<?php
$fp
= fsockopen("udp://127.0.0.1", 13, $errno, $errstr);
if (!
$fp) {
echo
"ERREUR : $errno - $errstr<br />\n";
} else {
fwrite($fp, "\n");
echo
fread($fp, 26);
fclose($fp);
}
?>

Notes

Note:

Suivant les environnements, le type 'domaine Unix' ou l'option timeout ne sont pas toujours disponibles.

Avertissement

Les sockets UDP semblent quelques fois avoir été ouverts sans erreur, même si l'hôte distant n'est pas accessible. L'erreur apparaît alors uniquement lorsque vous tentez de lire/écrire sur le socket. La raison de cela est que UDP est un protocole "connectionless", ce qui signifie que le système ne tentera pas d'établir un lien pour le socket tant qu'il ne doit pas recevoir/envoyer de données.

Note: Lors de la spécification d'adresses IPv6 au format numérique (e.g. fe80::1) vous devez placer l'adresse IP entre crochets. Par exemple : tcp://[fe80::1]:80.

Voir aussi

add a note add a note

User Contributed Notes 42 notes

up
21
joe at edwardsconsultants dot com
21 years ago
just a quick note for users attempting https and thinking they must resort to curl or alternate methods -
you can use fsockopen, just read the docs closely.  basically they are saying to use 'ssl://' for a HTTPS (SSL) web request.

so this would work for authorize.net, and others; even for that paypal IPN - however I think it would be best to leave the site and deal with paypal's form:

<?php
$host
= "something.example.com";
$port = 443;
$path = "/the/url/path/file.php"; //or .dll, etc. for authnet, etc.

//you will need to setup an array of fields to post with
//then create the post string
$formdata = array ( "x_field" => "somevalue");
//build the post string
 
foreach($formdata AS $key => $val){
   
$poststring .= urlencode($key) . "=" . urlencode($val) . "&";
  }
// strip off trailing ampersand
$poststring = substr($poststring, 0, -1);

$fp = fsockopen("ssl://".$host, $port, $errno, $errstr, $timeout = 30);

if(!
$fp){
//error tell us
echo "$errstr ($errno)\n";
  
}else{

 
//send the server request
 
fputs($fp, "POST $path HTTP/1.1\r\n");
 
fputs($fp, "Host: $host\r\n");
 
fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n");
 
fputs($fp, "Content-length: ".strlen($poststring)."\r\n");
 
fputs($fp, "Connection: close\r\n\r\n");
 
fputs($fp, $poststring . "\r\n\r\n");

 
//loop through the response from the server
 
while(!feof($fp)) {
    echo
fgets($fp, 4096);
  }
 
//close fp - we are done with it
 
fclose($fp);
}
?>
up
16
sir_reality2001 at yahoo dot com
20 years ago
<?php
// This script is an example of posting multiple files using
// fsockopen.
// The tricky part is making sure the HTTP headers and file boundaries are acceptable to the target webserver.
// This script is for example purposes only and could/should be improved upon.

$host='targethost';
$port=80;
$path='/test/socket/file_upload/receive_files.php';

// the file you want to upload
$file_array[0] = "dingoboy.gif"; // the file
$file_array[1] = "dingoboy2.gif"; // the file
$file_array[2] = "dingoboy3.gif"; // the file
$content_type = "image/gif"; // the file mime type
//$content_type = "text/plain";
//echo "file_array[0]:$file_array[0]<br><br>";

srand((double)microtime()*1000000);
$boundary = "---------------------------".substr(md5(rand(0,32000)),0,10);

$data = "--$boundary";

for(
$i=0;$i<count($file_array);$i++){
  
$content_file = join("", file($file_array[$i]));

  
$data.="
Content-Disposition: form-data; name=\"file"
.($i+1)."\"; filename=\"$file_array[$i]\"
Content-Type:
$content_type

$content_file
--
$boundary";

}

$data.="--\r\n\r\n";

$msg =
"POST $path HTTP/1.0
Content-Type: multipart/form-data; boundary=
$boundary
Content-Length: "
.strlen($data)."\r\n\r\n";

$result="";

// open the connection
$f = fsockopen($host, $port);

fputs($f,$msg.$data);

// get the response
while (!feof($f)) $result .= fread($f,32000);

fclose($f);

?>
up
11
ryan1_00 at hotmail dot com
17 years ago
This script checks specific ports so you need to have the correct port open on the server for this to work.

E.g if i have a windows domain controller and it is servering LDAP then the following would be used to check it is online:
<?php
chkServer
("MyDC", "389");
?>

for a webserver:
<?php
chkServer
("MyWebSvr", "80");
?>

etc etc
--------------------------------------------------------

<?php
// check if a server is up by connecting to a port
function chkServer($host, $port)
{  
   
$hostip = @gethostbyname($host); // resloves IP from Hostname returns hostname on failure
   
   
if ($hostip == $host) // if the IP is not resloved
   
{
        echo
"Server is down or does not exist";
    }
    else
    {
        if (!
$x = @fsockopen($hostip, $port, $errno, $errstr, 5)) // attempt to connect
       
{
            echo
"Server is down";
        }
        else
        {
            echo
"Server is up";
            if (
$x)
            {
                @
fclose($x); //close connection
           
}
        } 
    }
}
?>
up
4
saul dot dobney at dobney dot com
19 years ago
If you are using fsockopen to access webpage, but come across a redirect (Location: ) in the header and want to find and follow the redirect as in this snippet:

<?php
while (!feof($fp)) {
  
$line=fgets($fp, 1024);               
   if (
stristr($line,"location:")!="") {
   
$redirect=preg_replace("/location:/i","",$line);
   }
}
?>

Then don't forget to <?php $redirect = trim($redirect); ?> before trying to follow this new link as $redirect actually has a \r\n on the end of it and won't give you a valid path in the next iteration otherwise. A six hour bug.

Saul Dobney
up
4
edwin at bitstorm dot org
19 years ago
Here's a function to just fetch the contents behind an URL.

<?php
function fetchURL( $url ) {
   
$url_parsed = parse_url($url);
   
$host = $url_parsed["host"];
   
$port = $url_parsed["port"];
    if (
$port==0)
       
$port = 80;
   
$path = $url_parsed["path"];
    if (
$url_parsed["query"] != "")
       
$path .= "?".$url_parsed["query"];

   
$out = "GET $path HTTP/1.0\r\nHost: $host\r\n\r\n";

   
$fp = fsockopen($host, $port, $errno, $errstr, 30);

   
fwrite($fp, $out);
   
$body = false;
    while (!
feof($fp)) {
       
$s = fgets($fp, 1024);
        if (
$body )
           
$in .= $s;
        if (
$s == "\r\n" )
           
$body = true;
    }
   
   
fclose($fp);
   
    return
$in;
}
?>
up
4
michiel at parse dot nl
20 years ago
The following snippet allows you to retrieve the title of a page.

Great for rewriting auto-url detectors to display the actual title rather then http://...

<?php
echo get_url_title("http://www.php.net/cal.php?id=409");

function
get_url_title($url, $timeout = 2)
{
   
$url = parse_url($url);

    if(!
in_array($url['scheme'],array('','http')))
        return;

   
$fp = fsockopen ($url['host'], ($url['port'] > 0 ? $url['port'] : 80), $errno, $errstr, $timeout);
    if (!
$fp)
    {
        return;
       
// echo "$errstr ($errno)<br>\n";
   
}
    else
    {
       
fputs ($fp, "GET /".$url['path'].($url['query'] ? '?'.$url['query'] : '')." HTTP/1.0\r\nHost: ".$url['host']."\r\n\r\n");
       
$d = '';
        while (!
feof($fp))
        {
           
$d .= fgets ($fp,2048);

            if(
preg_match('~(</head>|<body>|(<title>\s*(.*?)\s*</title>))~i', $d, $m))
                break;
        }
       
fclose ($fp);

        return
$m[3];
    }
}
?>
up
4
verran at descent-rangers dot com
22 years ago
I was tearing my hair out for a week trying to figure out how to do this.

If you use fsockopen with a service that doesn't have an EOF, or you try to read beyond EOF or line break, PHP can hang completely.

In my case, I was trying to write a class that talks to Kali servers (www.kali.net) to get a list of people on the chat server. To keep PHP from hanging due to the above, I discovered this:

<?php
   
class kali_utils {
        function
games_list($kali_server_ip, $kali_server_port) {
           
$result = array();
           
$fp = fsockopen($kali_server_ip, $kali_server_port, $errno, $error, 30);
            if (!
$fp) {
               
$result["errno"] = $errno;
               
$result["error"] = $error;
            }
            else {
               
fputs($fp, "KALIQ");
               
$header = fread($fp, 5);
               
$bytes_left = socket_get_status($fp);
                if (
$bytes_left > 0) {
                   
$result["results"] = fread($fp, $bytes_left["unread_bytes"]);
                }
                else {
                   
$result["results"] = "";
                }
               
fclose($fp);
            }
            return
$result;
        }
    }
?>

When I send the request packet, I get a response packet of length 5. Then I call socket_get_status() and use the unread_bytes key from it to know how far to fread from the socket. Works very good.

I've only used this on PHP 4.2.1 so far.
up
5
ghzero at ghzero dot de
15 years ago
note:
the default protocol - if not given - seems to be tcp://
up
4
richard dot lajaunie at cote-azur dot cci dot fr
19 years ago
<?php
/************************************************************
* Author: Richard Lajaunie
* Mail : richard.lajaunie@cote-azur.cci.fr
*
* subject : this script retreive all mac-addresses on all ports
* of a Cisco 3548 Switch by a telnet connection
*
* base on the script by: xbensemhoun at t-systems dot fr
**************************************************************/

if ( array_key_exists(1, $argv) ){
  
$cfgServer = $argv[1];
}else{
   echo
"ex: 'php test.php 10.0.0.0' \n";
   exit;
}

$cfgPort    = 23;                //port, 22 if SSH
$cfgTimeOut = 10;

$usenet = fsockopen($cfgServer, $cfgPort, $errno, $errstr), $cfgTimeOut);

if(!
$usenet){
       echo
"Connexion failed\n";
       exit();
}else{
       echo
"Connected\n";
      
fputs ($usenet, "password\r\n");
      
fputs ($usenet, "en\r\n");
      
fputs ($usenet, "password\r\n");
      
fputs ($usenet, "sh mac-address-table\r\n");
      
fputs ($usenet, " "); // this space bar is this for long output
     
       // this skip non essential text
      
$j = 0;
       while (
$j<16){
      
fgets($usenet, 128);
      
$j++;
       }
  
stream_set_timeout($usenet, 2); // set the timeout for the fgets
  
$j = 0;
       while (!
feof($usenet)){
      
$ret = fgets($usenet, 128);
      
$ret = str_replace("\r", '', $ret);
      
$ret = str_replace("\n", "", $ret);
       if  (
ereg("FastEthernet", $ret)){
           echo
"$ret \n";
       }
       if (
ereg('--More--', $ret) ){
          
fputs ($usenet, " "); // for following page
      
}
      
$info = stream_get_meta_data($usenet);
       if (
$info['timed_out']) {
          
$j++;
       }
       if (
$j >2){
          
fputs ($usenet, "lo");
           break;
       }
   }
}
echo
"End.\r\n";
?>
up
6
robin at pozytron dot com
19 years ago
I have found, when using fsockopen() and the POST method, that using HTTP/1.1 is VERY significantly slower than HTTP/1.0 (at least for the server I'm querying, an Orion-based server). Also, using cURL tended to be faster than fsockopen(), though only slightly. For example, here was a recent set of data (for the same exact request in each case):

cURL: 4.2sec
fsockopen() HTTP/1.0: 4.9sec
fsockopen() HTTP/1.1: 19.9sec (!)

I'm not sure why this was occurring. Perhaps it has something to do with the Orion server, which I have little experience with. However, it was not a fluke, and I double-checked the code to make sure there were no errors.

EDITORS NOTE: HTTP/1.1 uses persistent connection causing this delay. Use "Connection: close" header to disable it.
up
6
Alexander Wegener
17 years ago
To check if a Url is Online (with http and https)
Using @fgets to hide Warning when using SSL
(Bug: "Warning: function.fgets SSL: fatal protocol error", http://bugs.php.net/bug.php?id=23220)

<?php

   
function isOnline($url) {
        if (!
$url_info = parse_url($url)) {
            return
false;   
        }
       
        switch (
$url_info['scheme']) {
            case
'https':
               
$scheme = 'ssl://';
               
$port = 443;
                break;
            case
'http':
            default:
               
$scheme = '';
               
$port = 80;   
        }
       
       
$data = "";
       
$fid = @fsockopen($scheme . $url_info['host'], $port, $errno, $errstr, 30);
        if (
$fid) {
           
fputs($fid, 'HEAD ' . (isset($url_info['path'])? $url_info['path']: '/') . (isset($url_info['query'])? '?' . $url_info['query']: '') . " HTTP/1.0\r\n" .
                       
"Connection: close\r\n" .
                       
'Host: ' . $url_info['host'] . "\r\n\r\n");   
            while (!
feof($fid)) {
               
$data .= @fgets($fid, 128);
            }
           
fclose($fid);
            return !empty(
$data);
        } else {
            return
false;
        }
    }

?>
up
6
nytro_rst at yahoo dot com
14 years ago
A simple proxy list checker. You can check a list ip:port if that port is opened on that IP.

<?php

$fisier
= file_get_contents('proxy_list.txt'); // Read the file with the proxy list
$linii = explode("\n", $fisier); // Get each proxy
$fisier = fopen("bune.txt", "a"); // Here we will write the good ones

for($i = 0; $i < count($linii) - 1; $i++) test($linii[$i]); // Test each proxy

function test($proxy)
{
  global
$fisier;
 
$splited = explode(':',$proxy); // Separate IP and port
 
if($con = @fsockopen($splited[0], $splited[1], $eroare, $eroare_str, 3))
  {
   
fwrite($fisier, $proxy . "\n"); // Check if we can connect to that IP and port
   
print $proxy . '<br>'; // Show the proxy
   
fclose($con); // Close the socket handle
 
}
}

fclose($fisier); // Close the file

?>
up
4
Kiki_EF
19 years ago
Additional ICQ status request over proxy
<?php
function icq_uin($uin)
{
    if (!
is_numeric($uin))
        return
false;
   
$proxy_name = 'proxy.mydomain.de';
   
$proxy_port = 8080;
   
$proxy_user = "";
   
$proxy_pass = "";
   
$proxy_cont = '';
   
$request_url = "http://status.icq.com/online.gif?icq=$uin";

   
$proxy_fp = fsockopen($proxy_name, $proxy_port);
    if (!
$proxy_fp)
        return
false;
   
fputs($proxy_fp, "GET $request_url HTTP/1.0\r\nHost: $proxy_name\r\n");
   
fputs($proxy_fp, "Proxy-Authorization: Basic ". base64_encode ("$proxy_user:$proxy_pass")."\r\n\r\n");
    while(!
feof($proxy_fp)){
       
$proxy_cont .= fread($proxy_fp,4096);
    }
   
fclose($proxy_fp);
   
$proxy_cont = substr($proxy_cont, strpos($proxy_cont,"\r\n\r\n")+4);
    if (
strstr($proxy_cont, 'online1'))
        return
'online';
    if (
strstr($proxy_cont, 'online0'))
        return
'offline';
    if (
strstr($proxy_cont, 'online2'))
        return
'disabled';
}
echo
"User is ".icq_uin(123456789012345);
?>

Thanx

[EDIT BY danbrown AT php DOT net: Based on code provided in a note by (rafaelbc AT matrix DOT com DOT br) on 23-MAY-09, which has since been removed.]
up
1
huli0401 at gmail dot com
16 years ago
<?php
// Check for new version
   
$current_version = explode('.', '1.0.00');
   
$minor_revision = (int) $current_version[2];

   
$errno = 0;
   
$errstr = $version_info = '';

    if (
$fsock = fsockopen("www.exanmple.eu", 80, $errno, $errstr, 30))
    {
        @
fputs($fsock, "GET /ver.txt HTTP/1.1\r\n");
        @
fputs($fsock, "HOST: www.example.eu\r\n");
        @
fputs($fsock, "Connection: close\r\n\r\n");

       
$get_info = false;
        while (!@
feof($fsock))
        {
            if (
$get_info)
            {
               
$version_info .= @fread($fsock, 1024);
            }
            else
            {
                if (@
fgets($fsock, 1024) == "\r\n")
                {
                   
$get_info = true;
                }
            }
        }
        @
fclose($fsock);

       
$version_info = explode("\n", $version_info);
       
$latest_head_revision = (int) $version_info[0];
       
$latest_minor_revision = (int) $version_info[2];
       
$latest_version = (int) $version_info[0] . '.' . (int) $version_info[1] . '.' . (int) $version_info[2];

        if (
$latest_head_revision == 2 && $minor_revision == $latest_minor_revision)
        {
           
$version_info = '<p style="color:green">OK</p>';
        }
        else
        {
           
$version_info = '<p style="color:red">neaktualne';
           
$version_info .= '<br />'Latest_version_info' . $latest_version) . ' ' . sprintf(Current_version_info'. '1.0.00') . '</p>';
        }
    }
    else
    {
        if (
$errstr)
        {
           
$version_info = '<p style="color:red">' . sprintf(Connect_socket_error) . '</p>';
        }
        else
        {
           
$version_info = '<p>'Socket_functions_disabled'</p>';
        }
    }
   
   
$version_info .= '<p>'Mailing_list_subscribe_reminder'</p>';

echo
$version_info;
?>
up
1
bradland at umich dot edu
17 years ago
I was having trouble doing an https in fopen and with fsockopen where the address had ssl://.  I was getting error code 114 in the log.  After much research i found that there was some ssl conflict trouble with MySQL 5.0.20-5.0.33.  It had some functions that were interfering with openssl that showed up in the php install.

http://bugs.mysql.com/bug.php?id=21930
http://bugs.mysql.com/bug.php?id=19289
up
1
v13+phpnet at it dot teithe dot gr
17 years ago
The following function performs pop3 authentication. Returns NULL on error, or true/false to indicate username/password matching:

$address is the hostname of the server and $ssl is a boolean that indicates whether an SSL connection is requested.

<?php
function pop3authCheck($username, $password, $address, $ssl)
{
    if (
$ssl)
       
$uri="ssl://$address:995";
    else
       
$uri="tcp://$address:110";

   
$fp=fsockopen($uri);

    if (!
$fp)
        return(
NULL);

   
$st=fgets($fp, 512);
    if (
substr($st, 0, 3)!="+OK")
    {
       
fclose($fp);
        return(
NULL);
    }

   
$st="USER $username\n";
    if (
fwrite($fp, $st)!=strlen($st))
    {
       
fclose($fp);
        return(
NULL);
    }

   
$st=fgets($fp, 512);
    if (
substr($st, 0, 3)!="+OK")
    {
       
fclose($fp);
        return(
NULL);
    }

   
$st="PASS $password\n";
    if (
fwrite($fp, $st)!=strlen($st))
    {
       
fclose($fp);
        return(
NULL);
    }

   
$st=fgets($fp, 512);
   
fclose($fp);
    if (
substr($st, 0, 3)=="+OK")
        return(
true);
    else if (
substr($st, 0, 4)=="+ERR")
        return(
false);
    else
        return(
NULL);
}
?>
up
1
Duukkis
18 years ago
Lots of tries and lots of reading http-headers...

If you want to post $_POST vars and (in this case) one file named userfile to $remote_server and $remote_url.

<?php
       
// get the necessary data
       
$file_name = $_FILES['userfile']['name'];     // the file
       
$tmp_name = $_FILES['userfile']['tmp_name'];     // the file
       
$content_type = $_FILES['userfile']['type'];     // the file mime type
       
       
srand((double)microtime()*1000000);
       
$boundary = "---------------------".substr(md5(rand(0,32000)),0,10);
       
       
// Build the header
       
$header = "POST $remote_url HTTP/1.0\r\n";
       
$header .= "Host: $remote_server\r\n";
       
$header .= "Content-type: multipart/form-data, boundary=$boundary\r\n";
       
// attach post vars
       
foreach($_POST AS $index => $value){
           
$data .="--$boundary\r\n";
           
$data .= "Content-Disposition: form-data; name=\"".$index."\"\r\n";
           
$data .= "\r\n".$value."\r\n";
           
$data .="--$boundary\r\n";
        }
       
// and attach the file
       
$data .= "--$boundary\r\n";
       
$content_file = join("", file($tmp_name));
       
$data .="Content-Disposition: form-data; name=\"userfile\"; filename=\"$file_name\"\r\n";
       
$data .= "Content-Type: $content_type\r\n\r\n";
       
$data .= "".$content_file."\r\n";
       
$data .="--$boundary--\r\n";
       
$header .= "Content-length: " . strlen($data) . "\r\n\r\n";
                
// Open the connection
       
$fp = fsockopen($remote_server, 80);
       
// then just
       
fputs($fp, $header.$data);
       
fclose($fp);
?>
up
4
brage (a t) jeffnappi (d.o.t) commie
21 years ago
thought you guys may appreciate this function, allows you to pass an array of urls to download and does so simultaneously using non-blocking sockets, then returns the data in an array.

<?php
// function connects to an array of URLS at the same time
// and returns an array of results.

function multiHTTP ($urlArr) {
$sockets = Array(); // socket array!
$urlInfo = Array(); // info arr
$retDone = Array();
$retData = Array();
$errno   = Array();
$errstr  = Array();
for (
$x=0;$x<count($urlArr);$x++) {
 
$urlInfo[$x] = parse_url($urlArr[$x]);
 
$urlInfo[$x][port] = ($urlInfo[$x][port]) ? $urlInfo[$x][port] : 80;
 
$urlInfo[$x][path] = ($urlInfo[$x][path]) ? $urlInfo[$x][path] : "/";
 
$sockets[$x] = fsockopen($urlInfo[$x][host], $urlInfo[$x][port],
                          
$errno[$x], $errstr[$x], 30);
 
socket_set_blocking($sockets[$x],FALSE);
 
$query = ($urlInfo[$x][query]) ? "?" . $urlInfo[$x][query] : "";
 
fputs($sockets[$x],"GET " . $urlInfo[$x][path] . "$query HTTP/1.0\r\nHost: " .
       
$urlInfo[$x][host] . "\r\n\r\n");
}
// ok read the data from each one
$done = false;
while (!
$done) {
  for (
$x=0; $x < count($urlArr);$x++) {
   if (!
feof($sockets[$x])) {
    if (
$retData[$x]) {
    
$retData[$x] .= fgets($sockets[$x],128);
    } else {
    
$retData[$x] = fgets($sockets[$x],128);
    }
   } else {
   
$retDone[$x] = 1;
   }
  }
 
$done = (array_sum($retDone) == count($urlArr));
}
return
$retData;
}
?>
up
1
blazely at removetoemail netspace net au
21 years ago
Here's a quick function to establish a connection to a web server that will time out if the connection is lost after a user definable amount of time or if the server can't be reached.

Also supports Basic authentication if a username/password is specified. Any improvements or criticisms, please email me! :-)

Returns either a resource ID, an error code or 0 if the server can't be reached at all. Returns -1 in the event that something really wierd happens like a non-standard http response or something. Hope it helps someone.

Cheers,

Ben Blazely

<?php
function connectToURL($addr, $port, $path, $user="", $pass="", $timeout="30")
{
$urlHandle = fsockopen($addr, $port, $errno, $errstr, $timeout);
if (
$urlHandle)
{
 
socket_set_timeout($urlHandle, $timeout);
  if (
$path)
  {
  
$urlString = "GET $path HTTP/1.0\r\nHost: $addr\r\nConnection: Keep-Alive\r\nUser-Agent: MyURLGrabber\r\n";
   if (
$user)
   
$urlString .= "Authorization: Basic ".base64_encode("$user:$pass")."\r\n";
   
$urlString .= "\r\n";

   
fputs($urlHandle, $urlString);

   
$response = fgets($urlHandle);

    if (
substr_count($response, "200 OK") > 0)      // Check the status of the link
   
{
    
$endHeader = false;                     // Strip initial header information
    
while ( !$endHeader)
     {
      if (
fgets($urlHandle) == "\r\n")
      
$endHeader = true;
     }

     return
$urlHandle;                      // All OK, return the file handle
   
}
    else if (
strlen($response) < 15)                // Cope with wierd non standard responses
   
{
    
fclose($urlHandle);
     return -
1;
    }
    else                                           
// Cope with a standard error response
   
{
    
fclose($urlHandle);
     return
substr($response,9,3);
    }
   }

   return
$urlHandle;
  }
  else
  {
   return
0;
  }
}
}
?>
up
1
dan at lovepond dot com
21 years ago
Here is some code to help out abit more with the EOF problem.
I had a problem where I needed to strip out so many lines of server input to get back right data i wanted.

<?php
$port
=4000;
$host="localhost";
$message="test";
$status=senddata($host,$port,$message);
print
"$status";

function
senddata($host,$port,$message) {

#takes in account servers that do not return EOF character
#send data to server and get back input

#function globals
$linenumber="2"; #amount of lines to get rid of before we give input
$lineamount="1"; #amount of lines to read after we give input

$fp = fsockopen("$host", $port, $errno, $errstr, 30);
if (!
$fp) {
   echo
"$errstr ($errno)";
}
else {
   for (
$i = 1; $i < $linenumber+1; $i++) {
     
fread ($fp,1);
     
$bytes_left = socket_get_status($fp);
      if (
$bytes_left > 0) { fread($fp, $bytes_left[unread_bytes]); }
   }
  
fputs($fp, "$message\r\n");
   for (
$i = 1; $i < $lineamount+1; $i++) {
     
$status.=fread($fp,1);
     
$bytes_left = socket_get_status($fp);
      if (
$bytes_left > 0) { $status.=fread($fp, $bytes_left[unread_bytes]); }
   }
  
fclose ($fp);
}

return
$status;
}

?>
up
1
oliver dot christen at camptocamp dot com
15 years ago
When downloading large files, it is not really efficient to put the whole server answer in memory before parsing the data to remove the header parts. Here is a simple way to do it while writing the data as it arrive:

<?php

// $socket is a valid fsockopen handle

$out = '';
$headerendfound = false;
$fp = fopen($fileTarget, 'w');
$buffer = '';
while (!
feof($socket)) {
   
$out = fgets ($socket,16384);
    if (
$headerendfound) {
       
fwrite($fp, $out);
        print
'.';
    }
    if (!
$headerendfound) {
       
$buffer .= $out;
        print
"searching for header\n";
       
$headerend = strpos($buffer, "\r\n\r\n");
        if (
$headerend !== false) {
           
$headerendfound = true;
           
fwrite($fp, substr($buffer, $headerend+4));
           
$buffer = '';
        }
    }
}
fclose($fp);
fclose($socket);

?>
up
1
konrad dot meyer at gmail dot com
19 years ago
The documentation example is of a GET request. I have found POST documentation to be lacking, and here's a function to easily simulate submitting form data:

<?php
# $host includes host and path and filename
    # ex: "myserver.com/this/is/path/to/file.php"
# $query is the POST query data
    # ex: "a=thisstring&number=46&string=thatstring
# $others is any extra headers you want to send
    # ex: "Accept-Encoding: compress, gzip\r\n"
function post($host,$query,$others=''){
   
$path=explode('/',$host);
   
$host=$path[0];
    unset(
$path[0]);
   
$path='/'.(implode('/',$path));
   
$post="POST $path HTTP/1.1\r\nHost: $host\r\nContent-type: application/x-www-form-urlencoded\r\n${others}User-Agent: Mozilla 4.0\r\nContent-length: ".strlen($query)."\r\nConnection: close\r\n\r\n$query";
   
$h=fsockopen($host,80);
   
fwrite($h,$post);
    for(
$a=0,$r='';!$a;){
       
$b=fread($h,8192);
       
$r.=$b;
       
$a=(($b=='')?1:0);
    }
   
fclose($h);
    return
$r;
}
?>
up
3
asalamanca at redcetus dot com
20 years ago
This is a very fast program for test a form or link (many times).
<?php
$repeat 
= 100// How many times repeat the test

$timeout = 100// Max time for stablish the conection
$size    = 16;   // Bytes will be read (and display). 0 for read all

$server  = '127.0.0.1';            // IP address
$host    = 'www.example.net';             // Domain name
$target  = '/poll/answer.asp';        // Specific program
$referer = 'http://www.example.com/';    // Referer
$port    = 80;

// Setup an array of fields to get with then create the get string
$gets = array ( 'get_field_1' => 'somevalue',
               
'get_field_2' => 'somevalue' );

// Setup an array of fields to post with then create the post string
$posts = array ( 'post_field_1' => 'somevalue',
                
'post_field_2' => 'somevalue' );

// That's all. Now the program proccess $repeat times

$method = "GET";
if (
is_array( $gets ) ) {
   
$getValues = '?';
    foreach(
$gets AS $name => $value ){
       
$getValues .= urlencode( $name ) . "=" . urlencode( $value ) . '&';
    }
   
$getValues = substr( $getValues, 0, -1 );
} else {
   
$getValues = '';
}

if (
is_array( $posts ) ) {
    foreach(
$posts AS $name => $value ){
       
$postValues .= urlencode( $name ) . "=" . urlencode( $value ) . '&';
    }
   
$postValues = substr( $postValues, 0, -1 );
   
$method = "POST";
} else {
   
$postValues = '';
}

$request  = "$method $target$getValues HTTP/1.1\r\n";
$request .= "Host: $host\r\n";
$request .= 'User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.2.1) ';
$request .= "Gecko/20021204\r\n";
$request .= 'Accept: text/xml,application/xml,application/xhtml+xml,';
$request .= 'text/html;q=0.9,text/plain;q=0.8,video/x-mng,image/png,';
$request .= "image/jpeg,image/gif;q=0.2,text/css,*/*;q=0.1\r\n";
$request .= "Accept-Language: en-us, en;q=0.50\r\n";
$request .= "Accept-Encoding: gzip, deflate, compress;q=0.9\r\n";
$request .= "Accept-Charset: ISO-8859-1, utf-8;q=0.66, *;q=0.66\r\n";
$request .= "Keep-Alive: 300\r\n";
$request .= "Connection: keep-alive\r\n";
$request .= "Referer: $referer\r\n";
$request .= "Cache-Control: max-age=0\r\n";

if (
$method == "POST" ) {
   
$lenght = strlen( $postValues );
   
$request .= "Content-Type: application/x-www-form-urlencoded\r\n";
   
$request .= "Content-Length: $lenght\r\n";
   
$request .= "\r\n";
   
$request .= $postValues;
}

for (
$i = 0; $i < $repeat; $i++ ) {
   
$socket  = fsockopen( $server, $port, $errno, $errstr, $timeout );
   
fputs( $socket, $request );
    if (
$size > 0 ) {
       
$ret = fgets( $socket, $size );
    } else {
       
$ret = '';
        while ( !
feof( $socket ) ) {
           
$ret .= fgets( $socket, 4096 );
        }
    }
   
fclose( $socket );
    echo
"<hr> $i -- $content $ret";
}
?>

Alejandro Salamanca
up
2
anarchy
17 years ago
The DEFAULT stream timeout is set according to default_socket_timeout in your php.ini file.  Took forever for me to dig that up....
up
2
Jeremy Saintot
13 years ago
Here is my fsockopen-based HTTP request fonction (GET and POST) :

<?php
function http_request(
   
$verb = 'GET',             /* HTTP Request Method (GET and POST supported) */
   
$ip,                       /* Target IP/Hostname */
   
$port = 80,                /* Target TCP port */
   
$uri = '/',                /* Target URI */
   
$getdata = array(),        /* HTTP GET Data ie. array('var1' => 'val1', 'var2' => 'val2') */
   
$postdata = array(),       /* HTTP POST Data ie. array('var1' => 'val1', 'var2' => 'val2') */
   
$cookie = array(),         /* HTTP Cookie Data ie. array('var1' => 'val1', 'var2' => 'val2') */
   
$custom_headers = array(), /* Custom HTTP headers ie. array('Referer: http://localhost/ */
   
$timeout = 1,           /* Socket timeout in seconds */
   
$req_hdr = false,          /* Include HTTP request headers */
   
$res_hdr = false           /* Include HTTP response headers */
   
)
{
   
$ret = '';
   
$verb = strtoupper($verb);
   
$cookie_str = '';
   
$getdata_str = count($getdata) ? '?' : '';
   
$postdata_str = '';

    foreach (
$getdata as $k => $v)
               
$getdata_str .= urlencode($k) .'='. urlencode($v) . '&';

    foreach (
$postdata as $k => $v)
       
$postdata_str .= urlencode($k) .'='. urlencode($v) .'&';

    foreach (
$cookie as $k => $v)
       
$cookie_str .= urlencode($k) .'='. urlencode($v) .'; ';

   
$crlf = "\r\n";
   
$req = $verb .' '. $uri . $getdata_str .' HTTP/1.1' . $crlf;
   
$req .= 'Host: '. $ip . $crlf;
   
$req .= 'User-Agent: Mozilla/5.0 Firefox/3.6.12' . $crlf;
   
$req .= 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' . $crlf;
   
$req .= 'Accept-Language: en-us,en;q=0.5' . $crlf;
   
$req .= 'Accept-Encoding: deflate' . $crlf;
   
$req .= 'Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7' . $crlf;
   
    foreach (
$custom_headers as $k => $v)
       
$req .= $k .': '. $v . $crlf;
       
    if (!empty(
$cookie_str))
       
$req .= 'Cookie: '. substr($cookie_str, 0, -2) . $crlf;
       
    if (
$verb == 'POST' && !empty($postdata_str))
    {
       
$postdata_str = substr($postdata_str, 0, -1);
       
$req .= 'Content-Type: application/x-www-form-urlencoded' . $crlf;
       
$req .= 'Content-Length: '. strlen($postdata_str) . $crlf . $crlf;
       
$req .= $postdata_str;
    }
    else
$req .= $crlf;
   
    if (
$req_hdr)
       
$ret .= $req;
   
    if ((
$fp = @fsockopen($ip, $port, $errno, $errstr)) == false)
        return
"Error $errno: $errstr\n";
   
   
stream_set_timeout($fp, 0, $timeout * 1000);
   
   
fputs($fp, $req);
    while (
$line = fgets($fp)) $ret .= $line;
   
fclose($fp);
   
    if (!
$res_hdr)
       
$ret = substr($ret, strpos($ret, "\r\n\r\n") + 4);
   
    return
$ret;
}
?>

Example usages :

<?php
echo http_request('GET', 'www.php.net');
echo
http_request('GET', 'www.php.net', 80, '/manual/en/function.phpinfo.php');
echo
http_request('GET', 'www.php.net', 80, '/manual/en/function.phpinfo.php', array('get1' => 'v_get1'), array(), array('cookie1' => 'v_cookie1'), array('X-My-Header' => 'My Value'));
?>

[EDIT BY danbrown AT php DOT net: Contains a bugfix provided by "Wrinkled Cheese" on 24-JUN-2011 to fix the $getdata foreach() loop; another bugfix provided by Suat Secmen on 12-JAN-2012 to fix a $timeout = 1000, then stream_set_timeout($fp, 0, $timeout * 1000), equaling 1,000 seconds.]
up
1
richardaburton at hotmail dot com
21 years ago
Improved HTTP/1.1 chunked transfer-encoding example.

The sample code given below by Jack does not function correctly when run against a recent version of Apache (I'm assuming that this did once work, but from the HTTP/1.1 spec I can only assume if it did work it was based mostly on luck).

<?php

$header
= "";
$response = "";

// connect
if (!($request=fsockopen('example.com',80,$errno,$errstr))) exit($errstr);
else {
  
socket_set_timeout($request,10);
  
// send request
  
fwrite($request,$post);
  
// get header
  
do $header.=fread($request,1); while (!preg_match('/\\r\\n\\r\\n$/',$header));
  
// check for chunked encoding
  
if (preg_match('/Transfer\\-Encoding:\\s+chunked\\r\\n/',$header))
      do {
        
$byte = "";
        
$chunk_size="";
         do {
           
$chunk_size.=$byte;
           
$byte=fread($request,1);
         } while (
$byte!="\\r");      // till we match the CR
        
fread($request, 1);         // also drop off the LF
        
$chunk_size=hexdec($chunk_size); // convert to real number
        
$response.=fread($request,$chunk_size);
        
fread($request,2);          // ditch the CRLF that trails the chunk
     
} while ($chunk_size);         // till we reach the 0 length chunk (end marker)
  
else {
     
// check for specified content length
     
if (preg_match('/Content\\-Length:\\s+([0-9]*)\\r\\n/',$header,$matches)) {
        
$response=fread($request,$matches[1]);
      } else {
        
// not a nice way to do it (may also result in extra CRLF which trails the real content???)
        
while (!feof($request)) $response .= fread($request, 4096);
      }
   }
  
// close connection
  
fclose($request);
}

// do something useful with the response
print($header);
print(
$response);

?>

Richard.
up
1
iain at monitormedia dot co dot uk
22 years ago
Here's how to send an email using SMTP. This includes rudimentary checking on server responses during the process of sending an email. Could be improved by more comprehensive processing of the result codes...or going on to the next mail exchanger when you fail after connecting to the first.

<?php

function another_mail($to,$subject,$headers,$message)
{
// Could get this from the php ini?
$from="me@example.com";
list(
$me,$mydomain) = split("@",$from);

// Now look up the mail exchangers for the recipient
list($user,$domain) = split("@",$to,2);
if(
getmxrr($domain,$mx,$weight) == 0)  return FALSE;

// Try them in order of lowest weight first
array_multisort($mx,$weight);
$success=0;

foreach(
$mx as $host) {
 
// Open an SMTP connection
 
$connection = fsockopen ($host, 25, $errno, $errstr, 1);
  if (!
$connection)
    continue;
 
$res=fgets($connection,256);
  if(
substr($res,0,3) != "220") break;

 
// Introduce ourselves
 
fputs($connection, "HELO $mydomain\n");
 
$res=fgets($connection,256);
  if(
substr($res,0,3) != "250") break;

 
// Envelope from
 
fputs($connection, "MAIL FROM: $from\n");
 
$res=fgets($connection,256);
  if(
substr($res,0,3) != "250") break;

 
// Envelope to
 
fputs($connection, "RCPT TO: $to\n");
 
$res=fgets($connection,256);
  if(
substr($res,0,3) != "250") break;

 
// The message
 
fputs($connection, "DATA\n");
 
$res=fgets($connection,256);
  if(
substr($res,0,3) != "354") break;

 
// Send To:, From:, Subject:, other headers, blank line, message, and finish
  // with a period on its own line.
 
fputs($connection, "To: $to\nFrom: $from\nSubject: $subject\n$headers\n\n$message\n.\n");
 
$res=fgets($connection,256);
  if(
substr($res,0,3) != "250") break;

 
// Say bye bye
 
fputs($connection,"QUIT\n");
 
$res=fgets($connection,256);
  if(
substr($res,0,3) != "221") break;

 
// It worked! So break out of the loop which tries all the mail exchangers.
 
$success=1;
  break;
}
// Debug for if we fall over - uncomment as desired
// print $success?"Mail sent":"Failure: $res\n";
if($connection) {
  if(
$success==0) fputs($connection, "QUIT\n");
 
fclose ($connection);
}
return
$success?TRUE:FALSE;
}

another_mail("recipient@example.com","My Subject","X-mailer: PHP Script\nX-another-header: Whatever","Test email body.\n\nNote if you actually put a period on a line\nby itself, the function will terminate prematurely.\n\nYou will get a partial email sent though.\n");
?>
up
1
kexianbin at diyism dot com
12 years ago
My recursive unchunk function:

<?php
function unchunk($result)
         {return
preg_replace('/([0-9A-F]+)\r\n(.*)/sie',
                             
'($cnt=@base_convert("\1", 16, 10))
                               ?substr(($str=@strtr(\'\2\', array(\'\"\'=>\'"\', \'\\\\0\'=>"\x00"))), 0, $cnt).unchunk(substr($str, $cnt+2))
                               :""
                              '
,
                             
$result
                            
);
         }
?>
up
1
xbensemhoun at t-systems dot fr
21 years ago
To make a telnet connection with a Cisco router:

<?php
$cfgServer
= "nnn.nnn.nnn.nnn"//IP of your router
$cfgPort    = 23;                //port, 22 if SSH
$cfgTimeOut = 10;

$usenet = fsockopen($cfgServer, $cfgPort, $errno, $errstr, $cfgTimeOut);

if(!
$usenet)
        {
        echo
"Connexion failed\n";
        exit();
        }
else
        {
        echo
"Connected\n<BR>";
       
fputs ($usenet, "toto\r\n");
       
fputs ($usenet, "en\r\n");
       
fputs ($usenet, "tutu\r\n");
       
fputs ($usenet, "exit\r\n");
        while (!
feof($usenet))
                {
                echo
". ".fgets($usenet, 128)."<BR>\n";
                }
        }
?>

Then you will have:
Connected
. ��������
.
. User Access Verification
.
. Password:
. testXB>en
. Password:
. testXB#exit
.
up
1
p14nd4
10 years ago
It appears that in PHP 5.6.0 (at least the version in Debian jessie, with openssl 1.0.1h-3), this function *is* now validating SSL certificates (in a variety of ways). First, it appears to fail for untrusted certificates (i.e. no matching CA trusted locally), and secondly, it appears to fail for mismatched hostnames in the request and certificate.

---------
$ echo "<?php echo fsockopen(\"ssl://localhost\", 993); ?>" | php -a
Interactive mode enabled

PHP Warning
fsockopen(): Peer certificate CN=`my.test.server' did not match expected CN=`localhost' in - on line 1
PHP Warning:  fsockopen(): Failed to enable crypto in - on line 1
PHP Warning:  fsockopen(): unable to connect to ssl://localhost:993 (Unknown error) in - on line 1
----------
$ echo "<?php echo fsockopen(\"ssl://my.test.server\", 993); ?>" | php -a
Interactive mode enabled

PHP Warning:  fsockopen(): SSL operation failed with code 1. OpenSSL Error messages:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed in - on line 1
PHP Warning:  fsockopen(): Failed to enable crypto in - on line 1
PHP Warning:  fsockopen(): unable to connect to ssl://my.test.server:993 (Unknown error) in - on line 1
---------
#installed CA locally
---------
$ echo "<?php echo fsockopen(\"ssl://my.test.server\", 993); ?>" | php -a
Interactive mode enabled

Resource id #1
up
0
jszoja at gmail dot com
2 years ago
Opening non-existing socket file via `unix//` protocol will result in exception also when suppressing error with @ like:
<?php
$fh
= @fsockopen('unix:///var/run/file-not-exists.sock');
?>

It is important to know when migrating  from PHP 7.4 to 8.x, as handling error suppression with @ has changed.
up
0
GreenReaper
5 years ago
PHP (or OpenSSL) may not always choose to use e.g. TLS 1.2, but you can force it to with tlsv1.2://
https://docs.php.net/manual/en/migration56.openssl.php#migration56.openssl.crypto-method

This was a great help to me, given Twitter's recent API changes to require TLS 1.2+.
up
0
Goce Dokoski
6 years ago
Trying to fsockopen an ssl:// connection, but it was hanging for a long time, ignoring timeout parameter, and eventually returning false, without an error message.

Turns out (at least) on Windows it validates certificates and doesn't have a valid certificate store.

This worked for me:

- download Mozilla's certificate store from https://curl.haxx.se/ca/cacert.pem
- copy it inside php installation (for example: c:\php)
- and set it up in php.ini
       
              openssl.cafile="c:\php\cacert.pem"

My system: Apache/2.4.29 (Win64) OpenSSL/1.0.2n PHP/5.6.38
up
0
perrya at shoalhaven dot nsw dot gov dot au
8 years ago
on my FreeBSD vm, with Joomla, I was getting the error

fsockopen(): unable to connect to ssl://localhost:443 (Unknown error)

when using a contact form and also the module updating process.

After reading other notes on here, regarding certificate validation, I installed the port ca_root_nss

(Root certificates from certificate authorities included in the Mozilla
NSS library and thus in Firefox and Thunderbird.)

Now it works
up
0
gratcypalma at gmail dot com
14 years ago
<?php
/*
this script i used for remote my PvPGN Server, to check email user.
not good, but it work.
*/

set_time_limit(0);
$host   = 'host';
$port   = 'port';
$user   = 'user';
$pass   = 'pass';
$socket = fsockopen($host, $port) or die('Could not connect to: '.$host);
$userdota = "palma";
if(
$socket)
{
   
sendcmd("\r",$socket);
   
$status = "open"; // set status open
       
   
while($status=="open") //while we are connected to the server
     
{    
            
$line = @fgets($socket, 1024) ;
             
/////////////login////////////////   
           
if (strstr($line, "there is no guest account"))
              {
                
sendcmd($user."\r\n",$socket);
                
sendcmd($pass."\r\n",$socket);
              }   
           
//////////////send command ////////////////////
           
if (strstr($line,"Your unique name: ".$user))
              { 
sendcmd("/finger ".$userdota."\r\n",$socket);
              }
           
           
//////////////get email////////////////////
           
if (strstr($line,"email:")) // if respone server write "email:"
             

                
$pattern = '/email:(.*) ,/';
                
preg_match($pattern, $line, $matches);
                
fclose($socket);
                
$status="close"; // status close
                
$matches=str_replace(" ","", $matches);
                
$matches=str_replace(",is_operator:0,is_admin:0,","", $matches);
                
$matches=str_replace("email:","", $matches);
                 print
$matches[0];                
                
$email=$matches[0];
              }
            if (
strstr($line,"ERROR: Invalid user.")) // if respone server write "ERROR: Invalid user."
             

                
                
fclose($socket);
                
$status="close";
                
$error ="Invalid User";    // error message
             
}
           
           
////////////login failed //////////////////////////            
           
if (strstr($line, "Login failed")) // if respone server write "Login failed"
             
{
                
$error = "Login Failed";    // error message
                
fclose($socket);
                
$status="close";
              }
           
           
flush(); // close
     
     
}
         
}
function
sendcmd($cmd,$socket) // send command function
{
 
fputs($socket, $cmd, strlen($cmd));
}
?>
up
0
jabeba at web dot de
16 years ago
If you have to use a proxy to make requests outside of your local network, you may use this class:

<?php
/*
*
* No Proxy Authentification Implemented; PHP 5
*
*/

class RemoteFopenViaProxy {

    private
$result;
    private
$proxy_name;
    private
$proxy_port;
    private
$request_url;

    public function
get_proxy_name() {
        return
$this->proxy_name;
    }

    public function
set_proxy_name($n) {
       
$this->proxy_name = $n;
    }

    public function
get_proxy_port() {
        return
$this->proxy_port;
    }

    public function
set_proxy_port($p) {
       
$this->proxy_port = $p;
    }

    public function
get_request_url() {
        return
$this->request_url;
    }

    public function
set_request_url($u) {
       
$this->request_url = $u;
    }

    public function
get_result() {
        return
$this->result;
    }

    public function
set_result($r) {
       
$this->result = $r;
    }

    private function
get_url_via_proxy() {

       
$proxy_fp = fsockopen($this->get_proxy_name(), $this->get_proxy_port());

        if (!
$proxy_fp) {
            return
false;
        }
       
fputs($proxy_fp, "GET " . $this->get_request_url() . " HTTP/1.0\r\nHost: " . $this->get_proxy_name() . "\r\n\r\n");
        while (!
feof($proxy_fp)) {
           
$proxy_cont .= fread($proxy_fp, 4096);
        }
       
fclose($proxy_fp);
       
$proxy_cont = substr($proxy_cont, strpos($proxy_cont, "\r\n\r\n") + 4);
        return
$proxy_cont;

    }

    private function
get_url($url) {
       
$fd = @ file($url);
        if (
$fd) {
            return
$fd;
        } else {
            return
false;
        }
    }

    private function
logger($line, $file) {
       
$fd = fopen($file . ".log", "a+");
       
fwrite($fd, date("Ymd G:i:s") . " - " . $file . " - " . $line . "\n");
       
fclose($fd);
    }

    function
__construct($url, $proxy_name = "", $proxy_port = "") {

       
$this->set_request_url($url);
       
$this->set_proxy_name($proxy_name);
       
$this->set_proxy_port($proxy_port);

    }

    public function
request_via_proxy() {

       
$this->set_result($this->get_url_via_proxy());
        if (!
$this->get_result()) {
           
$this->logger("FAILED: get_url_via_proxy(" . $this->get_proxy_name() . "," . $this->get_proxy_port() . "," . $this->get_request_url() . ")", "RemoteFopenViaProxyClass.log");
        }
    }

    public function
request_without_proxy() {

       
$this->set_result($this->get_url($this->get_request_url()));
        if (!
$this->get_result()) {
           
$this->logger("FAILED: get_url(" . $url . ")", "RemoteFopenViaProxyClass.log");
        }
    }
}
?>

Use it this way:

<?php
// call constructor
$obj = new RemoteFopenViaProxy($insert_request_url, $insert_proxy_name, $insert_proxy_port);
// change settings after object generation
$obj->set_proxy_name($insert_proxy_name);
$obj->set_proxy_port($insert_proxy_port);
$obj->set_request_url($insert_request_url);
$obj->request_via_proxy();
echo
$obj->get_result();
?>

If there are errors during execution, the script tries to write some useful information into a log file.
up
-1
walter
15 years ago
For some reason the default FreeBSD 7.0 port (jailed environment) breaks fsockopen() on SSL URLs, returning a constant stream of nothing!  In my case this resulted in php-cgi bringing down lighttpd completely, in rapid time!  Avoid FreeBSD/jails/fsockopen + SSL.  Use curl_init() instead.
up
-1
jack at jtr dot de
20 years ago
Here is a function for testing a website/URI for availability:

<?php
   
/*
    * @return boolean
    * @param  string $link
    * @desc   ?berpr?ft die angegeben URL auf Erreichbarkeit (HTTP-Code: 200)
    */
   
function url_validate( $link )
    {       
       
$url_parts = @parse_url( $link );

        if ( empty(
$url_parts["host"] ) ) return( false );

        if ( !empty(
$url_parts["path"] ) )
        {
           
$documentpath = $url_parts["path"];
        }
        else
        {
           
$documentpath = "/";
        }

        if ( !empty(
$url_parts["query"] ) )
        {
           
$documentpath .= "?" . $url_parts["query"];
        }

       
$host = $url_parts["host"];
       
$port = $url_parts["port"];
       
// Now (HTTP-)GET $documentpath at $host";

       
if (empty( $port ) ) $port = "80";
       
$socket = @fsockopen( $host, $port, $errno, $errstr, 30 );
        if (!
$socket)
        {
            return(
false);
        }
        else
        {
           
fwrite ($socket, "HEAD ".$documentpath." HTTP/1.0\r\nHost: $host\r\n\r\n");
           
$http_response = fgets( $socket, 22 );
           
            if (
ereg("200 OK", $http_response, $regs ) )
            {
                return(
true);
               
fclose( $socket );
            } else
            {
//                echo "HTTP-Response: $http_response<br>";
               
return(false);
            }
        }
    }
?>
up
-1
terminal
21 years ago
Try this.
Use AUTH when necessary.
Read RFC 821 when having problems.

<?php

    $handle
= smtp_connect($smtp_server, 25, 30, 1, 1, 1);
    echo
smtp_command($handle, "EHLO $domain\r\n", 1, 1);
    echo
smtp_command($handle, "MAIL FROM:<$from_mail>\r\n", 1, 1);
    echo
smtp_command($handle, "RCPT TO:<$to_mail>\r\n", 1, 1);
    echo
smtp_command($handle, "DATA\r\n", 1, 1);
    echo
smtp_command($handle, "$message\r\n.\r\n", 1, 1);
   
// don't do it like this - it will hang up
    // echo smtp_command($handle, "$message", 1, 1);
    // echo smtp_command($handle, "\r\n.\r\n", 1, 1);
   
echo smtp_command($handle, "QUIT\r\n", 1, 1);
   
smtp_close($handle);
   
   
    function
smtp_connect($host, $port, $timeout=30, $echo_command=False, $echo_response=False, $nl2br=False)
    {
       
$errno = 0;
       
$errstr = 0;
        if(
$echo_command)
        {
            if(
$nl2br) { echo nl2br("CONNECTING TO $host\r\n"); }
            else { echo
"CONNECTING TO $host\r\n"; }
        }
       
$handle = fsockopen($host, $port, $errno, $errstr, $timeout);
        if(!
$handle)
        {
            if(
$echo_command)
            {
                if(
$nl2br) { echo nl2br("CONNECTION FAILED\r\n"); }
                else { echo
"CONNECTION FAILED\r\n"; }
            }
            return
False;
        }
        if(
$echo_command)
        {
            if(
$nl2br) { echo nl2br("SUCCESS\r\n"); }
            else { echo
"SUCCESS\r\n"; }
        }
       
$response = fgets($handle,1);
       
$bytes_left = socket_get_status($handle);
        if (
$bytes_left > 0) { $response .= fread($handle, $bytes_left["unread_bytes"]); }
        if(
$echo_response)
        {
            if(
$nl2br) { echo nl2br($response); }
            else { echo
$response; }
        }
        return
$handle;
    }

    function
smtp_command($handle, $command, $echo_command=False, $nl2br=False)
    {
        if(
$echo_command)
        {
            if(
$nl2br) { echo nl2br($command); }
            else { echo
$command; }
        }
       
fputs($handle, $command);
       
$response = fgets($handle,1);
       
$bytes_left = socket_get_status($handle);
        if (
$bytes_left > 0) { $response .= fread($handle, $bytes_left["unread_bytes"]); }
        if(
$nl2br) { return nl2br($response); }
        else { return
$response; }
    }
   
    function
smtp_close($handle)
    {
       
fclose($handle);
    }
?>
up
-1
Sherif Gayed
21 years ago
Here is how to connect to the web from behind a proxy server:

<?php
/*************start code**************/
/*your proxy server address*/
$proxy = "192.168.10.1";
/*your proxy server port*/
$port = 8080;
/*the url you want to connect to*/
$url = "http://www.php.net/";
$fp = fsockopen($proxy, $port);
fputs($fp, "GET $url HTTP/1.0\r\nHost: $proxy\r\n\r\n");
while(!
feof($fp)){
 
$line = fgets($fp, 4000);
  print(
$line);
}
fclose($fp);
/**************end code**************/
?>
up
-2
biguenique at yahoo dot ca
10 years ago
Did you know that fsockopen() DOES NOT validate SSL certificates whatsoever? For the sake of World's overall security level, I guess it would be a very positive idea to add a BIG WARNING notice on the manual page!

Citing the extensive study  titled "The Most Dangerous Code in the World: Validating SSL Certificates in Non-Browser Software" published in 2012 (google it if they removed the link) on page 5:

"PHP provides several methods for establishing SSL connections. For example, fsockopen, which opens a raw socket to the remote server, can be used to connect to SSL servers by putting “ssl://” in the URL. Even though fsockopen does not perform any certificate checks whatsoever, PHP application developers routinely use it for SSL connection establishment (see Section 9)."

For proper certificate validation with some level of ease, you can always move to cURL, but be careful:

"PHP also provides a cURL binding, which uses cURL’s default settings to establish SSL connections with proper certificate validation. As we show in Sections 7.1, 7.2, and 7.3, application developers often set cURL options incorrectly, overriding the defaults and breaking certificate validation."

For more detailed insights, try out the following code:
<?php readfile("http".str_replace('+', '.', implode('/', array(":", null, "www+cs+utexas+edu", "~shmat", "shmat_ccs12.pdf")))); ?>
up
-2
mikey at badpenguins dot com
16 years ago
My $0.02 on handling chunked transfer encoded output...  Has rudimentary error handling.

<?php
//
// Example usage...
//
$server  = '127.0.0.1';
$port    = '80';
$uri     = '/cgi-bin/random-cgi';
$content = 'Your post content...';

$post_results = httpPost($server,$port,$uri,$content);
if (!
is_string($post_results)) {
    die(
'uh oh, something went wrong');
    } else {
    die(
'Here are your results: ' . $post_results);
    }

//
// Post provided content to an http server and optionally
// convert chunk encoded results.  Returns false on errors,
// result of post on success.  This example only handles http,
// not https.
//
function httpPost($ip=null,$port=80,$uri=null,$content=null) {
    if (empty(
$ip))         { return false; }
    if (!
is_numeric($port)) { return false; }
    if (empty(
$uri))        { return false; }
    if (empty(
$content))    { return false; }
   
// generate headers in array.
   
$t   = array();
   
$t[] = 'POST ' . $uri . ' HTTP/1.1';
   
$t[] = 'Content-Type: text/html';
   
$t[] = 'Host: ' . $ip . ':' . $port;
   
$t[] = 'Content-Length: ' . strlen($content);
   
$t[] = 'Connection: close';
   
$t   = implode("\r\n",$t) . "\r\n\r\n" . $content;
   
//
    // Open socket, provide error report vars and timeout of 10
    // seconds.
    //
   
$fp  = @fsockopen($ip,$port,$errno,$errstr,10);
   
// If we don't have a stream resource, abort.
   
if (!(get_resource_type($fp) == 'stream')) { return false; }
   
//
    // Send headers and content.
    //
   
if (!fwrite($fp,$t)) {
       
fclose($fp);
        return
false;
        }
   
//
    // Read all of response into $rsp and close the socket.
    //
   
$rsp = '';
    while(!
feof($fp)) { $rsp .= fgets($fp,8192); }
   
fclose($fp);
   
//
    // Call parseHttpResponse() to return the results.
    //
   
return parseHttpResponse($rsp);
    }

//
// Accepts provided http content, checks for a valid http response,
// unchunks if needed, returns http content without headers on
// success, false on any errors.
//
function parseHttpResponse($content=null) {
    if (empty(
$content)) { return false; }
   
// split into array, headers and content.
   
$hunks = explode("\r\n\r\n",trim($content));
    if (!
is_array($hunks) or count($hunks) < 2) {
        return
false;
        }
   
$header  = $hunks[count($hunks) - 2];
   
$body    = $hunks[count($hunks) - 1];
   
$headers = explode("\n",$header);
    unset(
$hunks);
    unset(
$header);
    if (!
verifyHttpResponse($headers)) { return false; }
    if (
in_array('Transfer-Encoding: chunked',$headers)) {
        return
trim(unchunkHttpResponse($body));
        } else {
        return
trim($body);
        }
    }

//
// Validate http responses by checking header.  Expects array of
// headers as argument.  Returns boolean.
//
function validateHttpResponse($headers=null) {
    if (!
is_array($headers) or count($headers) < 1) { return false; }
    switch(
trim(strtolower($headers[0]))) {
        case
'http/1.0 100 ok':
        case
'http/1.0 200 ok':
        case
'http/1.1 100 ok':
        case
'http/1.1 200 ok':
            return
true;
        break;
        }
    return
false;
    }

//
// Unchunk http content.  Returns unchunked content on success,
// false on any errors...  Borrows from code posted above by
// jbr at ya-right dot com.
//
function unchunkHttpResponse($str=null) {
    if (!
is_string($str) or strlen($str) < 1) { return false; }
   
$eol = "\r\n";
   
$add = strlen($eol);
   
$tmp = $str;
   
$str = '';
    do {
       
$tmp = ltrim($tmp);
       
$pos = strpos($tmp, $eol);
        if (
$pos === false) { return false; }
       
$len = hexdec(substr($tmp,0,$pos));
        if (!
is_numeric($len) or $len < 0) { return false; }
       
$str .= substr($tmp, ($pos + $add), $len);
       
$tmp  = substr($tmp, ($len + $pos + $add));
       
$check = trim($tmp);
        } while(!empty(
$check));
    unset(
$tmp);
    return
$str;
    }

?>
To Top