ファイルシステムのベストプラクティス


10

ファイルシステムからファイルを読み取る必要があるMagento 2拡張機能に取り組んでいます。
ECGM2標準を使用してphpスニファを実行すると、basenameまたはのような関数を使用しているという事実について文句を言いdirnameます。

関数dirname()の使用は禁止されています

または

関数basename()の使用は禁止されています

同じ効果を得るには、これらの代わりにどのラッパーを使用する必要がありますか?

[編集]
ここにいくつかのコードがありますが、質問にはそれほど関係ありません。
クラスを拡張するコレクションクラスがあり\Magento\Framework\Data\Collection\Filesystem、グリッド(ui-components)にこのコレクションを一覧表示したいのですが、グリッド内のアクションの1つはダウンロードアクションです。
このため、ファイルの実際の名前を取得して、ダウンロードアクションに送信できるようにする必要があります。

    // 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 2016年

いくつかのコードを追加しましたが、質問にはまったく関係ありません。質問はどういうわけか抽象的です。コードスニファが文句を言わないように、basenameの代わりに何を使用すればよいですか?
マリウス

許可の問題のように見えます。
Ashish Jagnani 2016年

権限とは関係ありません。コードは適切に動作しますが、コードスニッファーはbasenameそこで使用すべきではないと言っています。質問をよく読んでください。
マリウス

回答:


15

私も最近そのようなものが必要でした。唯一の解決策は私が取得することが判明basenameし、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'];
}

その前に私は使用Magento\Framework\Filesystem\Directory\WritegetDriver()てみましたが、成功しませんでした。それらを使用すると、ほとんどすべてを取得できますが、は取得できませんbasename


はい。それでおしまい。ありがとうございました。許可され次第、賞金を授与します。
マリウス

マリウスは本当にそのように実装するのですか?[\ Magento \ Framework \ Filesystem \ Io \ File-> getpathinfo] [1]は、文字通り[pathinfo] [2]のみを呼び出し、次に、basenameおよびdirname [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個の結果が表示されます。

私があなただったら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 を参照できます。
chirag

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\FileFactorygenerateBackupDownloadNameMagento\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バックアップモデルからいくつかのマジックゲッターを使用します。したがって、彼らは以前に呼ばれた魔法のセッターを持っている必要があります。basenameやそれに代わるものに関連するものは何もありません。
マリウス

@マリウスは、別の可能な方法についての私の最新の回答を参照してください
デジタルピアニズムのラファエル、

これはうまくいくかもしれません。私はそれを試して、結果を返します。
マリウス

@Marius collectFileInfoMagento\MediaStorage\Helper\File\Media;)からもチェック
Digital PianismのRaphael、2016年

collectFileInfoメディアフォルダー内のファイルを想定しているため、役に立ちません。私はvarフォルダーにあります。またgetStorageData、私が必要としていることとは何の関係もありません。フォルダ内のすべてのファイルを収集したくありません。すでにファイル名があります。
マリウス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.