How to Upload File in CakePHP 4, Part-5

CakePHP 4 Moving the uploaded file from the its temporary location to the desire target location to using CakePHP 4 library to upload files. We need to use PHP’s  moveTo method upload file  to the server. In this tutorial you will learn how to upload a file in CakePHP.

Create MySQL Database and Table

In the first step we need to create a database and tables, so here I have created a database of tables “webscodex” and ”posts” with identifiers and columns with names. You simply create a Users table as described in the SQL query.

-- Database: `webscodex`

-- Table structure for table `posts`

CREATE TABLE `posts` (
  `title` varchar(100) NOT NULL,
  `description` varchar(100) NOT NULL,
  `post_image` varchar(100) NOT NULL,
  `created` datetime NOT NULL,
  `updated` datetime NOT NULL

File Upload Directory

Create the directory (webroot/img/post_image) where you want to upload or store images the upload directory using $targetPath

$targetPath = WWW_ROOT. 'img'. DS . 'post_image'. DS.;


In this post we will use the src/controller/PostsController.php  controller to create a add function to upload file in database.



// src/Controller/PostsController.php

namespace App\Controller;
use App\Controller\AppController;
use Cake\Event\EventInterface;
use Cake\Datasource\FactoryLocator;

class PostsController extends AppController{

	public $postsTableObj;

	public function beforefilter(EventInterface $event){
	    $this->postsTableObj = FactoryLocator::get('Table')->get('Posts');

    public function add(){
    	$postEnt = $this->postsTableObj->newEmptyEntity();
    	if ($this->request->is('post')) {
    	    $postData = $this->request->getData();
            $postImage = $this->request->getData('post_image');
            $name = $postImage->getClientFilename();
            $type = $postImage->getClientMediaType();
            $targetPath = WWW_ROOT. 'img'. DS . 'post_image'. DS. $name;
            if ($type == 'image/jpeg' || $type == 'image/jpg' || $type == 'image/png') {
                if (!empty($name)) {
                    if ($postImage->getSize() > 0 && $postImage->getError() == 0) {
                        $postData['post_image'] = $name;
    	    $posts = $this->postsTableObj->patchEntity($postEnt, $postData);
    	if ($this->postsTableObj->save($posts)) {
    	    $this->Flash->success(__('Your post has been saved.'));
            return $this->redirect(['controller'=>'Posts','action' => 'index']);
    	    $this->Flash->error(__('Unable to add your post.'));
            return $this->redirect(['controller'=>'Posts','action' => 'add']);
    	$this->set(compact('postEnt', $postEnt));


In Model src/Model/Table/PostsTable.php  to validate form and insert date time value in created and updated using addBehavior function with Timestamp.



namespace App\Model\Table;
use Cake\ORM\Table;
use Cake\Validation\Validator;

class PostsTable extends Table
    public function initialize(array $config): void
        $this->addBehavior('Timestamp', [
            'events' => [
                'Model.beforeSave' => [
                    'created' => 'new',
                    'updated' => 'always'

    public function validationDefault(Validator $validator): Validator 

        return $validator;



In view Templates/Posts/add.php view is responsible for creating the upload form and display the uploaded file list.


<div class="text-center" style="margin-top: 50px;">
  <h4>Add Post</h4>
<div class="container">
  <div class="row">
    <div class="col-sm-3"></div>
    <div class="col-sm-6">
      <?php echo $this->Form->create($postEnt, ['name'=>'add_post', 'class'=>'was-validated',
       'enctype'=>'multipart/form-data']) ?>
      <div class="form-group">
        <?php echo $this->Form->control('title', ['type'=>'text', 'class'=>'form-control','placeholder'=>'Enter title','required'=>true]);?>
      <div class="form-group">
        <?php echo $this->Form->control('description', ['type'=>'text', 'class'=>'form-control','placeholder'=>'Enter description','required'=>true]);?>
      <div class="form-group">
        <?= $this->Form->control('post_image', ['type'=>'file', 'class'=>'form-control','required'=>true]); ?>
      <button type="submit" class="btn btn-success" style="float: right;">Save</button>
      <?php echo $this->Form->end() ?>

You can always support by sharing on social media or recommending my blog to your friends and colleagues. If you have any suggestions or problems about this tutorial, please comment on the  form below.😊

How to Upload File in CakePHP 4, Part-5


Leave a Reply

Your email address will not be published. Required fields are marked *

  1. Hey, thanks for this – it worked well! My only question is – on edit if I don't choose a file, it gives an error "cannot be blank". Essentially, I don't want to update the field if a new file isn't selected (just keep the file that is already there). Any recommendations on how to approach this? Thanks!