CAKEPHP 4:我不能同时上传很多文件

CAKEPHP 4: I cannot upload many files at the same time

晚安(或早安),

我想同时上传多个文件。我正在按照 cookbook instructions 构建解决方案。我总是得到第一个文件(不是文件数组)。

这是我的查看代码...

<?php
/**
 * @var \App\View\AppView $this
 * @var \App\Model\Entity\Upload $upload
 */
?>
<div class="row">
    <aside class="column">
        <div class="side-nav">
            <h4 class="heading"><?= __('Actions') ?></h4>
            <?= $this->Html->link(__('List Uploads'), ['action' => 'index'], ['class' => 'side-nav-item']) ?>
        </div>
    </aside>
    <div class="column-responsive column-80">
        <div class="uploads form content">
            <?= $this->Form->create($upload, ['type' => 'file']) ?>
            <fieldset>
                <legend><?= __('Add Upload') ?></legend>
                <?php
                    echo $this->Form->control('name');
                    echo $this->Form->control('document_type_id', ['options' => $documentTypes]);
                    echo $this->Form->control('period_id', ['options' => $periods]);
                    echo $this->Form->control('user_id', ['options' => $users]);
                    echo $this->Form->control('documents', ['type' => 'file',  'label' => __('Choose PDF Files'), 'accept' => 'application/pdf', 'multiple' => 'multiple']);
                ?>
            </fieldset>
            <?= $this->Form->button(__('Submit')) ?>
            <?= $this->Form->end() ?>
        </div>
    </div>
</div>

这是我的控制器代码...

public function add()
{
    $upload = $this->Uploads->newEmptyEntity();

    if ($this->request->is('post')) {

        $upload = $this->Uploads->patchEntity($upload, $this->request->getData());

        if ($this->Uploads->save($upload)) {

            if (!is_dir($this->Parameters->findByName('document_directory')->first()->toArray()['value'] )) {
                mkdir($this->Parameters->findByName('document_directory')->first()->toArray()['value'], 0776, true);
            }

            $documents = $this->request->getData('documents');

            $this->loadModel('Dockets');
            $dockets = $this->Dockets->findByDocketStateId(1);

            $documents_ok = 0;
            $documents_nok = 0;
            $dockets_without_document = 0;

            foreach($documents as $documents_key => $document_to_save)
            {
                foreach($dockets as $dockets_key => $docket)
                {
                    $contents = file_get_contents($document_to_save);
                    
                    $pattern = str_replace('-', '', $pattern);

                    $pattern = str_replace('', '', $pattern);

                    $pattern = preg_quote($docket->cuit, '/');

                    $pattern = "/^.*$pattern.*$/m";
                    // search, and store all matching occurences in $matches
                    if(preg_match_all($pattern, $contents, $matches)){

                        $documentsTable = $this->getTableLocator()->get('Documents');
                        $document = $documentsTable->newEmptyEntity();

                        $document->upload_id = $upload->id;

                        $document->document_type_id = $upload->document_type_id;

                        $document->period_id = $upload->period_id;

                        $document->docket_id = $docket->id;

                        $document->user_id = $this->getRequest()->getAttribute('identity')['id'];
                        
                        if ($documentsTable->save($document)) {

                            if (!is_dir($this->Parameters->findByName('document_directory')->first()->toArray()['value'] )) {
                                mkdir($this->Parameters->findByName('document_directory')->first()->toArray()['value'], 0776, true);
                            }

                            $fileobject = $this->request->getData('document');

                            $destination = $this->Parameters->findByName('document_directory')->first()->toArray()['value']  . 'document_' . $document->id . '.pdf';

                            // Existing files with the same name will be replaced.
                            $fileobject->moveTo($destination);
                        }
                        $this->Flash->error(__('The document could not be saved. Please, try again.'));

                        $documents_ok = $documents_ok + 1;

                        unset($dockets[$dockets_key]);

                        unset($documents[$documents_key]);

                        break;
                    }
                }
            }

            if(!empty($documents)){

                //print_r($documents);

                $documents_nok = count($documents);

                unset($documents);
            }

            if(!empty($dockets)){

                $dockets_without_document = count($dockets);

                unset($dockets);

            }

            $message = __('There were processed ') . $documents_ok . __(' documents succesfully. ') . $documents_nok . __(' documents did not math with a docket. And ') . $dockets_without_document . __(' active dockets ddid not not have a document.');

            $this->Flash->success(__('The upload has been saved. ') . $message);

            return $this->redirect(['action' => 'view', $upload->id]);
        }
        $this->Flash->error(__('The upload could not be saved. Please, try again.'));
    }
    $documentTypes = $this->Uploads->DocumentTypes->find('list', ['keyField' => 'id',
                                                                  'valueField' => 'document_type',
                                                                  'limit' => 200]);
    $periods = $this->Uploads->Periods->find('list', ['keyField' => 'id',
                                                      'valueField' => 'period',
                                                      'limit' => 200]);
    $users = $this->Uploads->Users->find('list', ['keyField' => 'id',
                                                  'valueField' => 'full_name',
                                                  'conditions' => ['id' => $this->getRequest()->getAttribute('identity')['id']],
                                                  'limit' => 200]);
    $this->set(compact('upload', 'documentTypes', 'periods', 'users'));
}

你能帮我理解我做错了什么吗?

谢谢,

贡萨洛

当使用PHP时,多文件表单输入的名称必须附加[],否则PHP无法解析出多个条目,它们都会有相同的名称,PHP 将只使用该名称的最后一次出现。

echo $this->Form->control('documents', [
    'type' => 'file',
    'label' => __('Choose PDF Files'),
    'accept' => 'application/pdf',
    'multiple' => 'multiple',
    'name' => 'documents[]',
]);

还有下面一行:

$fileobject = $this->request->getData('document');

应该更像这样,因为 a) 没有 document 字段和 b) 即使有,您很可能不想一遍又一遍地处理同一个文件:

$fileobject = $documents[$documents_key];

还要确保您对上传的文件进行了适当的验证,即使您似乎没有使用用户提供的文件信息,您仍然应该确保您收到了有效数据!