PHP nasıl uyumsuz bir GET isteğini yapabilirim?

16 Cevap php

Ben farklı bir sunucu üzerinde başka bir komut dosyası için basit bir GET isteğini yapmak istiyoruz. Bunu nasıl yaparsınız?

Bir durumda, ben sadece herhangi çıkışı için gerek kalmadan harici bir komut dosyası istemeniz gerekir.

make_request('http://www.externalsite.com/script1.php?variable=45'); //example usage

İkinci durumda, ben metin çıktısı almak gerekiyor.

$output = make_request('http://www.externalsite.com/script2.php?variable=45');
echo $output; //string output

Bu gerçekten CURL bir iş değil gibi Dürüst olmak gerekirse, ben CURL etrafında karışıklık istemiyorum. Ben de PECL uzantıları yok gibi http_get yararlanmak istemiyorum.

Iş fsockopen misiniz? Eğer öyleyse, dosyanın içeriğini okumadan bunu nasıl yapabilirim? Başka bir yol var mı?

Tüm teşekkürler

Update

Ben ilk durumda, ben komut şey dönmek için beklemek istemiyorsanız, ekledi gerekir. Ben file_get_contents anlamak gibi () tamamen vb yük sayfa için beklemek olacak?

16 Cevap

file_get_contents istediğini yapacak

$output = file_get_contents('http://www.example.com/');
echo $output;

Edit: bir GET isteğini kapalı yangın ve hemen geri dönmek için bir yolu.

http://petewarden.typepad.com/searchbrowser/2008/06/how-to-post-an.html Alıntı

function curl_post_async($url, $params)
{
    foreach ($params as $key => &$val) {
      if (is_array($val)) $val = implode(',', $val);
        $post_params[] = $key.'='.urlencode($val);
    }
    $post_string = implode('&', $post_params);

    $parts=parse_url($url);

    $fp = fsockopen($parts['host'],
        isset($parts['port'])?$parts['port']:80,
        $errno, $errstr, 30);

    $out = "POST ".$parts['path']." HTTP/1.1\r\n";
    $out.= "Host: ".$parts['host']."\r\n";
    $out.= "Content-Type: application/x-www-form-urlencoded\r\n";
    $out.= "Content-Length: ".strlen($post_string)."\r\n";
    $out.= "Connection: Close\r\n\r\n";
    if (isset($post_string)) $out.= $post_string;

    fwrite($fp, $out);
    fclose($fp);
}

Ne yapar, bir yuva açmaya get isteği kapalı yangın ve hemen yuva ve getiri yakın olduğunu.

Sen yok. PHP bir URL aramak için birçok yolu sunarken, bu istek / yürütme döngüsü başına uyumsuz / dişli işleme her türlü yapmak için kutusu desteği dışarı sunmuyor. Bir URL (veya bir SQL deyimi, ya da vb) için bir istek göndererek herhangi bir yöntem tepki some tür beklemek için gidiyor. Ikincil sistem bunu başarmak için yerel makine üzerinde çalışan bir çeşit ("php iş kuyruğunda" etrafında google) gerekir

İlginç bir sorun. Ben sadece bazı işlem veya başka bir sunucuda eylemi tetiklemek istiyorum tahmin ediyorum, ama sonuç ne bakım ve komut devam etmek istemiyorum. Orada bunu yapabilir cURL şey muhtemelen, ama cURL bunu yapamaz eğer çağrıyı yapan sunucu üzerinde başka bir komut dosyası çalıştırmak için exec() kullanarak düşünebilirsiniz. (Genelde insanlar komut arama sonuçları yüzden PHP sadece sürecini tetiklemek için yeteneği varsa emin değilim istiyorum.) exec() bir wget koşmak ya da başka erdirebilirler ile istekte PHP komut dosyası file_get_conents().

Deneyin:

//Your Code here
$pid = pcntl_fork();
if ($pid == -1) {
     die('could not fork');
}
else if ($pid)
{
echo("Bye")  
}
else
{
     //Do Post Processing
}

