skip to Main Content

This works without any warnings in every version of PHP except 8

I think they have changed something with implode and I have tried all the examples to no avail.

Perhaps I could get this done some other way. I need some PHP 8 eyes as I’m very new to PHP 8 and up.

The warning in my function is on the following line:

Warning: array to string conversion

  $test = implode(', ', $data);

It is very hard to make sense of certain things when you use so many different languages with similar syntax. I fear that this is just a minor brain fart on my part.

This code appears to be working all though I have the warning, I am wondering if this is just a bug in PHP 8 and 8.1 etc

function deepPurifier($data) 
{
    global $html_auth, $admin;

    static $config, $purifier;

    # Error check
    if(empty($data) || !isset($data))       
    return $data;

    if(!is_array($data))   
    return stripslashes((string) $data);
    
    // THIS IS WHERE MY WARNING IS
    // warning: array to string conversion 
    $test = implode(', ', $data);

    if(!preg_match('[<|>]', $test)) 
    {
        return $data;
    }
    
    if(!isset($config) || empty($config)) 
    {
        set_include_path(NUKE_BASE_DIR. get_include_path() );
        require_once(NUKE_VENDOR_DIR.'ezyang/htmlpurifier/library/HTMLPurifier/Bootstrap.php'); 
        require_once(NUKE_VENDOR_DIR.'ezyang/htmlpurifier/library/HTMLPurifier.autoload.php');      
        $config = HTMLPurifier_Config::createDefault();
        $config->set('Core.Encoding', 'UTF-8');
        $config->set('HTML.Doctype', 'HTML 4.01 Transitional');
        if(!is_god($admin) || (is_god($admin) && !$html_auth)) 
        {
            $config->set('HTML.Trusted', true);
            $config->set('HTML.SafeObject', true);
            $config->set('HTML.SafeEmbed', true);
            $config->set('HTML.AllowedAttributes','img@height,img@width,img@src,iframe@src,iframe@allowfullscreen');
            $config->set('HTML.AllowedAttributes', 'src, height, width, alt');
            $config->set('HTML.AllowedElements', ['img', 'iframe', 'div', 'script', 'object', 'p', 'span', 'pre', 'b', 'i', 'u', 'strong', 'em', 'sup', 'a', 'img', 'table', 'tr', 'td', 'tbody', 'thead', 'param']);
            $config->set('Output.FlashCompat', true);
            $config->set('Attr.EnableID', true);
            $config->set('Filter.Custom', [new HTMLPurifier_Filter_YouTube()]);
         }
        $def = $config->getHTMLDefinition(true);
        $def->addAttribute('iframe', 'allowfullscreen', 'Bool');
        $purifier = new HTMLPurifier($config);
    }
 # Loop through the data
 foreach ($data as $k => $v) {
         # If its an array
        if (is_array($data[$k])) {
            # Go though this function again
            $data[$k] = array_map('deepStrip', $data[$k]);
        } elseif (is_numeric($v) || empty($v)) {
            $data[$k] = $v;
         } else {
            if (isset($_GET['op']) && $_GET['op'] == 'Configure' && isset($_GET['sub']) && $_GET['sub'] == '11') {
                $data[$k] = $v;
                continue;
            } elseif ($k == 'xsitename' || $k == 'xslogan') {
                $data[$k] = $v;
                continue;
            } elseif (isset($_GET['name'])) {
                # If forum post let it pass to the forum html security
                if ($_GET['name'] == 'Forums' && (isset($_GET['file']) && ($_GET['file'] == 'posting')) && ($k == 'message' || $k == 'subject')) {
                     $data[$k] = $v;
                     continue;
                }
                # If PM let it pass to the forum html security
                if ($_GET['name'] == 'Private_Messages' && ($k == 'message' || $k == 'subject')) {
                     $data[$k] = $v;
                     continue;
                }
                # If SIG let it pass to the forum html security
                if ($_GET['name'] == 'Profile' && (isset($_GET['mode']) && ($_GET['mode'] == 'signature')) && $k == 'signature') {
                    $data[$k] = $v;
                    continue;
                }
            }
            # If its a strip lets purify it
            if (!is_god($admin) || (is_god($admin) && !$html_auth)) {
                    $data[$k] = $purifier->purify($v);
                }
            $data[$k] = str_replace('n', "n", (string) $data[$k]);
            # Get the registered globals also
            global ${$k};
            if (isset(${$k}) && !empty(${$k})) {
                ${$k} = $data[$k];
             }
         }
     }
    return $data;
}

var_dump($test);

string(20) "Forums,viewtopic,284" string(20) "Forums,viewtopic,284"

2

Answers


  1. Chosen as BEST ANSWER

    To get rid of the warning you must change the following:

    From:

    $test = implode(',', $data);
    

    To:

    $test  = json_encode($data);
    

    Also Change Improper Syntax:

    From:

        if(!preg_match('[<|>]', $test)) 
        {
            return $data;
        }
    

    To:

        if(!preg_match('/[<|>]/', $test)) 
        {
            return $data;
        }
    

  2. The warning appears in PHP 8 when the array being imploded is nested. From the docs, the $array argument should be an array of strings, not an array of arrays.

    For example, the following produces no warnings in both PHP 7.4 and PHP 8.1:

    $data = ["a", "b"];
    print(implode(" ", $data));
    

    Whereas the following gives the warning Array to string conversion (note the arrays within the first array):

    $data = ["a", "b" => ["c"], "d" => ["e"]];
    print(implode(" ", $data));
    

    You can verify the behaviour with docker and different PHP versions:

    docker run --rm php:7.4 -r 'print(implode(" ", ["a", "b" => ["c"], "d" => ["e"]]));'
    docker run --rm php:8.1 -r 'print(implode(" ", ["a", "b" => ["c"], "d" => ["e"]]));'
    

    Both produce the output:

    a Array Array
    

    But PHP 8 will now raise warnings:

    Warning: Array to string conversion in Command line code on line 1
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search