Hệ thống tập tin thực hành tốt nhất


10

Tôi đang làm việc trên một số tiện ích mở rộng Magento 2 yêu cầu đọc tệp từ hệ thống tệp.
Khi chạy trình thám thính php bằng các tiêu chuẩn ECGM2, nó phàn nàn về thực tế là tôi đang sử dụng các hàm như basenamehoặc dirname.

Việc sử dụng hàm dirname () bị cấm

hoặc là

Việc sử dụng hàm basename () bị cấm

Tôi nên sử dụng trình bao bọc nào thay vì các trình bao bọc để có được hiệu quả tương tự?

[EDIT]
Đây là một số mã, nhưng nó không liên quan đến câu hỏi.
Tôi có một lớp bộ sưu tập mở rộng \Magento\Framework\Data\Collection\Filesystemlớp và tôi muốn liệt kê bộ sưu tập này trong một lưới (ui-thành phần) và một trong những hành động trong lưới là một hành động tải xuống.
Đối với điều này, tôi cần lấy tên thật của tệp để tôi có thể gửi nó đến hành động tải xuống.

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

bạn có thể chia sẻ một phần mã của bạn, những gì bạn đã cố đọc tệp từ hệ thống.
Dhiren Vasoya

Tôi đã thêm một số mã, nhưng nó hoàn toàn không liên quan đến câu hỏi. Câu hỏi có phần trừu tượng. Tôi nên sử dụng cái gì thay vì tên cơ sở để mã sniffer không phàn nàn?
Marius

Nó trông giống như vấn đề cho phép.
Ashish Jagnani

Nó không có gì để làm với quyền. Mã này hoạt động đúng, nhưng mã sniffer nói rằng không nên sử dụng basenameở đó. Xin vui lòng đọc câu hỏi cẩn thận.
Marius

Câu trả lời:


15

Tôi cũng cần một cái gì đó như thế gần đây. Giải pháp duy nhất tôi tìm thấy để có được basenamedirnameđang sử dụng:

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

Trước đó tôi đã thử sử dụng Magento\Framework\Filesystem\Directory\WritegetDriver()không thành công. Với họ bạn có thể nhận được khá nhiều thứ nhưng không phải basename.


ĐÚNG. Đó là nó. Cảm ơn bạn. Tôi sẽ thưởng tiền thưởng ngay khi tôi được phép.
Marius

Marius bạn thực sự sẽ thực hiện nó theo cách đó? [\ Magento \ Framework \ Filesystem \ Io \ File-> getpathinfo] [1] theo nghĩa đen chỉ gọi [pathinfo] [2] mà lần lượt gọi basename và dirname [1]: github.com/magento/magento2/blob/develop/ lib / nội / Magento / ... [2]: github.com/php/php-src/blob/master/ext/standard/string.c#L1662
Richard

1
@Richard. Tôi đã thấy điều đó. Để bây giờ tôi cần / muốn tránh một số chức năng. Và trong trường hợp cụ thể của tôi, nó rất phù hợp vì tôi đã có một thể hiện \Magento\Framework\Filesystem\Io\Fileđược tiêm trong lớp của riêng tôi cho một chức năng khác. Tôi chỉ không biết trước về getPathInfophương pháp.
Marius

3

May mắn thay git cho chúng ta thấy khi dirname và tên cơ sở bị cấm , lý do rõ ràng là "Đã thêm tệp"

Nhìn vào vấn đề cho dự án ECG, bạn có thể thấy các vấn đề đóng như có gì đó không tốt trong file_exists không? # 33 , Hàm lỗi # 26 , có gì không ổn trong hàm này? # 17 , Bối cảnh / Giải thích cho Quy tắc # 12 , Việc sử dụng hàm iconv () bị cấm # 14 khiến tôi nghĩ rằng danh sách ban đầu của các hàm bị cấm không được xem xét quá nhiều và magento có thể thay đổi được danh sách cấm.

Tìm kiếm mã cơ sở m2 cho thấy ~ = 78 kết quả cho tên cơ sở, hỗn hợp các biến và mã thực sự gọi tên cơ sở, bao gồm cả yêu thích của tôi .

Tôi nghĩ rằng nếu tôi là bạn, tôi sẽ đăng một vấn đề trên github và hỏi zlik nếu anh ta vẫn nghĩ họ thuộc về nơi đó hoặc nếu M2 cung cấp trình bao bọc


2

Bạn có thể sử dụng đối tượng của SplFileInfo()lớp có thể nó sẽ hoạt động.

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

có thể nó sẽ làm việc

bạn cũng có thể tham khảo url này .


Cảm ơn vì điều đó. Nó trông sạch hơn, nhưng bạn có một ví dụ mã làm điều này? Tôi muốn làm theo các tiêu chuẩn cốt lõi.
Marius

bạn có thể tham khảo php.net/manual/en/splfileinfo.getfilename.php url này.
chirag

2

Đề nghị của tôi sẽ là sử dụng Magento/Backupmô-đun làm ví dụ.

Cách mà lớp hành động tải xuống được viết sẽ rất thú vị khi xem bởi vì nó cũng xử lý các tệp thực để tải xuống:

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

Đối với tôi, bạn nên xem cách phương thức này tạo tệp để tải xuống bằng cách sử dụng \Magento\Framework\App\Response\Http\FileFactorygenerateBackupDownloadNametừ Magento\Backup\Helper\Data(chú ý sử dụng OM;) được đề xuất)

Một chút thú vị

Một điều thú vị khác bạn nên xem xét là getStorageData phương thức Magento\MediaStorage\Model\ResourceModel\File\Storage\Filemà chính nó gọi trực tiếp dirnamebasenamenhưng nếu bạn gọi phương thức cốt lõi đó trong mô-đun của mình, bạn sẽ không gặp phải các lỗi bị cấm;)

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

Trong một ý tưởng tương tự, cũng có collectFileInfo từMagento\MediaStorage\Helper\File\Media


generateBackupDownloadNamesử dụng một số getters ma thuật từ mô hình sao lưu. Vì vậy, họ phải có ma thuật được gọi trước đó. Tôi không thấy bất cứ điều gì liên quan đến tên cơ sở hoặc một thay thế cho nó.
Marius

@Marius xem câu trả lời cập nhật của tôi cho một cách có thể khác
Raphael tại Digital Pianism

Điều này có thể làm việc. Tôi sẽ thử và quay lại với kết quả.
Marius

@Marius cũng kiểm tra collectFileInfotừ Magento\MediaStorage\Helper\File\Media;)
Raphael tại Digital Pianism

collectFileInfosẽ không giúp tôi vì nó mong đợi một tập tin trong thư mục media. Của tôi là trong thư mục var. Cũng getStorageDatakhông có gì để làm với những gì tôi cần. Tôi không muốn thu thập tất cả các tệp trong một thư mục. Tôi đã có tên tập tin.
Marius
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.