Bu bir apache modülü olarak çalışacak GEÇMEZ, CGI kullanarak gerekir.

Ben uyumsuz işlem (istek olsun) yapmak için bu ilginç bir bağlantı bulundu.

askapache

Bunun örneği beanstalkd için böyle bir ileti kuyruğu ile uyumsuz işlem yapabilirdi.

Ayrıca fsockpen düşünün.

Bana sen benim yol göstereyim :)

sunucuda yüklü nodejs ihtiyacı

(Benim sunucu 1000 https olsun talebi sadece 2 saniye sürer gönderir)

url.php:

<?
$urls = array_fill(0, 100, 'http://google.com/blank.html');

function execinbackground($cmd) { 
    if (substr(php_uname(), 0, 7) == "Windows"){ 
        pclose(popen("start /B ". $cmd, "r"));  
    } 
    else { 
        exec($cmd . " > /dev/null &");   
    } 
} 
fwite(fopen("urls.txt","w"),implode("\n",$urls);
execinbackground("nodejs urlscript.js urls.txt");
// { do your work while get requests being executed.. }
?>

urlscript.js>

var https = require('https');
var url = require('url');
var http = require('http');
var fs = require('fs');
var dosya = process.argv[2];
var logdosya = 'log.txt';
var count=0;
http.globalAgent.maxSockets = 300;
https.globalAgent.maxSockets = 300;

setTimeout(timeout,100000); // maximum execution time (in ms)

function trim(string) {
    return string.replace(/^\s*|\s*$/g, '')
}

fs.readFile(process.argv[2], 'utf8', function (err, data) {
    if (err) {
        throw err;
    }
    parcala(data);
});

function parcala(data) {
    var data = data.split("\n");
    count=''+data.length+'-'+data[1];
    data.forEach(function (d) {
        req(trim(d));
    });
    /*
    fs.unlink(dosya, function d() {
        console.log('<%s> file deleted', dosya);
    });
    */
}


function req(link) {
    var linkinfo = url.parse(link);
    if (linkinfo.protocol == 'https:') {
        var options = {
        host: linkinfo.host,
        port: 443,
        path: linkinfo.path,
        method: 'GET'
    };
https.get(options, function(res) {res.on('data', function(d) {});}).on('error', function(e) {console.error(e);});
    } else {
    var options = {
        host: linkinfo.host,
        port: 80,
        path: linkinfo.path,
        method: 'GET'
    };        
http.get(options, function(res) {res.on('data', function(d) {});}).on('error', function(e) {console.error(e);});
    }
}


process.on('exit', onExit);

function onExit() {
    log();
}

function timeout()
{
console.log("i am too far gone");process.exit();
}

function log() 
{
    var fd = fs.openSync(logdosya, 'a+');
    fs.writeSync(fd, dosya + '-'+count+'\n');
    fs.closeSync(fd);
}
function make_request($url, $waitResult=true){
  $cmi = curl_multi_init();

  $curl = curl_init();
  curl_setopt($curl, CURLOPT_URL, $url);
  curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);

  curl_multi_add_handle($cmi, $curl);

  $running = null;
  do {
   curl_multi_exec($cmi, $running);
   sleep(.1);
   if(!$waitResult)
       break;
} while ($running > 0);
curl_multi_remove_handle($cmi, $curl);
if($waitResult){
   $curlInfos = curl_getinfo($h);
   if((int) $curlInfos['http_code'] == 200){
       curl_multi_close($cmi);
       return curl_multi_getcontent($curl);
   }
}
curl_multi_close($cmi);

}

curl-easy: Ben iyi test PHP kütüphanesi tavsiye ederim

<?php
$request = new cURL\Request('http://www.externalsite.com/script2.php?variable=45');
$request->getOptions()
    ->set(CURLOPT_TIMEOUT, 5)
    ->set(CURLOPT_RETURNTRANSFER, true);

