如何使用Cakephp 3.0上传文件?

如何使用Cakephp 3.0上传文件?,cakephp,cakephp-3.0,Cakephp,Cakephp 3.0,我正在尝试在cakephp上创建一个文件上传,我还没有找到任何关于cakephp 3.0的详细教程,我也不知道如何安装插件 我在我的添加部分有这个 echo $this->Form->create('filename', array('action' => 'upload', 'type' => 'file')); echo $this->Form->file('filename'); 我还没有在控制器中添加任何内容 /** * Index method

我正在尝试在cakephp上创建一个文件上传,我还没有找到任何关于cakephp 3.0的详细教程,我也不知道如何安装插件

我在我的添加部分有这个

echo $this->Form->create('filename', array('action' => 'upload', 'type' => 'file'));
echo $this->Form->file('filename');
我还没有在控制器中添加任何内容

/**
 * Index method
 *
 * @return void
 */
public function index()
{
    $this->paginate = [
        'contain' => ['Courses']
    ];
    $this->set('contents', $this->paginate($this->Contents));
    $this->set('_serialize', ['contents']);
}

/**
 * View method
 *
 * @param string|null $id Content id.
 * @return void
 * @throws \Cake\Network\Exception\NotFoundException When record not found.
 */
public function view($id = null)
{
    $content = $this->Contents->get($id, [
        'contain' => ['Courses']
    ]);
    $this->set('content', $content);
    $this->set('_serialize', ['content']);
}

/**
 * Add method
 *
 * @return void Redirects on successful add, renders view otherwise.
 */
public function add()
{
    $content = $this->Contents->newEntity();
    if ($this->request->is('post')) {
        $content = $this->Contents->patchEntity($content, $this->request->data);
        if ($this->Contents->save($content)) {
            $this->Flash->success('The content has been saved.');
            return $this->redirect(['action' => 'index']);
        } else {
            $this->Flash->error('The content could not be saved. Please, try again.');
        }
    }
    $courses = $this->Contents->Courses->find('list', ['limit' => 200]);
    $this->set(compact('content', 'courses'));
    $this->set('_serialize', ['content']);
}

/**
 * Edit method
 *
 * @param string|null $id Content id.
 * @return void Redirects on successful edit, renders view otherwise.
 * @throws \Cake\Network\Exception\NotFoundException When record not found.
 */
public function edit($id = null)
{
    $content = $this->Contents->get($id, [
        'contain' => []
    ]);
    if ($this->request->is(['patch', 'post', 'put'])) {
        $content = $this->Contents->patchEntity($content, $this->request->data);
        if ($this->Contents->save($content)) {
            $this->Flash->success('The content has been saved.');
            return $this->redirect(['action' => 'index']);
        } else {
            $this->Flash->error('The content could not be saved. Please, try again.');
        }
    }
    $courses = $this->Contents->Courses->find('list', ['limit' => 200]);
    $this->set(compact('content', 'courses'));
    $this->set('_serialize', ['content']);
}

/**
 * Delete method
 *
 * @param string|null $id Content id.
 * @return void Redirects to index.
 * @throws \Cake\Network\Exception\NotFoundException When record not found.
 */
public function delete($id = null)
{
    $this->request->allowMethod(['post', 'delete']);
    $content = $this->Contents->get($id);
    if ($this->Contents->delete($content)) {
        $this->Flash->success('The content has been deleted.');
    } else {
        $this->Flash->error('The content could not be deleted. Please, try again.');
    }
    return $this->redirect(['action' => 'index']);
}

但是在这之后,你不知道该做什么。

首先,你需要决定何时处理上传。我已经使用beforemashall方法和afterSave方法创建了一个肮脏但有效的方法,我将在最后解释这两种方法的原因

如果创建文件输入,如:

<?= $this->Form->file('submittedfile', ['class' => 'form-control input-upload', 'style' => 'height:100px']) ?>
您可以在修补和保存实体之前处理这些文件:

public function beforeMarshal(Event $event, \ArrayObject $data, \ArrayObject $options) {
        $images = array();
        $dir = md5(time().$data['name']);
        for ($i = 0; $i < count($data['images']); $i++) {
            $image = $data['images'][$i]['submittedfile'];
            if (!empty($image['name'])) {
                if(!isset($data['id'])) {
                    $data['temp_dir'] = $dir;
                }
                else {
                    $dir = $data['id'];
                }
                if ($this->Images->uploadFile(array('img', 'model', $dir), $image) === true) {
                    $images[] = array('name' => pathinfo($image['name'], PATHINFO_FILENAME), 'ext' => pathinfo($image['name'], PATHINFO_EXTENSION));
                }
            }
        }
        $data['images'] = $images;
    }
如果在没有主实体ID的子目录时添加图像,则必须在获得ID后立即重命名该目录:

public function afterSave(Event $event, Entity $entity, \ArrayObject $options) {
        if(!empty($entity->temp_dir)) {
            $this->Images->renameFolder(array('img', 'model', $entity->temp_dir),$entity->id);
        }
    }
电话:

public function renameFolder($path = array(), $newName) {
        $oldPath = $this->wwwRoot . implode(DS, $path);
        $nameToChange = array_pop($path);
        array_push($path, $newName);
        $newPath = $this->wwwRoot . implode(DS, $path);
        return rename($oldPath, $newPath);
    }
使用BeforeMarshall,您可以在整个实体准备好保存关联之前将文件数据注入实体结构。 使用afterSave,您可以识别主对象ID并调用以前上载的对象集。 请记住设置将文件保存到目录的递归权限,以及创建和重命名目录的权限。
如果你不懂插件,那就自学或者雇人教你。这本手册涵盖了框架的所有内容,所以只要使用它就可以了。你能从控制器发布代码吗?这样我们就可以看到那里发生了什么。我假设你有一个提交按钮或某种机制将文件提交给控制器。你不会找太久的。CakePHP食谱中有一个关于处理上传文件的部分:上面的帮助链接是我已经有的,我更喜欢控制器部分
public function uploadDir($path = array()) {
        return $this->wwwRoot . implode(DS, $path);
    }

    public function uploadFile($path = array(), $filetoupload = null) {
        if (!$filetoupload) {
            return false;
        }
        $dir = new Folder($this->uploadDir($path), true, 755);
        $tmp_file = new File($filetoupload['tmp_name']);
        if (!$tmp_file->exists()) {
            return false;
        }
        $file = new File($dir->path . DS . $filetoupload['name']);
        if (!$tmp_file->copy($dir->pwd() . DS . $filetoupload['name'])) {
            return false;
        }
        $file->close();
        $tmp_file->delete();
        return true;
    }
public function afterSave(Event $event, Entity $entity, \ArrayObject $options) {
        if(!empty($entity->temp_dir)) {
            $this->Images->renameFolder(array('img', 'model', $entity->temp_dir),$entity->id);
        }
    }
public function renameFolder($path = array(), $newName) {
        $oldPath = $this->wwwRoot . implode(DS, $path);
        $nameToChange = array_pop($path);
        array_push($path, $newName);
        $newPath = $this->wwwRoot . implode(DS, $path);
        return rename($oldPath, $newPath);
    }