PHP
downloads | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | conferences | my php.net

search for in the

Manejando conexiones> <Soporte del método PUT
Last updated: Fri, 22 Aug 2008

view this page in

Usando archivos remotos

Siempre que allow_url_fopen esté habilitado en php.ini, se pueden usar URLs HTTP y FTP con la mayoría de las funciones que toman un archivo como parámetro. Además URLs pueden ser usadas con include(), include_once(), require() y require_once(). Consultar Lista de Protocolos/Envolturas Soportadas para más información sobre los protocolos soportados por PHP.

Note: En PHP 4.0.3 y versiones anteriores, para usar envolturas URL, habia que configurar PHP usando la opción de configuración --enable-url-fopen-wrapper.

Note: Las versiones para windows de PHP anteriores a PHP 4.3 no soportaban acceso remoto a ficheros en las funciones siguientes: include(), include_once(), require(), require_once(), y las funciones imagecreatefromXXX de la extensión GD Functions.

Por ejemplo, se puede usar este para abrir un archivo en un servidor web remoto, analizar en la salida la información que se quiera, y entonces, usar la información en una consulta a base de datos, o simplemente para sacarlas en un estilo que coincida con el resto de su sitio web.

Example #1 Obtener el título de una página remota

<?php
$file 
fopen ("http://www.example.com/""r");
if (!
$file) {
    echo 
"<p>Unable to open remote file.\n";
    exit;
}
while (!
feof ($file)) {
    
$line fgets ($file1024);
    
/* This only works if the title and its tags are on one line */
    
if (eregi ("<title>(.*)</title>"$line$out)) {
        
$title $out[1];
        break;
    }
}
fclose($file);
?>

También se puede escribir a archivos en un servidor FTP (siempre que se conecte como un usuario con los correctos derechos de acceso). Solamente se pueden crear nuevos ficheros usando este método; si se intenta sobreescribir un fichero ya existente, la función fopen() fallará

Para conectar como un usuario distinto de 'anonymous', se necesita especificar el nombre de usuario (y posiblemente contraseña) dentro de la URL, tales como 'ftp://usuario:clave@ftp.example.com/ruta/hacia/archivo'. (Se puede usar la misma clase de sintaxis para acceder a archivos via HTTP cuando se requería una autenticació de same sort of syntax to access files via HTTP when they require Basic authentication.)

Example #2 Almacenando datos en un servidor remoto

<?php
$file 
fopen ("ftp://ftp.example.com/incoming/outputfile""w");
if (!
$file) {
    echo 
"<p>Unable to open remote file for writing.\n";
    exit;
}
/* Write the data here. */
fwrite ($file$_SERVER['HTTP_USER_AGENT'] . "\n");
fclose ($file);
?>

Note: Podeis creer por el ejemplo anterior, que podeis usar esta tecnica para escribir en un fichero de registro remoto. Desgraciadamente no funcionaria porque la llamada fopen() fallaria si el fichero remoto existe. Para usar registros distribuidos de esa manera podeis consultar la funcion syslog().



Manejando conexiones> <Soporte del método PUT
Last updated: Fri, 22 Aug 2008
 
add a note add a note User Contributed Notes
Usando archivos remotos
mail at 3v1n0 dot net
29-Apr-2008 03:18
I've changed the function below to support the 4xx errors and the 30x redirects... This is a partial implementation yet but it's sufficient for the normal usage.

I've made a recursive implementation (if a 30x redirect is found), but it could be easily reverted to an iterative way (simple put something like while (!empty $url) at the beginning, and set the $url to an empty string if no 3xx/4xx status are found).