// add callback when the request will be completed
$request->addListener('complete', function (cURL\Event $event) {
    $response = $event->response;
    $content = $response->getContent();
    echo $content;
});

while ($request->socketPerform()) {
    // do anything else when the request is processed
}

Burada basit bir GET isteğini gerçekleştirmek için kabul edilen yanıt bir uyarlaması.

Sunucu, bu herhangi bir url yeniden yazma çalışmaz yoksa Unutulmaması gereken bir şey. Bir daha tam özellikli http istemcisi kullanmak gerekir.

  /**
   * Performs an async get request (doesn't wait for response)
   * Note: One limitation of this approach is it will not work if server does any URL rewriting
   */
  function async_get($url)
  {
      $parts=parse_url($url);

      $fp = fsockopen($parts['host'],
          isset($parts['port'])?$parts['port']:80,
          $errno, $errstr, 30);

      $out = "GET ".$parts['path']." HTTP/1.1\r\n";
      $out.= "Host: ".$parts['host']."\r\n";
      $out.= "Connection: Close\r\n\r\n";
      fwrite($fp, $out);
      fclose($fp);
  }

Ben CodeIgniter proje için bu yapılan bu parçacığı dayanarak. Gayet güzel çalışıyor. Sen arka planda işlenen herhangi bir işleve sahip olabilir.

Uyumsuz çağrıları kabul eden bir denetleyici.

class Daemon extends CI_Controller
{
    // Remember to disable CI's csrf-checks for this controller

    function index( )
    {
        ignore_user_abort( 1 );
        try
        {
            if ( strcmp( $_SERVER['REMOTE_ADDR'], $_SERVER['SERVER_ADDR'] ) != 0 && !in_array( $_SERVER['REMOTE_ADDR'], $this->config->item( 'proxy_ips' ) ) )
            {
                log_message( "error", "Daemon called from untrusted IP-address: " . $_SERVER['REMOTE_ADDR'] );
                show_404( '/daemon' );
                return;
            }

            $this->load->library( 'encrypt' );
            $params = unserialize( urldecode( $this->encrypt->decode( $_POST['data'] ) ) );
            unset( $_POST );
            $model = array_shift( $params );
            $method = array_shift( $params );
            $this->load->model( $model );
            if ( call_user_func_array( array( $this->$model, $method ), $params ) === FALSE )
            {
                log_message( "error", "Daemon could not call: " . $model . "::" . $method . "()" );
            }
        }
        catch(Exception $e)
        {
            log_message( "error", "Daemon has error: " . $e->getMessage( ) . $e->getFile( ) . $e->getLine( ) );
        }
    }
}

Ve uyumsuz çağrı yapan bir kütüphane

class Daemon
{
    public function execute_background( /* model, method, params */ )
    {
        $ci = &get_instance( );
        // The callback URL (its ourselves)
        $parts = parse_url( $ci->config->item( 'base_url' ) . "/daemon" );
        if ( strcmp( $parts['scheme'], 'https' ) == 0 )
        {
            $port = 443;
            $host = "ssl://" . $parts['host'];
        }
        else 
        {
            $port = 80;
            $host = $parts['host'];
        }
        if ( ( $fp = fsockopen( $host, isset( $parts['port'] ) ? $parts['port'] : $port, $errno, $errstr, 30 ) ) === FALSE )
        {
            throw new Exception( "Internal server error: background process could not be started" );
        }
        $ci->load->library( 'encrypt' );
        $post_string = "data=" . urlencode( $ci->encrypt->encode( serialize( func_get_args( ) ) ) );
        $out = "POST " . $parts['path'] . " HTTP/1.1\r\n";
        $out .= "Host: " . $host . "\r\n";
        $out .= "Content-Type: application/x-www-form-urlencoded\r\n";
        $out .= "Content-Length: " . strlen( $post_string ) . "\r\n";
        $out .= "Connection: Close\r\n\r\n";
        $out .= $post_string;
        fwrite( $fp, $out );
        fclose( $fp );
    }
}

