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

search for in the

Tratamento de Conexões> <Suporte ao método PUT
[edit] Last updated: Fri, 26 Apr 2013

view this page in

Usando arquivos remotos

Enquanto allow_url_fopen estiver disponível no arquivo php.ini, você pode usar URLs HTTP e FTP com a maioria das funções que recebem um nome de arquivo como parâmetro. Além disso, URLs podem ser usadas com as funções include, include_once, require e require_once (desde o PHP 5.2.0, allow_url_include precisa estar habilitado para isto). Veja Supported Protocols and Wrappers para mais informações sobre protocolos suportados pelo PHP.

Nota:

No PHP 4.0.3 e inferiores, para usar URL wrappers, você precisava configurar o PHP usando a opção do script configure --enable-url-fopen-wrapper .

Nota:

As versões para Windows do PHP mais novas que o PHP 4.3 não suportam acesso a arquivos remoto para as seguintes funções: include, include_once, require, require_once, e as funções imagecreatefromXXX na extensão Funções da GD.

Por exemplo, você pode usar isso para abrir um arquivo em um web server remoto, avaliar a saída para a informação que você precisa, e então usar a informação em uma query de banco de dados, ou simplesmente mostrar em um estilo que combine com o resto do seu website.

Exemplo #1 Pegando o título de uma página remota

<?php
$file 
fopen ("http://www.example.com/""r");
if (!
$file) {
    echo 
"<p>Incapaz de abrir arquivo remoto.\n";
    exit;
}
while (!
feof ($file)) {
    
$line fgets ($file1024);
    
/* Isso só funciona se o título e suas tags estiverem na mesma linha */
    
if (eregi ("<title>(.*)</title>"$line$out)) {
        
$title $out[1];
        break;
    }
}
fclose($file);
?>

Você também pode escrever arquivos em um servidor FTP (presumindo que você conectou como um usuário com os direitos de acesso corretos). Você só pode criar arquivos novos usando esse método. Se você tentar sobrescrever um arquivo que já existe, a chamada para fopen() falhará.

Para conectar como usuário que não o 'anonymous', você precisa especificar o nome de usuário (e possivelmente a senha) dentro da URL, como 'ftp://usuario:senha@ftp.example.com/caminho/para/arquivo'. (Você pode usar o mesmo tipo de sintaxe para acessar arquivos via HTTP quando eles requerem autenticação Basic).

Exemplo #2 Guardando informação em um servidor remoto

<?php
$file 
fopen ("ftp://ftp.example.com/incoming/outputfile""w");
if (!
$file) {
    echo 
"<p>Incapaz de abrir arquivo remoto para escrita.\n";
    exit;
}
/* Escreva informação aqui. */
fwrite ($file$_SERVER['HTTP_USER_AGENT'] . "\n");
fclose ($file);
?>

Nota:

Você talvez tenha tido a idéia, pelo exemplo acima, de usar essa técnica para escrever para um arquivo de log remoto. Infelizmente isso não funcionaria porque a chamada a fopen() falhará se o arquivo remoto já existir. Para fazer logs distrubuídos dessa maneira, você deve dar uma olhada na função syslog().



Tratamento de Conexões> <Suporte ao método PUT
[edit] Last updated: Fri, 26 Apr 2013
 
add a note add a note User Contributed Notes Usando arquivos remotos - [4 notes]
up
1
heck at fas dot harvard dot edu
8 years ago
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.
up
0
mail at 3v1n0 dot net
5 years ago
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;
}
?>
up
0
geoffrey at nevra dot net
9 years ago
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 ;)
up
-1
geoffrey at nevra dot net
6 years ago
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)

 
show source | credits | stats | sitemap | contact | advertising | mirror sites