Передовий досвід роботи з файловою системою


11

Я працюю над розширенням Magento 2, яке вимагає зчитування файлів з файлової системи.
Під час запуску php sniffer з використанням стандартів ECGM2 він скаржиться на те, що я використовую такі функції, як basenameабо dirname.

Використання функції dirname () заборонено

або

Використання базової функції функції () заборонено

Яку обгортку я повинен використовувати замість тих, щоб отримати той самий ефект?

[EDIT]
Ось якийсь код, але це не так важливо для питання.
У мене є клас колекції, який розширює \Magento\Framework\Data\Collection\Filesystemклас, і я хочу перерахувати цю колекцію в сітці (ui-компоненти), і одне з дій у сітці - це дія завантаження.
Для цього мені потрібно отримати власне ім’я файлу, щоб я міг надіслати його до дії завантаження.

    // here $file is dynamic and it can be
    // folder/filename.xml or folder/subfolder/file.tar.gz
    //so there is no strict number of folders and subfolders.
    $file = $downloader->getRelativePath($packageName);
    $relativeFile = UmcFilesystem::VAR_DIR_NAME . '/' .$file;
    $absoluteFile = $rootDir->getAbsolutePath($relativeFile);
    if ($rootDir->isFile($relativeFile) && $rootDir->isReadable($relativeFile)){
        //I don't want to use `explode` just for the sake of avoiding basename
        $fileName = basename($absoluteFile);
        $this->fileFactory->create(
            $fileName,
            null,
            DirectoryList::VAR_DIR,
            'application/octet-stream',
            $rootDir->stat($relativeFile)['size']
        );

        $resultRaw = $this->resultRawFactory->create();
        $resultRaw->setContents($rootDir->readFile($relativeFile));
        return $resultRaw;
    } else {
       ...
    }

Ви можете поділитися частиною свого коду, що ви спробували прочитати файл із системи.
Дхірен Васоя

Я додав код, але це питання абсолютно не має значення. Питання якось абстрактне. що я повинен використовувати замість базового імені, щоб sniffer коду не скаржився?
Маріус

Це виглядає як видача дозволу.
Ashish Jagnani

Це не має нічого спільного з дозволами. Код працює належним чином, але sniffer коду каже, що він не повинен використовуватись basenameтам. Будь ласка, уважно прочитайте питання.
Маріус

Відповіді:


18

Нещодавно мені теж було потрібно щось подібне. Єдине рішення, яке я знайшов basenameі dirnameвикористовував:

\ Magento \ Framework \ файлова система \ Io \ Файл

protected function someFunction()
{
    /** @var \Magento\Framework\Filesystem\Io\File $fileSystemIo **/
    $fileInfo = $this->fileSystemIo->getPathInfo('<absolutePath>');
    $basename = $fileInfo['basename'] 
    $dirname = $fileInfo['dirname'];
}

До цього я намагався використовувати Magento\Framework\Filesystem\Directory\Writeі getDriver()не мав успіху. З ними ви можете отримати майже все, але не те basename.


ТАК. Це воно. Дякую. Я вручу нагороду, як тільки мені дозволять.
Маріус

Маріус, ти справді збираєшся реалізувати це таким чином? [\ Magento \ Framework \ Filesystem \ Io \ File-> getpathinfo] [1] буквально викликає лише [pathinfo] [2], який, у свою чергу, називає базове ім'я та ім’я dirname [1]: github.com/magento/magento2/blob/develop/ lib / Internal
Річард

1
@Richard. Я побачив, що. Наразі мені потрібно / хочу уникати певних функцій. І в моєму конкретному випадку це добре підходить, тому що я вже мав екземпляр \Magento\Framework\Filesystem\Io\Fileвведеного в свій клас для іншої функціональності. Я просто не знав наперед про getPathInfoметод.
Маріус

3

На щастя, git дозволяє нам побачити, коли dirname та basename були заборонені , причина - "Додані файли"

Дивлячись на проблему проекту ЕКГ, ви можете побачити закриті проблеми, такі як щось погане у file_exists? № 33 , функції помилок №26 , щось погано в цих функціях? # 17 , Контекст / Пояснення Правил №12 , Використання функції iconv () заборонено # 14, що б змусило мене думати, що в початковому списку заборонених функцій не було занадто багато уваги, і магенто, ймовірно, піддається зміні список заборонених

