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

search for in the

Connection handling> <PUT methode ondersteuning
Last updated: Wed, 22 Jul 2009

view this page in

Het gebruik van remote bestanden

Zo lang de ondersteuning voor "URL fopen wrapper" actief is wanneer je PHP configureert (is standaard actief tenzij je expliciet de --disable-url-fopen-wrapper optie gebruikt (voor versies tot en met 4.0.3) of allow_url_fopen zet to "off" (voor nieuwere versies) kun je HTTP en FTP urls gebruiken met de meeste functies die standaard gezien een bestandsnaam als argument vereisen, dit werkt ook met de require() en include() functies.

Note: Op het Windows platform kun je geen remote bestanden gebruiken als argument in de include() en require() functies.

Je kunt dit bijvoorbeeld gebruiken om een bestand te openen op een andere webserver, de output verwerken om de data te krijgen die jij wilt hebben en vervolgens deze data in een database query gebruiken of om simpel weg deze data weer te geven in je eigen website-stijl.

Example#1 De titel van een remote pagina op halen.

<?php
$bestand 
fopen ("http://www.php.net/""r");
if (!
$bestand) {
    echo 
"<p>Kon remote bestand niet open.\n";
    exit;
}
while (!
feof ($bestand)) {
    
$regel fgets ($bestand1024);
    
/* dit werkt alleen als de titel en <title> en </title> op 1 regel staan */
    
if (eregi ("<title>(.*)</title>"$regel$matches)) {
        
$titel $matches[1];
        break;
    }
}
fclose($bestand);
?>

Je kunt ook naar bestanden schrijven op een FTP server als je teminste de juiste rechten hebt voor deze operatie en zolang het bestand nog niet bestaat op de FTP server. Om in te loggen als een user anders dan 'anonymous' moet je je gebruikersnaam en mogelijk je paswoord opgeven in de URL, dit gaat op deze manier: 'ftp://gebruikersnaam:paswoord@ftp.mijnserver.nl/pad/naar/bestand' Op deze manier kan je ook over HTTP toegang krijgen tot bestanden die 'Basic Authentication' vereisen.

Example#2 Data opslaan op een andere server

<?php
$bestand 
fopen ("ftp://ftp.php.net/incoming/outputfile""w");
if (!
$bestand) {
    echo 
"<p>Kon remote bestand niet openen om naar te schrijven\n</p>";
    exit;
}
/* Schrijf data weg */
fputs ($bestand"$HTTP_USER_AGENT\n");
fclose ($bestand);
?>

Note: Je kunt het idee krijgen om deze techniek te gebruiken om te schrijven naar een log op een andere server, maar zoals eerder gezegd kan je alleen schrijven naar bestanden die nog niet bestaan. Om 'distributed logging' mogelijk te maken zou je moeten kijken naar syslog().



Connection handling> <PUT methode ondersteuning
Last updated: Wed, 22 Jul 2009
 
add a note add a note User Contributed Notes
Het gebruik van remote bestanden
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 ;)

Connection handling> <PUT methode ondersteuning
Last updated: Wed, 22 Jul 2009
 
 
show source | credits | stats | sitemap | contact | advertising | mirror sites