ошибка интеллектуальной защиты в VS Code: ожидаемый тип ‘string’. Найдено ‘string[]’

#php #visual-studio-code #intelephense

Вопрос:

Предположим, что следующий фрагмент кода:

 <?php
declare (strict_types = 1);

define('SOURCE_PATH', 'C:xampphtdocsatlantisProductImages\');

$dest = explode('\', SOURCE_PATH);
$dest[count($dest) - 2] = 'ToUpload';
$dest = implode('\', $dest);

function transfer(string $file)
{
    global $dest;

    if (!@chdir($dest)) {
        mkdir($dest);
        chdir($dest);
    }

    // ...
}

function compress(string $path)
{
    global $dest;

    $zip = new ZipArchive();
    $zip->open(dirname($dest, 1) . '\' . explode('\', SOURCE_PATH)[count(explode('\', SOURCE_PATH)) - 2] . '.zip', ZipArchive::CREATE | ZipArchive::OVERWRITE);

    // ...
}
 

Итак, intelephense в VS Code продолжает жаловаться Expected type 'string'. Found 'string[]'. на все четыре экземпляра, которые я использую $dest в своих функциях…

Что не нравится intelephense в моем коде? Обратите внимание, что страница работает нормально… И что это за тип string[]? implode() возвращает строку, так в чем же проблема?

РЕДАКТИРОВАТЬ: скорее всего, это ошибка intelephense…

Я рассчитал $dest так:

$dest = dirname(SOURCE_PATH, 1) . 'ToUpload\';

что не связано explode() с редактированием, и действительно, ошибка исчезла… Так или иначе intelephense не учитывает, что implode() возвращает строку, а не массив…

На самом деле, я отправил сообщение об ошибке на github, и я жду ответа Mewburn на это … 🙂

Ответ №1:

Глобальные переменные могут быть немного шаткими в intelephense, проблема уже существует для улучшения поддержки. В этом конкретном случае выводимый тип определяется первым присваиванием. Поскольку это оператор explode, предполагается $dest , что это массив строк.

Для этого есть несколько решений:

  • Убедитесь, что в intelephense указан тип $dest с комментариями.
     function transfer(string $file)
    {
        /** @var string $dest */
        global $dest;
    }
     
  • Убедитесь, что первое присвоение $dest на самом деле является строкой:
     $tempdest = explode('\', SOURCE_PATH);
    $tempdest[count($tempdest) - 2] = 'ToUpload';
    $dest = implode('\', $dest);
     

Ответ №2:

Я думаю, это потому, что параметры implode были изменены.

https://www.php.net/manual/de/migration74.deprecated.php говорит следующее:

Implode с историческим порядком параметров Передача параметров в implode () в обратном порядке устарела, используйте implode($glue, $ parts) вместо implode($parts, $ glue) .