Praktik terbaik filesystem

11

Saya sedang mengerjakan beberapa ekstensi Magento 2 yang membutuhkan membaca file dari sistem file.
Saat menjalankan sniffer php menggunakan standar ECGM2, ia mengeluh tentang fakta bahwa saya menggunakan fungsi seperti basenameatau dirname.

Penggunaan fungsi dirname () dilarang

atau

Penggunaan fungsi basename () dilarang

Wrapper apa yang harus saya gunakan dan bukan untuk mendapatkan efek yang sama?

[EDIT]
Berikut ini beberapa kode, tetapi tidak relevan dengan pertanyaan itu.
Saya memiliki kelas koleksi yang memperluas \Magento\Framework\Data\Collection\Filesystemkelas dan saya ingin mendaftar koleksi ini dalam kotak (ui-komponen) dan salah satu tindakan dalam kotak adalah tindakan mengunduh.
Untuk ini, saya perlu mendapatkan nama file yang sebenarnya sehingga saya dapat mengirimkannya ke tindakan unduhan.

    // 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 {
       ...
    }
Marius
sumber
dapatkah Anda membagikan bagian dari kode Anda, apa yang Anda coba baca file dari sistem.
Dhiren Vasoya
Saya menambahkan beberapa kode, tetapi sama sekali tidak relevan untuk pertanyaan itu. Pertanyaannya entah bagaimana abstrak. apa yang harus saya gunakan daripada nama merek sehingga sniffer kode tidak mengeluh?
Marius
Sepertinya masalah izin saja.
Ashish Jagnani
Itu tidak ada hubungannya dengan izin. Kode berfungsi dengan baik, tetapi sniffer kode mengatakan bahwa tidak boleh digunakan basenamedi sana. Silakan baca pertanyaan dengan seksama.
Marius

Jawaban:

17

Saya juga membutuhkan sesuatu seperti itu baru-baru ini. Satu-satunya solusi yang saya temukan basenamedan dapatkan dirname:

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

Sebelumnya saya mencoba menggunakan Magento\Framework\Filesystem\Directory\Writedan getDriver()tidak berhasil. Dengan mereka Anda bisa mendapatkan hampir semuanya tetapi tidak basename.

Jalogut
sumber
IYA. Itu dia. Terima kasih. Saya akan memberi hadiah itu begitu saya diizinkan.
Marius
Marius apakah Anda benar-benar akan menerapkannya seperti itu? [\ Magento \ Framework \ Filesystem \ Io \ File-> getpathinfo] [1] secara harfiah hanya memanggil [pathinfo] [2] yang pada gilirannya memanggil nama dan nama panggilan [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. Saya melihat bahwa. Untuk saat ini saya perlu / ingin menghindari fungsi-fungsi tertentu. Dan dalam kasus khusus saya cocok karena saya sudah memiliki instance yang \Magento\Framework\Filesystem\Io\Filedisuntikkan di kelas saya sendiri untuk fungsi yang berbeda. Saya hanya tidak tahu di muka tentang getPathInfometode ini.
Marius
3

Untungnya git memungkinkan kita melihat kapan dirname dan nama bas dilarang , alasannya jelas, "File yang ditambahkan"

Melihat masalah untuk proyek EKG Anda dapat melihat masalah tertutup seperti sesuatu yang buruk di file_exists? # 33 , Fungsi Kesalahan # 26 , ada sesuatu yang buruk dalam fungsi ini? # 17 , Konteks / Penjelasan untuk Aturan # 12 , Penggunaan iconv fungsi () dilarang # 14 yang akan membuat saya berpikir bahwa daftar awal fungsi terlarang tidak terlalu dipertimbangkan, dan magento mungkin bisa diubah daftar terlarang.

Mencari basis kode m2 menunjukkan ~ = 78 hasil untuk nama bas, campuran variabel dan kode yang memanggil nama bas, termasuk favorit saya .

Saya pikir jika saya adalah Anda, saya akan memposting masalah di github dan bertanya pada Zlik apakah dia masih berpikir mereka termasuk di sana atau jika M2 menyediakan pembungkus

Richard
sumber
2

Anda dapat menggunakan objek SplFileInfo()kelas mungkin itu akan berhasil.

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

mungkin itu akan berhasil.

Anda juga dapat merujuk url ini .

chirag
sumber
Terima kasih untuk ini. Ini terlihat lebih bersih, tetapi apakah Anda memiliki contoh kode yang melakukan ini? Saya ingin mengikuti standar inti.
Marius
Anda dapat merujuk php.net/manual/en/splfileinfo.getfilename.php url ini.
chirag
2

Saran saya adalah menggunakan Magento/Backupmodul sebagai contoh.

Cara kelas tindakan unduhan ditulis akan menarik untuk dilihat karena juga berkaitan dengan file nyata untuk diunduh:

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

Bagi saya, Anda harus melihat cara metode ini menghasilkan file untuk diunduh menggunakan \Magento\Framework\App\Response\Http\FileFactorydan generateBackupDownloadNamedari Magento\Backup\Helper\Data(perhatikan penggunaan OM yang direkomendasikan;))

Bagian lain yang menarik

Hal lain yang menarik yang harus Anda perhatikan adalah getStorageDatametode dari Magento\MediaStorage\Model\ResourceModel\File\Storage\Filemana ia memanggil langsung dirnamedan basenametetapi jika Anda memanggil metode inti dalam modul Anda, Anda tidak akan mendapatkan kesalahan terlarang;)

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

Dalam ide yang sama, ada juga yang collectFileInfodariMagento\MediaStorage\Helper\File\Media

Raphael di Digital Pianism
sumber
generateBackupDownloadNamemenggunakan beberapa getter ajaib dari model cadangan. Jadi mereka harus memiliki setter sihir yang dipanggil sebelumnya. Saya tidak melihat apa pun yang terkait dengan nama merek atau alternatifnya.
Marius
@Marius lihat jawaban saya yang diperbarui untuk cara lain yang memungkinkan
Raphael di Digital Pianism
Ini bisa berhasil. Saya akan mencobanya dan kembali dengan hasilnya.
Marius
@Marius juga memeriksa collectFileInfodari Magento\MediaStorage\Helper\File\Media;)
Raphael di Digital Pianism
collectFileInfotidak akan membantu saya karena mengharapkan file di dalam folder media. Milik saya ada di dalam folder var. Juga getStorageDatatidak ada hubungannya dengan apa yang saya butuhkan. Saya tidak ingin mengumpulkan semua file dalam folder. Saya sudah memiliki nama file.
Marius