CURLOPT_HEADERFUNCTION - Return of cookies

Asked

Viewed 438 times

0

I have this function that returns Cookies from a particular site, I’m learning HTTP HEADERS,

But I don’t know why this warning if I’m returning my cookies all okay, What’s wrong with my code?

Notice: Object of class stdClass could not be converted to int in C: wamp64 www tr api login.php on line 34

Here is my code:

<?php

function cookies() {
    $request = curl_init();
    curl_setopt_array($request, [
            CURLOPT_URL                         => 'https://tr.com',
            CURLOPT_CUSTOMREQUEST       => 'GET',
            CURLOPT_RETURNTRANSFER  => true,
            CURLOPT_SSL_VERIFYHOST  => false,
            CURLOPT_SSL_VERIFYPEER  => false,
            CURLOPT_HEADER                  => true,
            CURLOPT_HEADERFUNCTION  => function($curl, $header) use (&$cookie) {
                if (stripos($header, 'Set-Cookie:') === 0) {
                    $cookieOBJ = new \stdClass();
                    $cookieOBJ->cookies = '';
                    if (preg_match_all('/^Set-Cookie: \s*([^;]*)/i', $header, $matches)) {
                        foreach ($matches[1] as $cookie) {
                            $cookie = explode('=', $cookie);

                            $key = (!empty($cookie[0])) ? $cookie[0] : '';
                            $val = (!empty($cookie[1])) ? $cookie[1] : '';

                            $cookieOBJ->{"$key"} = $val;

                            $cookieOBJ->cookies .= $key . '=' . $cookieOBJ->{"$key"} . '; ';
                        }
                    }
                    return $cookieOBJ;
                }
                return strlen($header);
            }
        ]
    );
    $response = curl_exec($request);
    curl_close($request);
}

var_dump(cookies());

Note: I need you to return me as follows:

C:\wamp64\www\tr\api\login.php:28:
object(stdClass)[2]
  public 'cookies' => string 'fm=; ' (length=5)
  public 'fm' => string '' (length=0)

And by using my variable $cookieOBJ return me all or $cookieOBJ->cookies, but if I use $cookieOBJ->fm gives me an error:

Notice: Undefined Property: stdClass::$fm in C: wamp64 www tr api login.php on line 28

What is the solution?

1 answer

0

This code will never work, first see the documentation of the CURLOPT_HEADERFUNCTION:

This callback Function must Return the number of bytes Actually Taken care of. If that amount differs from the amount passed in to your Function, it’ll Signal an error to the library. This will cause the transfer to get aborted and the libcurl Function in Progress will Return CURLE_WRITE_ERROR.

Your return $cookieOBJ; doesn’t make any sense. Just as it doesn’t make sense to make a foreach nor preg_match_all, if each time will only have one cookie, not several. After all, by CURLOPT_HEADERFUNCTION:

The header callback will be called Once for each header and only complete header Lines are passed on to the callback.

If you go see the RFC6265:

Origin Servers SHOULD NOT fold Multiple Set-Cookie header Fields into a single header field. The usual Mechanism for Folding HTTP headers Fields (i.e., as defined in [RFC2616]) Might change the Semantics of the Set-Cookie header field because the %x2C (",") Character is used by Set-Cookie in a way that Conflicts with such Folding.

Therefore, each header of the Set-Cookie, sent by the server, you will only have a single cookie.


A much easier way, that even you’ve used, inclusive must have come from here and was explained here:

CURLOPT_HEADERFUNCTION => function($curl, $cabeçalho) use (&$cookie){

    if(stripos($cabeçalho, 'Set-Cookie:') === 0){
        if(preg_match('/Set-Cookie:\s?(.*?);/i', $cabeçalho, $matches)) {
            $cookie .= $matches[1] . '; ';
        }
    }

    return strlen($cabeçalho);
}

This will create a string, containing Nome=Valor;, but if you really want an object, simply change the REGEX and create the object OUTSIDE the function.

The idea is to pass the variable as a reference in &$cookie that will allow to obtain the result, ie:

function cookies()
{
    $request = curl_init();
    $cookie = new \stdClass();  // Inicia aqui fora

    curl_setopt_array($request, [
            CURLOPT_URL => 'SEU.SITE.COM',
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_NOBODY => true, // Você só precisa o header, não do corpo
            CURLOPT_PROTOCOLS => CURLPROTO_HTTPS, // Você só usa HTTPS, não STMP, por exemplo.
            CURLOPT_SSLVERSION => CURL_SSLVERSION_TLSv1_2, // A versão mais segura de TLS.
            CURLOPT_SSL_VERIFYHOST => 2, // Usar false é claramente inseguro.
            CURLOPT_SSL_VERIFYPEER => 1, // Usar false é claramente inseguro.
            CURLOPT_HEADERFUNCTION => function ($curl, $header) use (&$cookie) {
            // Estamos usando o `&$cookie` ou seja uma "referencia" a variável lá de fora.
                if (stripos($header, 'Set-Cookie:') === 0) {
                    if (preg_match('/^Set-Cookie: \s*([^=]*)=([^;]*)/i', $header, $matches)) {
                        $cookie->{$matches[1]} = $matches[2];
                    }
                }
                return strlen($header);
            }
        ]
    );

    $response = curl_exec($request);
    curl_close($request);

    return $cookie; // Retornamos aqui.
}

THE REGEX /^Set-Cookie: \s*([^=]*)=([^;]*)/i will do the job of picking up the name and value of the cookie, Isot will be added using:

$cookie->{$matches[1]} = $matches[2];

The $cookie is a reference (due to the use of (&$cookie)) at the $cookie = new \stdClass(); started in the first lines. Some other changes were made for security, if this is not important, which is common in PHP, just remove them.

  • Ta all right, but I wanted, that returns up for example: fm=0; and it’s returning me like this: public 'fm' => string '0' (length=1)

  • 1

    Ué, is returning just what you say you want in your post "Note: I need you to return me as follows:". If you want to access each value just do $seuscookies = cookie(); and then $seuscookies->fm. If you want to format all cookies, to keep everything together, use http_build_query($seuscookies, '', '; ', PHP_QUERY_RFC3986) . ';';, so everything will be the way "that now you want".

  • It worked. Thank you.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.