<?
function http_get($url, $range = 0)
{
    $url_stuff = parse_url($url);
    $port = isset($url_stuff['port']) ? $url_stuff['port'] : 80;
   
    $fp = @fsockopen($url_stuff['host'], $port);
   
    if (!$fp)
        return false;
   
    $query  = 'GET '.$url_stuff['path'].'?'.$url_stuff['query']." HTTP/1.1\r\n";
    $query .= 'Host: '.$url_stuff['host']."\r\n";
    $query .= 'Connection: close'."\r\n";
    $query .= 'Cache-Control: no'."\r\n";
    $query .= 'Accept-Ranges: bytes'."\r\n";
    if ($range != 0)
        $query .= 'Range: bytes='.$range.'-'."\r\n"; // -500
    //$query .= 'Referer: http:/...'."\r\n";
    //$query .= 'User-Agent: myphp'."\r\n";
    $query .= "\r\n";
   
    fwrite($fp, $query);
   
    $chunksize = 1*(1024*1024);
    $headersfound = false;

    while (!feof($fp) && !$headersfound) {
        $buffer .= @fread($fp, 1);
        if (preg_match('/HTTP\/[0-9]\.[0-9][ ]+([0-9]{3}).*\r\n/', $buffer, $matches)) {
            $headers['HTTP'] = $matches[1];
            $buffer = '';
        } else if (preg_match('/([^:][A-Za-z_-]+):[ ]+(.*)\r\n/', $buffer, $matches)) {
            $headers[$matches[1]] = $matches[2];
            $buffer = '';
        } else if (preg_match('/^\r\n/', $buffer)) {
            $headersfound = true;
            $buffer = '';
        }

        if (strlen($buffer) >= $chunksize)
            return false;
    }

    if (preg_match('/4[0-9]{2}/', $headers['HTTP']))
        return false;
    else if (preg_match('/3[0-9]{2}/', $headers['HTTP']) && !empty($headers['Location'])) {
        $url = $headers['Location'];
        return http_get($url, $range);
    }

    while (!feof($fp) && $headersfound) {
        $buffer = @fread($fp, $chunksize);
        echo $buffer;
        ob_flush();
        flush();
    }

    $status = fclose($fp);

    return $status;
}
?>
geoffrey at nevra dot net
07-May-2006 12:53
Really, you should not send headers terminated by \n - it's not per-rfc supported by a HTTP server.

Instead, send as \r\n which is what the protocol specifies, and that regular expression would be matched anywhere, so match for something like /^Content-Length: \d+$/i on each header-line (headers are terminated by the regular expression  /(\r\n|[\r\n])/ - so preg_split on that. Remeber to use the appropriate flags, I can't be arsed to look them up)
heck at fas dot harvard dot edu
14-Sep-2004 09:06
The previous post is part right, part wrong. It's part right because it's true that the php script will run on the remote server, if it's capable of interpreting php scripts. You can see this by creating this script on a remote machine:
<?php
echo system("hostname");
?>
Then include that in a php file on your local machine. When you view it in a browser, you'll see the hostname of the remote machine.

However, that does not mean there are no security worries here. Just try replacing the previous script with this one:
<?php
echo "<?php system(\"hostname\"); ?>";
?>
I'm guessing you can figure out what that's gonna do.

So yes, remote includes can be a major security problem.
geoffrey at nevra dot net
05-Aug-2003 02:25
ok, here is the story:

I was trying to download remote images, finding urls throught apache indexs with regexps and fopen()ing them to get the datas. It didn't work. I thought about binary considerations. Putting the 'b' in the second argument of fopen didn't help much, my browser still didn't want to display the images. I finally understood by watching the datas i was getting from the remote host: it was an html page ! hey, i didn't know apache sent html pages when requesting images, did you ?
the right way is then to send an http request via fsockopen. Here comes my second problem, using explode("\n\n", $buffer); to get rid of the headers. The right way is to get the value of the Content-Lenght field and use it in substr($buffer, -$Content-Lenght);

finally, here is my own function to download these files:

<?php
function http_get($url)
{

   
$url_stuff = parse_url($url);
   
$port = isset($url_stuff['port']) ? $url_stuff['port'] : 80;

   
$fp = fsockopen($url_stuff['host'], $port);

   
$query  = 'GET ' . $url_stuff['path'] . " HTTP/1.0\n";
   
$query .= 'Host: ' . $url_stuff['host'];
   
$query .= "\n\n";

   
fwrite($fp, $query);

    while (
$tmp = fread($fp, 1024))
    {
       
$buffer .= $tmp;
    }

   
preg_match('/Content-Length: ([0-9]+)/', $buffer, $parts);
    return
substr($buffer, - $parts[1]);
?>

}

ho, maybe you'll say i could have parsed the page to get rid of the html stuff, but i wanted to experience http a little ;)

Manejando conexiones> <Soporte del método PUT
Last updated: Fri, 22 Aug 2008
 
 
show source | credits | sitemap | contact | advertising | mirror sites