Import data - Best Practice?

I have seen many threads about file uploading, and how to handle those via a model or a form. But I haven’t seen any thread nor a documentation talking about best practices (or even some directions) on how to implement an import feature.

I’m developing a management application where I need to implement a feature to let the users import a large quantity of data via Excel/CSV files.

For example I have a table called Companies which collect some information about customer’s entities, in addition to the normal form to create a new company I also want to give the users the chance to import nth number of companies via a predefined CSV file (with a specific format).

Logic suggests me I have to put my file rule in the Companies’ model and create a separate view for it with the file upload handling. Unfortunately can’t do that as when trying to create a new company manually it will miss the file (that field won’t be in that form but on a separate form). So I should separate the two things, but then how will I handle the creation of records in the table if my file is just based on a form and not on the model?

Can somebody with more experience in YII shed some light on this pattern and what’s the best approach without creating too much mess in the code?


I might be missing something, but I would do this quite differently. I would completely separate Company data (model) from import feature. I would create separate action (or even controller), which would handle file upload (i.e. form for this action would only have one field - for selecting file, and no fields related to Company model). After submitting a field, an action responsible to process the file would open it, read thoroughly and add every new company basing on data found there, using model.

This way, operation of adding a new company using form or importing one or more companies using file upload would be separated and you would never run into concerns, you are writing about.

BTW: I don’t remember if due to security restriction you can open uploaded file directly from a temporal upload folder, process it and PHP will automatically delete it after your script execution is ended (as it always do with files uploaded to temporary location and not moved to a permanent one by script) or if you have to move it to a permanent location, process and then delete manually?

I don’t actually have much experience in Yii but I’m implementing a CSV import for several tables in my database. I found it easier to make a separate CSV model to validate and save the CSV data. It takes a data model as one of its variables. That way I can implement it on every one of my models who needed the feature and I can validate which CSV lines are valid and can be saved.

@Trejder: in this case all I have to do is to create a new controller and related view with form where the controller will handle the data loading in db. I assume from within the controller I’ll be able to call like the Companies’ data model otherwise how would I save the data in the db?

@Alarice Chan: I don’t think I can create a model based not on a db table? or do you suggest to create some sort of CSV table in db? Can you expand a little bit I’m interested to know your approach in better details

Thanks all for the kind replies!

You can’t make a CActiveRecord model that is not based on a table but you can make a CFormModel or a CModel that isn’t. I extended CModel and added a rule to validate the file being passed was really a txt or a csv. Added a save method that reads the csv and saves it to the database line by line using a constructed object based on the model passed. If the line data contents cannot be saved for some reason the line is recorded in a variable array of failed lines.