文件系统最佳实践


11

我正在开发一些需要从文件系统读取文件的Magento 2扩展程序。
当使用ECGM2标准运行php嗅探器时,它抱怨我正在使用类似basename或的功能dirname

禁止使用函数dirname()

要么

禁止使用函数basename()

我应该使用哪种包装代替那些包装以获得相同的效果?

[编辑]
这是一些代码,但与问题无关。
我有一个扩展\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 {
       ...
    }

您可以共享部分代码,还是尝试从系统读取文件。
Dhiren Vasoya

我添加了一些代码,但这与问题完全无关。这个问题有点抽象。我应该使用什么代替基本名,以便代码嗅探器不会抱怨?
马吕斯

它看起来仅像权限问题。
Ashish Jagnani '16

它与权限无关。该代码可以正常工作,但是嗅探器说不应basename在其中使用。请仔细阅读问题。
马吕斯

Answers:


18

最近我也需要类似的东西。我发现获得basenamedirname正在使用的唯一解决方案:

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

在此之前,我尝试使用Magento\Framework\Filesystem\Directory\Write并且getDriver()没有成功。有了它们,您几乎可以获得所有东西,但不能得到basename


是。而已。谢谢。我将尽快授予赏金。
马吕斯

Marius您真的要那样实施吗?[\ Magento \ Framework \ Filesystem \ Io \ File-> getpathinfo] [1]实际上仅调用[pathinfo] [2],后者依次调用基名和目录名[1]:github.com/magento/magento2/blob/develop/ LIB /内部/ Magento的/ ... [2]:github.com/php/php-src/blob/master/ext/standard/string.c#L1662
理查德

1
@理查德。我看到了。目前,我需要/想要避免某些功能。在我的特定情况下,它非常合适,因为我已经\Magento\Framework\Filesystem\Io\File在自己的类中为不同的功能注入了一个实例。我只是不了解这种getPathInfo方法。
马吕斯

3

幸运的是,git让我们看到了何时禁止 dirname和basename ,其原因很明显是“添加的文件”

查看ECG项目的问题,您会看到已关闭的问题,例如file_exists中的不良内容?#33错误功能#26此功能有问题吗?#17规则的上下文/解释#12禁止使用函数iconv()#14,这使我认为对禁用函数的初始列表没有过多考虑,并且magento可能可以更改禁止清单。

搜索m2代码库显示〜= 78个结果,其中包括basename,变量和实际调用basename的代码(包括我的最爱)的混合

我想如果我是您,我会在github上发布问题,并询问zlik他是否仍然认为它们属于该目录,或者M2是否提供包装器



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\FileFactorygenerateBackupDownloadName从中下载文件Magento\Backup\Helper\Data(注意建议使用OM;))

另一个有趣的地方

您应该查看的另一件有趣的事情是它自身直接调用的getStorageData方法,但是如果您在模块中调用该核心方法,则不会得到禁止的错误;)Magento\MediaStorage\Model\ResourceModel\File\Storage\Filedirnamebasename

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以另一种可能的方式查看我的更新答案
Raphael在Digital Pianism

这可能有效。我将尝试一下,然后返回结果。
马吕斯

@Marius还collectFileInfo从以下位置进行检查Magento\MediaStorage\Helper\File\Media;)
拉斐尔(Raphael)在Digital Pianism上16/11/14

collectFileInfo不会帮我,因为它需要媒体文件夹中的文件。我的在var文件夹中。也getStorageData与我所需要的无关。我不想收集文件夹中的所有文件。我已经有了文件名。
马吕斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.