Bu yöntem, 'arka planda' herhangi bir model :: yöntem () işlemek için çağrılabilir. Bu değişken argüman kullanır.

$this->load->library('daemon');
$this->daemon->execute_background( 'model', 'method', $arg1, $arg2, ... );

Öneri: içeren bir FRAMESETya HTML sayfa biçimlendirmek, en 9 kare içinde, diyelim. Her kare kendi myapp.php sayfanın farklı bir "örnek" GET olacaktır. Paralel olarak, Web sunucusu üzerinde çalışan 9 farklı konu yok olacaktır.

Bu kodu deneyin ....

$chu = curl_init();

curl_setopt($chu, CURLOPT_URL, 'http://www.myapp.com/test.php?someprm=xyz');

curl_setopt($chu, CURLOPT_FRESH_CONNECT, true);
curl_setopt($chu, CURLOPT_TIMEOUT, 1);

curl_exec($chu);
curl_close($chu);

CURL php uzantısını etkinleştirin unutmayın lütfen.

Bu benim için çalışıyor, ne yazık ki sizin istek yanıt alamıyor:

<?php
header("http://mahwebsite.net/myapp.php?var=dsafs");
?>

Bu ham tcp soketleri için gerek yok, çok hızlı çalışıyor :)

Bu POST ve GET istekleri hem de Marquis 'cevabı çalışması için nasıl:

  // $type must equal 'GET' or 'POST'
  function curl_request_async($url, $params, $type='POST')
  {
      foreach ($params as $key => &$val) {
        if (is_array($val)) $val = implode(',', $val);
        $post_params[] = $key.'='.urlencode($val);
      }
      $post_string = implode('&', $post_params);

      $parts=parse_url($url);

      $fp = fsockopen($parts['host'],
          isset($parts['port'])?$parts['port']:80,
          $errno, $errstr, 30);

      // Data goes in the path for a GET request
      if('GET' == $type) $parts['path'] .= '?'.$post_string;

      $out = "$type ".$parts['path']." HTTP/1.1\r\n";
      $out.= "Host: ".$parts['host']."\r\n";
      $out.= "Content-Type: application/x-www-form-urlencoded\r\n";
      $out.= "Content-Length: ".strlen($post_string)."\r\n";
      $out.= "Connection: Close\r\n\r\n";
      // Data goes in the request body for a POST request
      if ('POST' == $type && isset($post_string)) $out.= $post_string;

      fwrite($fp, $out);
      fclose($fp);
  }

Sizin güncellemeyle ilgili, yüklemek için tam sayfa için beklemek istemeyen hakkında - Ben bir HTTP HEAD isteği aradığınız ne olduğunu düşünüyorum ..

get_headers Bu yapmalıyım - Ben sadece başlıkları istekleri düşünüyorum, yani tam sayfa içerik gönderilen olmayacaktır.

"PHP / Curl: HEAD Request takes a long time on some sites" PHP / Curl kullanarak bir HEAD isteği yapmak için nasıl açıklar

Eğer her komut tutmak isteği tetiklemek değil istiyorsanız, değişen karmaşık bir kaç yolu vardır ..

  • Bir arka plan işlemi olarak HTTP isteği yürütmek, http://stackoverflow.com/questions/45953/php-execute-a-background-process/45966 - Bu platform özgü olacak ve really dikkatli olmak zorunda - temelde sizin gibi "wget -O /dev/null $carefully_escaped_url" şey çalıştıracaktır komutu parametreleri kaçan yaklaşık
  • Executing a PHP script in the background - temelde UNIX işletim yöntemi olarak aynı, ancak bir PHP komut dosyası yerine bir kabuk komutu yürütülürken
  • Bir veritabanı (veya beanstalkd olasılıkla overkill gibi bir şey) kullanarak, bir "iş kuyruğunu" var. Sen kuyruğuna bir URL eklemek ve bir arka plan işlemi veya cron işi rutin yeni işler için denetler ve URL isteklerini gerçekleştirir