Najlepsze praktyki systemu plików


11

Pracuję nad jakimś rozszerzeniem Magento 2, które wymaga odczytu plików z systemu plików.
Podczas uruchamiania sniffera php przy użyciu standardów ECGM2 narzeka on na fakt, że używam funkcji takich jak basenamelub dirname.

Używanie funkcji dirname () jest zabronione

lub

Korzystanie z funkcji basename () jest zabronione

Jakiego opakowania należy użyć zamiast tych, aby uzyskać ten sam efekt?

[EDYCJA]
Oto trochę kodu, ale nie jest tak istotny dla pytania.
Mam klasę kolekcji, która ją rozszerza \Magento\Framework\Data\Collection\Filesystemi chcę wyświetlić tę kolekcję w siatce (komponenty interfejsu użytkownika), a jedną z akcji w siatce jest akcja pobierania.
W tym celu muszę uzyskać rzeczywistą nazwę pliku, aby móc wysłać go do akcji pobierania.

    // 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 {
       ...
    }

czy możesz udostępnić część kodu, co próbujesz odczytać plik z systemu.
Dhiren Vasoya

Dodałem trochę kodu, ale nie ma to znaczenia dla pytania. Pytanie jest w jakiś sposób abstrakcyjne. czego powinienem używać zamiast basename, aby sniffer kodu nie narzekał?
Marius

Wygląda jak tylko kwestia uprawnień.
Ashish Jagnani

Nie ma to nic wspólnego z uprawnieniami. Kod działa poprawnie, ale sniffer kodu mówi, że nie należy go basenametam używać . Przeczytaj uważnie pytanie.
Marius

Odpowiedzi:


18

Potrzebowałem też czegoś takiego ostatnio. Jedyne rozwiązanie, które znalazłem basenamei dirnameużywałem:

\ Magento \ Framework \ Filesystem \ Io \ File

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

Wcześniej próbowałem używać Magento\Framework\Filesystem\Directory\Writei getDriver()bez powodzenia. Dzięki nim możesz uzyskać prawie wszystko, ale nie basename.


TAK. Otóż ​​to. Dziękuję Ci. Przyznam nagrodę, gdy tylko będę mógł.
Marius

Marius, czy naprawdę zamierzasz to tak wdrożyć? [\ Magento \ Framework \ Filesystem \ Io \ File-> getpathinfo] [1] dosłownie wywołuje tylko [pathinfo] [2], który z kolei wywołuje basename i dirname [1]: github.com/magento/magento2/blob/develop/ lib / internal / Magento /… [2]: github.com/php/php-src/blob/master/ext/standard/string.c#L1662
Richard

1
@Richard. Widziałem to. Na razie potrzebuję / chcę uniknąć niektórych funkcji. A w moim konkretnym przypadku pasuje to ładnie, ponieważ miałem już instancję \Magento\Framework\Filesystem\Io\Filewstrzykniętą we własnej klasie dla innej funkcjonalności. Po prostu nie wiedziałem z góry o getPathInfometodzie.
Marius

3

Na szczęście git pozwala nam zobaczyć, kiedy dirname i basename były zabronione , powód jest wyraźnie „Dodane pliki”

Patrząc na problem dotyczący projektu EKG, możesz zobaczyć zamknięte problemy, takie jak coś złego w pliku_istniejące? # 33 , Funkcje błędów # 26 , coś złego w tych funkcjach? # 17 , Kontekst / objaśnienia do reguł # 12 , Zabronione jest użycie funkcji iconv () # 14, co sprawiłoby, że pomyślałem, że początkowa lista zabronionych funkcji nie była zbytnio rozważana, a Magento prawdopodobnie można zmienić zabroniona lista.

Przeszukiwanie bazy kodu m2 pokazuje ~ = 78 wyników dla nazwy basename, mieszanki zmiennych i kodu faktycznie wywołującego basename, w tym mojego ulubionego .

Myślę, że gdybym był tobą, opublikowałbym problem na githubie i zapytał Zlik, czy nadal uważa, że ​​one tam są, czy M2 zapewnia opakowanie


2

Możesz użyć obiektu SplFileInfo()klasy, może to zadziała.

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

być może zadziała.

możesz również skierować ten adres URL.


Dzięki za to. Wygląda na czystsze, ale czy masz przykład kodu, który to robi? Chcę przestrzegać podstawowych standardów.
Marius


2

Moją sugestią byłoby użycie Magento/Backupmodułu jako przykładu.

Ciekawie byłoby zobaczyć, w jaki sposób napisano klasę działania pobierania, ponieważ dotyczy ona również rzeczywistych plików do pobrania:

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;
}

Do mnie należy spojrzeć na sposób metoda ta generuje plik do pobrania przy użyciu \Magento\Framework\App\Response\Http\FileFactoryi generateBackupDownloadNameod Magento\Backup\Helper\Data(powiadomienia zalecanego użycia OM;))

Kolejny interesujący kawałek

Inną ciekawą rzeczą, należy spojrzeć na to getStorageDatametoda z Magento\MediaStorage\Model\ResourceModel\File\Storage\Filektórych sam nazywa bezpośrednio dirnamei basenametylko jeśli wywołanie tej metody rdzenia w module, nie dostanie zabronione błędy;)

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];
}

W podobnym pomyśle jest też coś collectFileInfozMagento\MediaStorage\Helper\File\Media


generateBackupDownloadNamewykorzystuje niektóre magiczne metody pobierania z modelu zapasowego. Więc muszą wcześniej wezwać seterów magii. Nie widzę nic związanego z basename ani alternatywy dla niego.
Marius

@Marius zobacz moją zaktualizowaną odpowiedź na inny możliwy sposób
Raphael w Digital Pianism

To może zadziałać. Spróbuję i wrócę z wynikami.
Marius

@Marius również sprawdzić collectFileInfood Magento\MediaStorage\Helper\File\Media;)
Raphael w Digital Pianism

collectFileInfonie pomoże mi, ponieważ oczekuje pliku w folderze multimediów. Mój jest w folderze var. Nie getStorageDatama też nic wspólnego z tym, czego potrzebuję. Nie chcę zbierać wszystkich plików w folderze. Mam już nazwę pliku.
Marius
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.