file upload in cakephp 2.3

2019-01-25 12:39发布

问题:

I'm new in cakephp and i'm trying to create a simple file upload with cakephp 2.3 here is my controller

public function add() {
    if ($this->request->is('post')) {
        $this->Post->create();
           $filename = WWW_ROOT. DS . 'documents'.DS.$this->data['posts']['doc_file']['name']; 
           move_uploaded_file($this->data['posts']['doc_file']['tmp_name'],$filename);  


        if ($this->Post->save($this->request->data)) {
            $this->Session->setFlash('Your post has been saved.');
            $this->redirect(array('action' => 'index'));
        } else {
            $this->Session->setFlash('Unable to add your post.');
        }
     }
 }

and my add.ctp

echo $this->Form->create('Post');
echo $this->Form->input('firstname');
echo $this->Form->input('lastname');
echo $this->Form->input('keywords');
echo $this->Form->create('Post', array( 'type' => 'file'));
echo $this->Form->input('doc_file',array( 'type' => 'file'));
echo $this->Form->end('Submit')

it saves firstname, lastname, keywords, and the name of the file in DB , but the file which i want to save in app/webroot/documents is not saving , can anyone help ? Thanks

Update

thaJeztah i did as u said but it gives some errors here is controller if i'm not wrong

public function add() {
     if ($this->request->is('post')) {
         $this->Post->create();
            $filename = WWW_ROOT. DS . 'documents'.DS.$this->request->data['Post']['doc_file']['name']; 
           move_uploaded_file($this->data['posts']['doc_file']['tmp_name'],$filename);



         if ($this->Post->save($this->request->data)) {
             $this->Session->setFlash('Your post has been saved.');
             $this->redirect(array('action' => 'index'));
         } else {
            $this->Session->setFlash('Unable to add your post.');
         }
     }

 }

and my add.ctp

 echo $this->Form->create('Post', array( 'type' => 'file'));
 echo $this->Form->input('firstname'); echo $this->Form->input('lastname');
 echo $this->Form->input('keywords');
 echo $this->Form->input('doc_file',array( 'type' => 'file'));
 echo $this->Form->end('Submit') 

and the errors are

Notice (8): Array to string conversion [CORE\Cake\Model\Datasource\DboSource.php, line 1005]

Database Error Error: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'Array' in 'field list'

SQL Query: INSERT INTO first.posts (firstname, lastname, keywords, doc_file) VALUES ('dfg', 'cbhcfb', 'dfdbd', Array)

and Victor i did your version too , it doesnt work too .

回答1:

You seem to be using the wrong 'key' to access the posted data;

