你如何在 CakePHP 中获取所有上传的文件?

How do you get all uploaded files in CakePHP?

如何在 CakePHP 3.x 中获取所有上传的文件?这是我的控制器,可以让你走上正轨。

<?php
class MyController extends AppController {
    public function upload() {
        // how to loop through all files?
    }
}

示例表格

<form action="/my/upload" method="post" enctype="multipart/form-data">
    <input type="text">
    <!-- any number of file inputs -->
    <input type="file" name="file">
    <input type="file" name="image[]">
    <textarea></textarea>
    <!-- etc. -->
    <input type="submit" value="Upload">
</form>

回答我自己的问题。我还没有接受它,以防有人想出更好的东西或发现错误。

<?php
class MyController extends AppController {
    public function upload() {
        $files = $this->getFilesArray($this->request->data);
        foreach($files as $file) {
            // move_uploaded_file
        }
    }

    /**
     * Get files recursively in flat array
     *
     * @param mixed $field
     * @return array
     */
    public function getFilesArray($field) {

        if(is_array($field)) {
            if(!empty($field['tmp_name'])) {
                return [$field];
            }
            $files = [];
            foreach($field as $item) {
                $files = array_merge($files, $this->getFilesArray($item));
            }
            return $files;
        }

        return [];
    }

}

文件上传数据不再单独存储,所以如果您不知道名称(无论出于何种原因),并且只有这一块数据,那么您将不得不迭代它并计算哪个条目是文件上传数组,类似于您在答案中显示的内容。

我个人在这种情况下使用自定义请求 类。这是一个简单的示例,其中存储了已处理文件数据的密钥,并用于提取之后上传的文件。

namespace App\Network;

class Request extends \Cake\Network\Request {

    /**
     * Holds the keys that are being used to store the file uploads
     * in the data array.
     *
     * @var string[]
     */
    protected $_fileKeys = [];

    /**
     * Returns all file uploads.
     *
     * @return array[]
     */
    public function files() {
        return array_intersect_key($this->data, array_flip($this->_fileKeys));
    }

    protected function _processFiles($post, $files) {
        $filesData = parent::_processFiles([], $files);
        $this->_fileKeys = array_keys($filesData);
        return array_merge($post, $filesData);
    }

}

webroot/index.php

$dispatcher = DispatcherFactory::create();
$dispatcher->dispatch(
    \App\Network\Request::createFromGlobals(),
    new Response()
);