phppreg-matchstrpos

PHP search for string in $variable and extract the next x characters


I need to extract the cookie time from a cookie when a user visits the page. The cookie text will be stored in a variable. I'm pretty sure I can do this with preg_match or maybe strpos but I'm not sure how to structure the code. I'd appreciate any help.

The cookie text will look like this...

09/02-13:05 : Array
(
    [_fbp] => fb.1.1739106196697.235924611659269905
    [_fbc] => fb.1.1739106196727.IwZXh0bgNhZW0CMTAAAR3y6z47O2mW29lM1GoX2fijs4oYAehPYgcoxpSO2FiCv60XMF8MnxgSOJk_aem_KYAWfzaaJNjl06suPL6ExA
    [_ga] => GA1.1.765488705.1739106207
    [hash] => 96f5de6147cb0fdfbbcd97e7fb074294
    [user] => 51895204
)

I want to return the 1739106196727 number from the line which starts with [_fbc]. This doesn't always appear in the 2nd line of the array.

Thanks


Solution

  • $_COOKIE is an array, so you can access the entry with its key. But the cookie may not be present, so you also have to check if it's there or not.

    First, the regex to extract it: ^fb\.\d\.(\d+)

    Secondly, depending what you want to do with this number, you may want to convert it from string to integer. Be aware that this number is longer than an integer on a 32 bit system. So to be sure, check this before conversion.

    Here's the PHP code I would use (here, I just did some prints in the console, but you'll probably do something else with it):

    <?php
    
    $_COOKIE = [
        '_fbp' => 'fb.1.1739106196697.235924611659269905',
        '_fbc' => 'fb.1.1739106196727.IwZXh0bgNhZW0CMTAAAR3y6z47O2mW29lM1GoX2fijs4oYAehPYgcoxpSO2FiCv60XMF8MnxgSOJk_aem_KYAWfzaaJNjl06suPL6ExA',
        '_ga' => 'GA1.1.765488705.1739106207',
        'hash' => '96f5de6147cb0fdfbbcd97e7fb074294',
        'user' => 51895204
    ];
    
    // If the _fbc cookie is present.
    if (isset($_COOKIE['_fbc'])) {
        // Try to extract the second number after "fb.1." (assuming 1 could be another digit).
        if (preg_match('/^fb\.\d\.(\d+)/i', $_COOKIE['_fbc'], $match)) {
            printf('$match = ' . var_export($match, true) . PHP_EOL);
    
            // On 32 bit PHP, max int val is 2147483647.
            // On 64 bit PHP, max int val is 9223372036854775807.
            // The desired number is 1739106196727, which is higher than the max 32 bit value.
            // So up to you to see if you want to keep it as a string, or convert it to
            // an int number or a float number.
            $number = intval($match[1]);
            
            if (0 < $number && $number < PHP_INT_MAX)
                printf('The desired number is %d' . PHP_EOL, $number);
            else {
                printf('ERROR: "%s" is out of the integer range!' . PHP_EOL, $match[1]);
                printf('       PHP_INT_SIZE = %d bytes, so max value is %d' . PHP_EOL, PHP_INT_SIZE, PHP_INT_MAX);
                printf('       Keep it as a string or save it as a float (with some risk).' . PHP_EOL);
            }
        } else {
            printf('ERROR: Could not find the desired number in the cookie!' . PHP_EOL);
        }
    }
    else {
        printf('ERROR: The _fbc cookie does not exist!' . PHP_EOL);
    }
    

    Execution output:

    $match = array (
      0 => 'fb.1.1739106196727',
      1 => '1739106196727',
    )
    The desired number is 1739106196727
    

    You can test it here: https://onlinephp.io/c/7cff3

    Caution with other methods

    You mentionned in your comment below that you finally used this piece of PHP:

    extract($_COOKIE);
    $fbc = $_fbc;
    

    This is very dangerous, because the $_COOKIE array is sent by the customer, who is anybody, including a potential attacker.

    Imagine that your code is having a $user variable containing "James". You would like to print it in your HTML output. But, bad luck, you are receiving the cookie user (which is already the case in your example). So instead of printing "Hello James", you'll print "Hello 51895204".

    Now, if you receive a cookie called _COOKIE, _GET or _SERVER, the extract() operation will ovewrite the global variables, leading to big problems.

    The $_COOKIE array can contain anything. Cookies can be created by JavaScript code in the browser or sent in the HTTP request with many available browser extensions (tamper, request editors, cookie editors).

    A safer alternative to extract() is array destructuring:

    ['_fbc' => $fbc] = $_COOKIE;
    

    This will create a variable called $fbc with the value of the entry _fbc of your $_COOKIE array.

    But the problem is that you'll get a warning if the key doesn't exist. This is why I used isset($_COOKIE['_fbc']) to check that it exists.

    Conclusion