Пошук у кодовій базі м2 показує ~ = 78 результатів для базової назви, суміші змінних та коду, що фактично викликає базове ім'я, включаючи моє улюблене .

Я думаю, якби я був ти, я опублікував би проблему на github і запитав zlik, чи все ще він вважає, що вони там належать, або якщо M2 надає обгортку


2

Ви можете використовувати об'єкт SplFileInfo()класу, він може працювати.

$info = new SplFileInfo('/path/to/foo.txt');
var_dump($info->getFilename())

можливо, це спрацює.

Ви також можете посилатися на цю URL-адресу.


Дякую за це Це виглядає чистіше, але чи є у вас приклад коду, який це робить? Я хочу дотримуватися основних стандартів.
Маріус

ви можете посилатись на php.net/manual/en/splfileinfo.getfilename.php за цією URL-адресою.
чіраг

2

Моя пропозиція буде використовувати Magento/Backupмодуль як приклад.

Спосіб написання класу дій для завантаження було б цікаво подивитися, оскільки він також має справу з реальними файлами для завантаження:

public function execute()
{
    /* @var $backup \Magento\Backup\Model\Backup */
    $backup = $this->_backupModelFactory->create(
        $this->getRequest()->getParam('time'),
        $this->getRequest()->getParam('type')
    );

    if (!$backup->getTime() || !$backup->exists()) {
        /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */
        $resultRedirect = $this->resultRedirectFactory->create();
        $resultRedirect->setPath('backup/*');
        return $resultRedirect;
    }

    $fileName = $this->_objectManager->get('Magento\Backup\Helper\Data')->generateBackupDownloadName($backup);

    $this->_fileFactory->create(
        $fileName,
        null,
        DirectoryList::VAR_DIR,
        'application/octet-stream',
        $backup->getSize()
    );

    /** @var \Magento\Framework\Controller\Result\Raw $resultRaw */
    $resultRaw = $this->resultRawFactory->create();
    $resultRaw->setContents($backup->output());
    return $resultRaw;
}

Мені слід поглянути на те, як цей метод генерує файл для завантаження за допомогою \Magento\Framework\App\Response\Http\FileFactoryта generateBackupDownloadNameз Magento\Backup\Helper\Data(зверніть увагу на рекомендоване використання OM;))

Ще один цікавий шматочок

Ще одна цікава річ , яку ви повинні дивитися на це getStorageDataметод з Magento\MediaStorage\Model\ResourceModel\File\Storage\Fileяких сам по собі викликає безпосередньо dirnameі , basenameале якщо ви викликати цей метод ядра в модулі, ви не отримаєте заборонені помилки;)

public function getStorageData($dir = '/')
{
    $files = [];
    $directories = [];
    $directoryInstance = $this->_filesystem->getDirectoryRead(DirectoryList::MEDIA);
    if ($directoryInstance->isDirectory($dir)) {
        foreach ($directoryInstance->readRecursively($dir) as $path) {
            $itemName = basename($path);
            if ($itemName == '.svn' || $itemName == '.htaccess') {
                continue;
            }
            if ($directoryInstance->isDirectory($path)) {
                $directories[] = [
                    'name' => $itemName,
                    'path' => dirname($path) == '.' ? '/' : dirname($path),
                ];
            } else {
                $files[] = $path;
            }
        }
    }

    return ['files' => $files, 'directories' => $directories];
}

У подібній ідеї є також і collectFileInfoзMagento\MediaStorage\Helper\File\Media


generateBackupDownloadNameвикористовує деякі магічні геттери з резервної моделі. Тому вони повинні мати чарівних сетерів, які раніше називались. Я не бачу нічого, пов’язаного з базовим іменем або альтернативою.
Маріус

@Marius дивіться мою оновлену відповідь ще одним можливим способом
Рафаель у Digital Pianism

Це могло б спрацювати. Я спробую і повернусь з результатами.
Маріус

@Marius також перевірити collectFileInfoз Magento\MediaStorage\Helper\File\Media;)
Рафаель в цифровому піанізму

collectFileInfoне допоможе мені, оскільки він очікує, що файл знаходиться в папці медіа. Шахта знаходиться в папці var. Також не getStorageDataмає нічого спільного з тим, що мені потрібно. Я не хочу збирати всі файли в папці. У мене вже є ім'я файлу.
Маріус
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.