Importing Data from CSV into CakePHP

This is a quick little method that lets you get some data from a CSV into a table.

It should work with very large CSV files as it only has to read one row at a time.

Controller Method

Pretty simple, just an import action to drop into your controller.

controllers/posts_controller.php
class PostsController extends AppController {
        var $name = 'Posts';

        function import() {
                // to avoid having to tweak the contents of
                // $data you should use your db field name as the heading name
                // eg: Post.id, Post.title, Post.description

                // set the filename to read CSV from
                $filename = TMP . 'uploads' . DS . 'Post' . DS . 'posts.csv';
               
                // open the file
                $handle = fopen($filename, "r");
               
                // read the 1st row as headings
                $header = fgetcsv($handle);
               
                // read each data row in the file
                $i = 0; // for the message
                while (($row = fgetcsv($handle)) !== FALSE) {
                        $i++;
                        $data = array();

                        // for each header field
                        foreach ($header as $k=>$head) {
                                // get the data field from Model.field
                                if (strpos($head,'.')!==false) {
                                        $h = explode('.',$head);
                                        $data[$h[0]][$h[1]]=(isset($row[$k])) ? $row[$k] : '';
                                }
                                // get the data field from field
                                else {
                                        $data['Post'][$head]=(isset($row[$k])) ? $row[$k] : '';
                                }
                        }

                        // see if we have an id                        
                        $id = isset($data['Post']['id']) ? $data['Post']['id'] : 0;

                        // we have an id, so we update
                        if ($id) {
                                // there is 2 options here,
                                 
                                // option 1:
                                // load the current row, and merge it with the new data
                                //$this->Post->recursive = -1;
                                //$post = $this->Post->read(null,$id);
                                //$data['Post'] = array_merge($post['Post'],$data['Post']);
                               
                                // option 2:
                                // set the model id
                                $this->Post->id = $id;
                        }
                       
                        // or create a new record
                        else {
                                $this->Post->create();
                        }
                       
                        // see what we have
                        // debug($data);
                       
                        // set the error to false
                        $error = false;
                       
                        // validate the row
                        $this->Post->set($data);
                        if (!$this->Post->validates()) {
                                $this->_flash(__(sprintf('Post for Row %d failed to validate.',$i), true),'warning');
                                $error = true;
                        }

                        // save the row
                        if (!$error && !$this->Post->save($data)) {
                                $this->_flash(__(sprintf('Post for Row %d failed to save.',$i), true),'warning');
                        }

                        // save the row
                        if (!$error) {
                                // for more info on _flash() please visit:
                                // http://mrphp.com.au/node/1820
                                $this->_flash(__(sprintf('Post for Row %d was saved.',$i), true),'success');
                        }
                }
               
                // close the file
                fclose($handle);
               
                // go to another page
                // $this->autoRender = false; // if you remove the redirect then add this
                $this->redirect(array('action'=>'index'));
        }
}

Post new comment

  • Allowed HTML tags: <b> <br> <p> <a> <strong> <cite> <em> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
  • You may use [img:xx] tags to display uploaded files or images inline.
  • You can enable syntax highlighting of source code with the following tags: <code>, <blockcode>, <css>, <diff>, <drupal5>, <html>, <javascript>, <php>. Beside the tag style "<foo>" it is also possible to use "[foo]". PHP source code can also be enclosed in <?php ... ?> or <% ... %>.

More information about formatting options