web-dev-qa-db-ja.com

カール経由のPHPでのヘッダーのみの取得

実際には、2つの質問があります。

(1)phpとcurlを使用した全ページ検索ではなく、ヘッダーのみを検索する場合、リモートサーバーで使用される処理能力または帯域幅の削減はありますか?

(2)最初の質問に対する答えは[〜#〜] yes [〜#〜]であると思い、間違っているかもしれないので、最終更新日またはIf-Modifiedを取得しようとしています。 -リモートファイルのヘッダーは、ローカルに保存されたデータの日時と比較するためだけに使用されるため、変更された場合はローカルに保存できます。ただし、私のスクリプトはその情報を取得できないようです。これを実行すると、NULLが返されます。

_class last_change {

 public last_change;

 function set_last_change() {
  $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, "http://url/file.xml");
    curl_setopt($curl, CURLOPT_HEADER, true);
    curl_setopt($curl, CURLOPT_FILETIME, true);
    curl_setopt($curl, CURLOPT_NOBODY, true);
  // $header = curl_exec($curl);
  $this -> last_change = curl_getinfo($header);
  curl_close($curl);
 }

 function get_last_change() {
  return $this -> last_change['datetime']; // I have tested with Last-Modified & If-Modified-Since to no avail
 }

}
_

$header = curl_exec($curl)がコメント化されていない場合、ヘッダーデータが表示されます(リクエストしていない場合でも)。

_HTTP/1.1 200 OK
Date: Fri, 04 Sep 2009 12:15:51 GMT
Server: Apache/2.2.8 (Linux/SUSE)
Last-Modified: Thu, 03 Sep 2009 12:46:54 GMT
ETag: "198054-118c-472abc735ab80"
Accept-Ranges: bytes
Content-Length: 4492
Content-Type: text/xml
_

それに基づいて、「Last-Modified」が返されます。

だから、私は何が間違っていますか?

59
Krule

curl_getinfo()に$ headerを渡します。 _$curl_(カールハンドル)である必要があります。 filetimeのみを取得するには、curl_getinfo()の2番目のパラメーターとして_CURLINFO_FILETIME_を渡します。 (多くの場合、filetimeは使用できません。その場合、-1として報告されます)。

しかし、あなたのクラスは無駄であるように思われ、役に立つかもしれない多くの情報を捨てています。以下に別の方法を示します。

_class URIInfo 
{
    public $info;
    public $header;
    private $url;

    public function __construct($url)
    {
        $this->url = $url;
        $this->setData();
    }

    public function setData() 
    {
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $this->url);
        curl_setopt($curl, CURLOPT_FILETIME, true);
        curl_setopt($curl, CURLOPT_NOBODY, true);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_HEADER, true);
        $this->header = curl_exec($curl);
        $this->info = curl_getinfo($curl);
        curl_close($curl);
    }

    public function getFiletime() 
    {
        return $this->info['filetime'];
    }

    // Other functions can be added to retrieve other information.
}

$uri_info = new URIInfo('http://www.codinghorror.com/blog/');
$filetime = $uri_info->getFiletime();
if ($filetime != -1) {
    echo date('Y-m-d H:i:s', $filetime);
} else {
    echo 'filetime not available';
}
_

はい、HTTPヘッダーのみを返す(結局、HEAD要求に応答する)ため、サーバーの負荷は軽くなります。ライターの量は大きく異なります。

50
GZipp

なぜこれにCURLを使用するのですか?そのためのPHP関数があります。

$headers=get_headers("http://www.amazingjokes.com/img/2014/530c9613d29bd_CountvonCount.jpg");
print_r($headers);

以下を返します。

Array
(
    [0] => HTTP/1.1 200 OK
    [1] => Date: Tue, 11 Mar 2014 22:44:38 GMT
    [2] => Server: Apache
    [3] => Last-Modified: Tue, 25 Feb 2014 14:08:40 GMT
    [4] => ETag: "54e35e8-8873-4f33ba00673f4"
    [5] => Accept-Ranges: bytes
    [6] => Content-Length: 34931
    [7] => Connection: close
    [8] => Content-Type: image/jpeg
)

この後、コンテンツタイプを簡単に取得できるはずです。

Format = 1をget_headersに追加することもできます。

$headers=get_headers("http://www.amazingjokes.com/img/2014/530c9613d29bd_CountvonCount.jpg",1);
    print_r($headers);

これにより、次が返されます。

Array
(
    [0] => HTTP/1.1 200 OK
    [Date] => Tue, 11 Mar 2014 22:44:38 GMT
    [Server] => Apache
    [Last-Modified] => Tue, 25 Feb 2014 14:08:40 GMT
    [ETag] => "54e35e8-8873-4f33ba00673f4"
    [Accept-Ranges] => bytes
    [Content-Length] => 34931
    [Connection] => close
    [Content-Type] => image/jpeg
)

詳細はこちら(PHP.NET)

37
patrick

(1)はい。 HEAD要求(この場合は発行している)は、標準のGET要求のようなヘッダーとコンテンツではなく、HTTPヘッダーのみを返すため、サーバー上ではるかに軽量です。

(2)curl_exec()を呼び出す前に、CURLOPT_RETURNTRANSFERオプションをtrueに設定して、印刷ではなくコンテンツを返す必要があります。

curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);

また、クラスが正しく機能するはずです。

15
Ian Kemp

デフォルトのストリームコンテキストを設定できます。

stream_context_set_default(
    array(
        'http' => array(
            'method' => 'HEAD'
        )
    )
);

次に使用します:

$headers = get_headers($url,1);

get_headersは、ログインプロンプトやCookieなどのトリガー認証ルーチンなどの手順をスキップすると、cURLよりも効率的であるようです。

4
lipinf

CURLOPT_HEADERを使用して、出力文字列をマップに解析する実装を次に示します。

function http_headers($url){
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_NOBODY, true);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HEADER, true);

    $headers = curl_exec($ch);

    curl_close($ch);

    $data = [];
    $headers = explode(PHP_EOL, $headers);
    foreach ($headers as $row) {
        $parts = explode(':', $row);
        if (count($parts) === 2) {
            $data[trim($parts[0])] = trim($parts[1]);
        }
    }

    return $data;
};

サンプル使用法:

$headers = http_headers('https://i.ytimg.com/vi_webp/g-dKXOlsf98/hqdefault.webp');
print_r($headers);

Array
(
    ['Content-Type'] => 'image/webp'
    ['ETag'] => '1453807629'
    ['X-Content-Type-Options'] => 'nosniff'
    ['Server'] => 'sffe'
    ['Content-Length'] => 32958
    ['X-XSS-Protection'] => '1; mode=block'
    ['Age'] => 11
    ['Cache-Control'] => 'public, max-age=7200'
)
4

追加する必要があります

curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);

ヘッダーを印刷する代わりに返す。

サーバー上でヘッダーのみを返すのが軽いかどうかは、実行中のスクリプトによって異なりますが、通常はそうなります。

「datetime」ではなく「filetime」も必要だと思います。

4
Greg