แนวทางปฏิบัติที่ดีที่สุดของระบบไฟล์


11

ฉันกำลังทำงานกับส่วนขยายของ Magento 2 ที่ต้องอ่านไฟล์จากระบบไฟล์
เมื่อใช้ PHP ดมกลิ่นโดยใช้มาตรฐาน ECGM2 ก็บ่นเกี่ยวกับความจริงที่ว่าฉันใช้ฟังก์ชั่นเหมือนหรือ basenamedirname

ห้ามใช้ฟังก์ชั่น dirname ()

หรือ

ห้ามใช้งานฟังก์ชันพื้นฐาน ()

ฉันควรใช้ wrapper แบบไหนเพื่อให้ได้เอฟเฟกต์เดียวกัน

[แก้ไข]
นี่คือรหัสบางส่วน แต่ไม่เกี่ยวข้องกับคำถาม
ฉันมีคลาสคอลเล็กชันที่ขยาย\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

ฉันเพิ่มรหัสแล้ว แต่มันไม่เกี่ยวข้องกับคำถามทั้งหมด คำถามเป็นนามธรรมอย่างใด สิ่งที่ฉันควรใช้แทนชื่อรหัสฐานเพื่อให้รหัสดมกลิ่นไม่บ่น?
Marius

ดูเหมือนว่าปัญหาการอนุญาตเท่านั้น
Ashish Jagnani

มันไม่มีส่วนเกี่ยวข้องกับการอนุญาต รหัสทำงานอย่างถูกต้อง แต่รหัสดมกลิ่นบอกว่าไม่ควรใช้basenameในที่นั่น โปรดอ่านคำถามอย่างระมัดระวัง
Marius

คำตอบ:


18

ฉันต้องการบางสิ่งเช่นนั้นเมื่อเร็ว ๆ นี้ ทางออกเดียวที่ฉันพบเพื่อรับbasenameและdirnameใช้:

\ วีโอไอพี \ Framework \ Filesystem \ ไอโอ \ ไฟล์

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

Marius คุณจะใช้มันอย่างนั้นจริงหรือ [\ Magento \ Framework \ Filesystem \ Io \ File-> getpathinfo] [1] แท้จริงเรียกเท่านั้น [pathinfo] [2] ซึ่งจะเรียก basename และ 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 ผมเห็นว่า. ตอนนี้ฉันต้องการ / ต้องการหลีกเลี่ยงฟังก์ชั่นบางอย่าง และในกรณีเฉพาะของฉันมันเหมาะอย่างยิ่งเพราะฉันมีตัวอย่างของการ\Magento\Framework\Filesystem\Io\Fileฉีดในชั้นเรียนของฉันเองสำหรับฟังก์ชั่นที่แตกต่างกัน ฉันไม่ทราบล่วงหน้าเกี่ยวกับgetPathInfoวิธีการ
Marius

3

โชคดีที่คอมไพล์ให้เราดูเมื่อมีการห้ามใช้ชื่อเล่นและชื่อเบสเหตุผลก็ชัดเจน "เพิ่มไฟล์"

หากมองปัญหาของโครงการ ECG คุณสามารถเห็นปัญหาที่ปิดเช่นสิ่งที่ไม่ดีใน file_exists หรือไม่ # 33 , ฟังก์ชั่นข้อผิดพลาด # 26 , บางสิ่งบางอย่างที่ไม่ดีในฟังก์ชั่นนี้หรือไม่? # 17 , บริบท / คำอธิบายสำหรับกฎ # 12 , การใช้ function iconv () ถูกห้าม # 14ซึ่งจะทำให้ฉันคิดว่ารายการเริ่มต้นของฟังก์ชันที่ต้องห้ามไม่ได้รับการพิจารณามากเกินไปและ magento อาจคล้อยตามการเปลี่ยนแปลง รายการที่ต้องห้าม

ค้นหาm2 codebaseแสดงผล ~ = 78 basename ผสมของตัวแปรและรหัสที่จริงเรียก basename รวมทั้งของฉันชื่นชอบ

ฉันคิดว่าถ้าฉันเป็นคุณฉันจะโพสต์ปัญหาใน github และถาม zlik ว่าเขายังคิดว่าพวกเขาอยู่ที่นั่นหรือถ้า M2 ให้เสื้อคลุม


2

คุณสามารถใช้วัตถุของSplFileInfo()คลาสได้

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

อาจจะใช้งานได้

คุณยังสามารถดูนี้ URL


ขอบคุณสำหรับสิ่งนี้. มันดูสะอาดกว่า แต่คุณมีตัวอย่างของรหัสที่ทำสิ่งนี้หรือไม่? ฉันต้องการที่จะปฏิบัติตามมาตรฐานหลัก
Marius

คุณสามารถอ้างอิงphp.net/manual/th/splfileinfo.getfilename.php URL นี้
chirag

2

ข้อเสนอแนะของฉันจะใช้Magento/Backupโมดูลเป็นตัวอย่าง

วิธีเขียนคลาส action download น่าสนใจที่จะดูเพราะมันเกี่ยวข้องกับไฟล์จริงที่จะดาวน์โหลด:

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ใช้ magic getters จากโมเดลการสำรองข้อมูล ดังนั้นพวกเขาจะต้องมีผู้เรียกเวทมนตร์มาก่อน ฉันไม่เห็นสิ่งที่เกี่ยวข้องกับชื่อไฟล์หรือทางเลือกอื่น
Marius

@Marius ดูคำตอบที่อัปเดตของฉันสำหรับวิธีอื่นที่เป็นไปได้
Raphael ที่ Digital Pianism

สิ่งนี้สามารถใช้งานได้ ฉันจะลองและกลับมาพร้อมผลลัพธ์
Marius

@Marius ตรวจสอบcollectFileInfoจากMagento\MediaStorage\Helper\File\Media;)
Raphael ที่ Digital Pianism

collectFileInfoจะไม่ช่วยฉันเพราะมันคาดว่าไฟล์ภายในโฟลเดอร์สื่อ Mine อยู่ในโฟลเดอร์ var ยังgetStorageDataไม่มีอะไรเกี่ยวข้องกับสิ่งที่ฉันต้องการ ฉันไม่ต้องการรวบรวมไฟล์ทั้งหมดในโฟลเดอร์ ฉันมีชื่อไฟล์แล้ว
Marius
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.