$this->data['posts'][....

Should match the 'alias' of you Model; singular and a captial first letter

$this->data['Post'][....

Also, $this->data is a wrapper for $this->request->data for backwards compatibility, so it's better to use this;

$this->request->data['Post'][...

To check the content of the posted data and understand how it's structured, you may debug it using this;

debug($this->request);

Just be sure to enable debugging, by setting debug to 1 or 2 inside app/Config/core.php

Update; duplicate Form tags!

I just noticed you're also creating multiple (nested) forms in your code;

echo $this->Form->input('keywords');

// This creates ANOTHER form INSIDE the previous one!
echo $this->Form->create('Post', array( 'type' => 'file'));

echo $this->Form->input('doc_file',array( 'type' => 'file'));

Nesting forms will never work, remove that line and add the 'type => file' to the first Form->create()

Using only the file name for the database

The "Array to string conversion" problem is cause by the fact that you're trying to directly use the data of 'doc_file' for your database. Because this is a file-upload field, 'doc_file' will contain an Array of data ('name', 'tmp_name' etc.).

For your database, you only need the 'name' of that array so you need to modify the data before saving it to your database.

For example this way;

// Initialize filename-variable
$filename = null;

if (
    !empty($this->request->data['Post']['doc_file']['tmp_name'])
    && is_uploaded_file($this->request->data['Post']['doc_file']['tmp_name'])
) {
    // Strip path information
    $filename = basename($this->request->data['Post']['doc_file']['name']); 
    move_uploaded_file(
        $this->data['Post']['doc_file']['tmp_name'],
        WWW_ROOT . DS . 'documents' . DS . $filename
    );
}

// Set the file-name only to save in the database
$this->data['Post']['doc_file'] = $filename;


回答2:

..ensure the documents directory already exists and check you have permissions to write to it? If it doesnt exist create it or in your code check if it exists and create it if it is not there: example of code that will check if the directory is there or not and create it then upload the file-

$dir = WWW_ROOT. DS . 'documents';
 if(file_exists($dir) && is_dir($dir))
 {
    move_uploaded_file($this->data['posts']['doc_file']['tmp_name'],$filename);  
 }
 elseif(mkdir($dir,0777))
 {
  move_uploaded_file($this->data['posts']['doc_file']['tmp_name'],$filename);  
  }

also ensure you are not uploading a blank/empty file - it might fail.



回答3:

Just incase anyone is searching for it again. Here's my code (tested & used on Cakephp 2.5.5). It is based on http://www.templemantwells.com.au/article/website-development/cakephp-image-uploading-with-database & http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#FormHelper::file

View file (*.ctp)

    <?php 
    echo $this->Form->create('Image', array('type' => 'file'));
?>


    <fieldset>
        <legend><?php echo __('Add Image'); ?></legend>
    <?php


        echo $this->Form->input('Image.submittedfile', array(
            'between' => '<br />',
            'type' => 'file',
            'label' => false
        ));
        // echo $this->Form->file('Image.submittedfile');

    ?>
    </fieldset>
<?php echo $this->Form->end(__('Send My Image')); ?>

Controller function (*.php)

    public function uploadPromotion() {

    // Custom
    $folderToSaveFiles = WWW_ROOT . 'img/YOUR_IMAGE_FOLDER/' ;




    if (!$this->request->is('post')) return;        // Not a POST data!


    if(!empty($this->request->data))
    {
        //Check if image has been uploaded
        if(!empty($this->request->data['Image']['submittedfile']))
        {
                $file = $this->request->data['Image']['submittedfile']; //put the data into a var for easy use

                debug( $file );

                $ext = substr(strtolower(strrchr($file['name'], '.')), 1); //get the extension
                $arr_ext = array('jpg', 'jpeg', 'gif'); //set allowed extensions

                //only process if the extension is valid
                if(in_array($ext, $arr_ext))
                {


                    //do the actual uploading of the file. First arg is the tmp name, second arg is 
                    //where we are putting it
                    $newFilename = $file['name']; // edit/add here as you like your new filename to be.
                    $result = move_uploaded_file( $file['tmp_name'], $folderToSaveFiles . $newFilename );

                    debug( $result );

                    //prepare the filename for database entry (optional)
                    //$this->data['Image']['image'] = $file['name'];
                }
        }

        //now do the save (optional)
        //if($this->Image->save($this->data)) {...} else {...}
    }




}


回答4:

I've found the complete guide to uploading files and images in CakePHP from here - Handling File Uploads in CakePHP

The example code is given below.

Controller:

$fileName = $this->request->data['file']['name'];
$uploadPath = 'uploads/files/';
$uploadFile = $uploadPath.$fileName;
if(move_uploaded_file($this->request->data['file']['tmp_name'],$uploadFile)){
    //DB query goes here
}

View:

<?php echo $this->Form->create($uploadData, ['type' => 'file']); ?>
    <?php echo $this->Form->input('file', ['type' => 'file', 'class' => 'form-control']); ?>
    <?php echo $this->Form->button(__('Upload File'), ['type'=>'submit', 'class' => 'form-controlbtn btn-default']); ?>
<?php echo $this->Form->end(); ?>