Http head request php

schlitt.info — php, photography and private stuff

ext/curl is the common tool of choice, if one needs to perform more advanced HTTP requests from a PHP script (for simple ones, use a stream!). I recently wanted to perform a HEAD request to a file, after which I wanted to perform some more advanced HTTP interaction, so CURL was also the tool of choice here.

Trying it out on the shell with a local web server, CURL was operating quite slow, in contrast to a GET request. The -i command line switch makes curl include the headers in the printed output, -X lets you define a custom HTTP request.

dotxp@tango ~ $ time curl -i -X HEAD http://localhost/admin/ HTTP/1.1 200 OK X-Powered-By: PHP/5.2.7-dev Content-Type: text/html; charset=utf-8 Date: Mon, 23 Jun 2008 09:10:59 GMT Server: lighttpd/1.4.19 real 0m6.079s user 0m0.004s sys 0m0.000s dotxp@tango ~ $ time curl -i -X GET http://localhost/admin/ HTTP/1.1 200 OK Transfer-Encoding: chunked X-Powered-By: PHP/5.2.7-dev Content-Type: text/html; charset=utf-8 Date: Mon, 23 Jun 2008 09:12:27 GMT Server: lighttpd/1.4.19 real 0m0.180s user 0m0.004s sys 0m0.000s

A difference of 6 seconds runtime of a HEAD in contrast to 0.2 seconds for a GET is quite contrary to the original idea of a HEAD request. HEAD is used to just receive the headers of an URI instead of receiving the whole contents, to save bandwidth, memory and execution time.

ext/curl showed the exact same problem. Fiddling a bit with the command line switches, I found to replace -i with -I which makes curl print only the headers, but not the body of the response.

dotxp@tango ~ $ time curl -I -X HEAD http://localhost/admin/ HTTP/1.1 200 OK X-Powered-By: PHP/5.2.7-dev Content-Type: text/html; charset=utf-8 Date: Mon, 23 Jun 2008 09:19:05 GMT Server: lighttpd/1.4.19 real 0m0.044s user 0m0.004s sys 0m0.000s

0.04 seconds is now even faster than the corresponding GET request, with the -I switch, which took me 0.09 seconds. Now I just needed to transfer the command line options to the corresponding ext/curl ones:

$c = curl_init(); curl_setopt( $c, CURLOPT_RETURNTRANSFER, true ); curl_setopt( $c, CURLOPT_CUSTOMREQUEST, ‘HEAD’ ); curl_setopt( $c, CURLOPT_HEADER, 1 ); curl_setopt( $c, CURLOPT_NOBODY, true ); curl_setopt( $c, CURLOPT_URL, ‘http://localhost/admin/’ ); $res = curl_exec( $c );

The RETURNTRANSFER makes ext/curl return the HTTP response instead of printing it. Using the CUSTOMREQUEST option you define to send a HEAD request instead of a standard GET or POST request. The HEADER option makes ext/curl include the response headers in the return value of curl_exec() call and NOBODY avoids the inclusion of the body content here. The URL option as usually sets the URL to request and curl_exec() makes ext/curl execute the request.

The runtime was even a fraction of a second faster here, compared to the command line version, but that can be subjectively. However, the HEAD request works as expected now. Maybe it’s useful for someone to know this.

If you liked this blog post or learned something, please consider using flattr to contribute back: .

Читайте также:  Тег IMG

Trackbacks

Comments

adnan.

if the curl statements were run in succession, is it not possible that server caching caused the remaining calls to be faster?

maybe queries are getting cached at the mysql level? or there’s some application caching going on?

Anonymous

I restarted the server and also tried multiple GET and HEAD requests in a sequence on their own. Since I’m requesting a PHP generated page that does not send cache headers on its own, caching is also very unlikely.

I think the problem without the NOBODY option is, that CURL waits for a repsonse body, but the server does not send any. Therefore CURL timesout somewhen.

However, the solution above works well.

Alexandr Egorov

Shahar Evron

With Zend_Http_Client you can do it so:

require_once ‘Zend/Http/Client.php’;
$client = new Zend_Http_Client(‘http://localhost/admin’);
$response = $client->request(‘HEAD’);
?>

It does understand the HEAD request so it will not try to read the body.

Toby

Sorry, your code seems to have been stripped your code example. If possible, please post it again without any markup (including the PHP tags).

Shahar Evron

Yep — I enclosed my code in php tags.. here it is without it:

Toby

Thanks for posting the code again. 🙂

Looks easy. Does Zend_HTTP_Client abstract different methods of sending the request or does is just use a manual socket?

Shahar Evron

Zend_Http_Client has adapters architecture — so theoretically, one could write different adapters that use different methods (cURL, wrappers, pecl_http etc.) to do the actual connection.

M. van der Klip

Did you have a look at the manpage for curl? The definition of the ‘-I’ option is not to display headers only, but in fact to perform a HEAD request. Exactly what you want and no need at all to specify a custom request method.

Raj

Tom

Thank you for the hints using curl. But this hint in the comments make my script work:

Источник

This website needs your consent to use cookies in order to customize ads and content.

If you give us your consent, data may be shared with Google.

GET, POST, and HEAD requests with PHP’s build-in functions

How to send HTTP requests using the build-in file functions of PHP.

d

PHP article image

There are a few ways to perform HTTP requests in PHP, in this tutorial we will show how to send a POST and GET request by using the file- functions in combination with stream_context_create.

While using a library like cURL is probably one of the most popular ways to perform HTTP requests, you can also use functions such as file_get_contents and fopen.

While the name of these functions do not exactly indicate that they can also be used for HTTP requests, they do actually work quite well for this, and they are also fairly easy to use.

The stream_context_create function mentioned before is used to gain finer control over various options related to a request.

There should be no disadvantage to using the build-in functions instead of cURL, and unlike what is often claimed, they can be used for both POST and GET requests. However, some hosting companies might disable allow_url_fopen, which will break scripts relying on these methods.

Читайте также:  Php включить базы данных

GET Requests

To perform a simple get request, we will first create a $handle variable. We can use this to reference the request when storing the downloaded data in the $contents variable using stream_get_contents.

$handle = fopen("https://beamtic.com/", "rb"); $contents = stream_get_contents($handle); fclose($handle); 

The stream_get_contents function automatically downloads a file or web page, however, if you wish to do it manually, for finer control over the process, you may use a while loop in combination with fread:

$handle = fopen("https://beamtic.com/", "rb"); $contents = ''; while (!feof($handle))  $contents .= fread($handle, 8192); > fclose($handle); echo $contents; 

In this case the last argument in the fread function is equal to the chunk size, this is usually not larger than 8192 (8*1024). Keep in mind that this can be larger or smaller, but may also be limited by the system PHP is running on. You can optimize your PHP scripts by not using a larger chunk-size than that of your storage device.

One of the simplest ways to download a file, is to use file_get_contents. It requires far less code than using the other methods, but it also offers less control over the process.

$homepage = file_get_contents('https://beamtic.com/'); echo $homepage; 

POST Requests

Sending a POST request is not much harder than sending GET. We just have to use the stream_context_create function to add the necessary headers to perform the request.

Again, we can do this both with file_get_contents and fopen; but let us just use file_get_contents for now:

$sURL = "https://beamtic.com/Examples/http-post.php"; // The POST URL $sPD = "name=Jacob&bench=150"; // The POST Data $aHTTP = array( 'http' => // The wrapper to be used array( 'method' => 'POST', // Request Method // Request Headers Below 'header' => 'Content-type: application/x-www-form-urlencoded', 'content' => $sPD ) ); $context = stream_context_create($aHTTP); $contents = file_get_contents($sURL, false, $context); echo $contents; 

The $sURL variable contains the POST URL.

The $sPD variable contains the data you want to post. Formatting should match the content-type header.

The $aHTTP array has all of the options, including headers, which will be passed on to stream_context_create.

You can also perform POST requests with the fread function.

$sURL = "http://beamtic.com/Examples/http-post.php"; // The POST URL $sPD = "name=Jacob&bench=150"; // The POST Data $aHTTP = array( 'http' => // The wrapper to be used array( 'method' => 'POST', // Request Method // Request Headers Below 'header' => 'Content-type: application/x-www-form-urlencoded', 'content' => $sPD ) ); $context = stream_context_create($aHTTP); $handle = fopen($sURL, 'r', false, $context); $contents = ''; while (!feof($handle))  $contents .= fread($handle, 8192); > fclose($handle); echo $contents; 

Request Headers

If you got multiple headers, remember to separate them with \r\n

The content-type header tells the server how the posted data is formatted. The application/x-www-form-urlencoded content-type is often used by web applications, but you can also encounter multipart/form-data. If an application does not support the content-type you specify, the POST will usually just fail.

The content header contains the actual data that you want to post. This should be formatted in accordance with the content-type you are using.

Alternatively, you may also add options and headers as shown below, this time adding a referer header:

$aHTTP['http']['method'] = 'GET'; $aHTTP['http']['header'] = "User-Agent: My PHP Script\r\n"; $aHTTP['http']['header'] .= "Referer: https://beamtic.com/\r\n"; 

Additional request headers will be added in the same way; do this by adding a single Carriage return (\r), and a line feed (\n) at the end of each header, followed by whatever header you want to add. Once you have added all the headers, you should end up with something like the below (full script):

$sURL = "https://beamtic.com/api/request-headers"; // The POST URL $aHTTP['http']['method'] = 'GET'; $aHTTP['http']['header'] = "User-Agent: My PHP Script\r\n"; $aHTTP['http']['header'] .= "Referer: https://beamtic.com/\r\n"; $context = stream_context_create($aHTTP); $contents = file_get_contents($sURL, false, $context); echo $contents; 

Tools:

You can use the following API endpoints for testing purposes:

https://beamtic.com/api/user-agent
https://beamtic.com/api/request-headers

Источник

Метод HEAD

Метод HEAD аналогичен методу GET, за исключением того, что сервер ничего не посылает в информационной части ответа. Метод HEAD запрашивает только информацию о файле и ресурсе, т.е. ничего кроме заголовков не возвращает. Этот метод используется, когда клиент хочет найти информацию о документе, не получая его. Удобно, когда нужно узнать размер файла, существует ли файл, когда последний раз изменялся файл. Позволяет сэкономить много времени и трафика.

Состав заголовка запроса HEAD должен быть такой же, как в запросе GET.

Пример метода HEAD

 else < // формируем http-заголовки к серверу $request ; $request .= "Host: ekimoff.ru\r\n"; $request .= "User-Agent: Mozilla/2.0\r\n"; $request .= "Connection: close\r\n\r\n"; // отсылаем запрос серверу fputs($fp, $request); // получем ответ от сервера $content = ''; while(!feof($fp) )< $content .= fgets($fp); >echo $content; fclose($fp); > ?>

Как мы видим, содержимое файла в ответ на запрос HEAD не передается. Приходят только заголовки

HTTP/1.1 200 OK Server: nginx/0.6.32 Date: Sat, 24 Apr 2010 14:19:41 GMT Content-Type: text/plain; charset=UTF-8 Connection: close Last-Modified: Sat, 24 Apr 2010 13:19:02 GMT ETag: "43ace4b-b-4bd2efc6" Accept-Ranges: bytes Content-Length: 11

Теперь заменим в исходном коде метод HEAD на метод GET

 else < // формируем http-заголовки к серверу $request ; $request .= "Host: ekimoff.ru\r\n"; $request .= "User-Agent: Mozilla/2.0\r\n"; $request .= "Connection: close\r\n\r\n"; // отсылаем запрос серверу fputs($fp, $request); // получем ответ от сервера $content = ''; while(!feof($fp) )< $content .= fgets($fp); >echo $content; fclose($fp); > ?>

Ответ аналогичен, но теперь сервер отправил еще содержимое файла:

HTTP/1.1 200 OK Server: nginx/0.6.32 Date: Sat, 24 Apr 2010 15:04:36 GMT Content-Type: text/plain; charset=UTF-8 Connection: close Last-Modified: Sat, 24 Apr 2010 13:19:02 GMT ETag: "43ace4b-b-4bd2efc6" Accept-Ranges: bytes Content-Length: 11 bla-bla-bla

Размер файлика всего 11 байт. Представим, что в файл весит 11 Мб и запрашивается каждую секунду (например, последние обновления продуктов компании). Если внешнее приложение будет запрашивать данный файл напрямую каждую секунду, то трафик будет расти как на дрожжах.

Кстати, подобная схема используется у нас на работе, за тем исключением, что рядом с большим xml-файлом лежит маленький файлик в несколько байт, в котором хранится md5–хэш от большого файла. Таким образом, сделав сначала GET-запрос к маленькому файлу с md-хэшем, мы узнаем нужно ли нам делать запрос к основному файлу. md5-хэш хранится у нас в кэше для того чтобы сравнить его с содержимым md5-файлика на удаленном сервере. В данном примере не используется метод HEAD, но принцип экономии ресурсов и трафика аналогичен методу HEAD.

Источник

Оцените статью