Anda di halaman 1dari 12

29/12/13

Creating a File Hosting Site with CodeIgniter | Nettuts+

Advertise Here

Creating a File Hosting Site with CodeIgniter


Henry Irish on Mar 11th 2009 with 152 Comments View post on Tuts+ BetaTuts+ Beta is an optimized, mobile-friendly and easy-to-read version of the Tuts+ network. I have seen a few introductory tutorials for Codeigniter, and was hoping to show you something a little more advanced. This tutorial will show you how to build a powerful web application for hosting images, using the flexibility of Codeigniter. This tutorial should teach you about the MVC coding philosophy, integral to producing serviceable applications.

Step 1: Setup
Before we go anywhere near the code, we need to do some setup. Fire up your favorite database editor (Ill be using SQLBuddy) and create a new database called uploadr. Inside this, create two tables: users and files. Set up users to have a primary-key, auto-numbered id column, along with two varchar columns: password and username. The files table needs another id column (again primary-key and auto-numbered), as well as an integer owner column, and a varchar name column.

net.tutsplus.com/tutorials/php/creating-a-file-hosting-site-with-codeigniter/

1/12

29/12/13

Creating a File Hosting Site with CodeIgniter | Nettuts+

Since this tutorial is focussed on learning Codeigniter programming and about MVC, we are going to forgo all of the styling stuff (like CSS, photoshop). To this end, Ive created a custom Codeigniter install for you, with all the files created, and the views (mostly) HTML-d and CSS-d. The two things youll need to change are the config and database settings. I even included a Beta stamp, so itd feel even more like a web-startup!

Step 2: Registration
Now onto the first bit of meat! Open up the login.php controller and create a function called register. This is going to control the entire registration process. First, we need to check whether any POST requests have been sent to the server. In this case, these will signify someone trying to register. We can do this by checking whether $_POST['username'] is set. If it is, then we know someone has tried to register, and can enter it into the DB. view plaincopy to clipboardprint? 1. 2. function register() 3. { 4. if(isset($_POST['username'])){ 5.
net.tutsplus.com/tutorials/php/creating-a-file-hosting-site-with-codeigniter/ 2/12

29/12/13

Creating a File Hosting Site with CodeIgniter | Nettuts+

6. // User has tried registering, insert them into database. 7. 8. $username = $_POST['username']; 9. $password = $_POST['password']; 10. 11. $this->users->register($username, $password); 12. 13. redirect('login'); 14. 15. } 16. else{ 17. //User has not tried registering, bring up registration information. 18. $this->load->view('register'); 19. } 20. } If the user has yet to try registering, it detects this and automatically sends them to the register view that Ive coded for you. Youll notice the line: view plaincopy to clipboardprint? 1. $this->users->register($username,$password); This is calling the function register in the model users. At the moment this will not work, since we havent loaded the model. We do this in the same way as loading views, but since we are going to be using this model extensively throughout this class, we will load it in the constructor function (the function with the same name as the class), so that it is always loaded and available: view plaincopy to clipboardprint? 1. function Login() 2. { 3. parent::Controller(); 4. $this->load->model('users'); 5. } Youre probably interested in what the registration function actually contains. Well, it simply uses a couple of Codeigniters active record functions, which allow for DB manipulation. The big advantage of using Codeigniters built in active record functions (besides the fact that theyre nice and simple) is that theyre database agnostic: you can easily switch in and out different database types (for example mySQL, SQLite) in the DB config file without affecting the application. In the case of our registration, were adding an entry to the users table. Create this function in the users.php model: view plaincopy to clipboardprint? 1. function register($username, $password) 2. { 3. $new_user = array ( 4. 'username'=>$username, 5. 'password'=>$password 6. ); 7. 8. $this->db->insert('users', $new_user); 9. 10. return true;
net.tutsplus.com/tutorials/php/creating-a-file-hosting-site-with-codeigniter/ 3/12

29/12/13

Creating a File Hosting Site with CodeIgniter | Nettuts+

11. } The only thing worth noticing in the registration view are the site_url() and base_url() functions. These respectively give your sites URL with and without the index.php/ suffix. The greatest advantage to them is that you can change your sites URL structure without having to go through all the links: it just takes one change in your config file. Once this is all setup, we can try registering an account. The function in our controller should redirect us to the login page again after our account is created.

Step 3: Login
Now that we have a few users set up, we need a way of actually letting them into the site. For this, we are going to use Codeigniters sessions class. Although this actually uses cookies, it works in a very similar way to normal PHP sessions, just with more options (I recommend you check the userguide). To start with, we need to create the function that the login button currently points to, go. This function will need to collect the information that the form has submitted, and then check it against the DB using a model. If all is correct, itll start a session, and redirect the user to their files. If they mistyped their information, theyll be redirected to the login page. view plaincopy to clipboardprint? 1. function go() 2. { 3. 4. $username = $_POST['username']; 5. $password = $_POST['password']; 6. 7. //Returns userid if successful, false if unsuccessful 8. $results = $this->users->login($username,$password); 9. 10. if ($results==false) redirect('login'); 11. else 12. { 13. $this->session->set_userdata(array('userid'=>$results)); 14. redirect('profile'); 15. } 16. 17. } Parts of this function should look very familiar to you from the register function: it collects $username and $password, before submitting them to a model (this time login). After this however, the differences begin to occur. It then checks to see if the login has failed; if it has, then the user is redirected back to the login page. However, if the login is successful then the script creates a session, setting userid to the users id. All that we need now for the login script to work is the model. Add this function to the users model we used earlier: view plaincopy to clipboardprint? 1. function login($username, $password) 2. { 3. 4. $query = $this->db->get_where('users', array('username'=>$username, 'password'=>$password));
net.tutsplus.com/tutorials/php/creating-a-file-hosting-site-with-codeigniter/ 4/12

29/12/13

Creating a File Hosting Site with CodeIgniter | Nettuts+

5. 6. if ($query->num_rows()==0) return false; 7. else{ 8. $result = $query->result(); 9. $first_row = $result[0]; 10. $userid = $first_row->id; 11. 12. return $userid; 13. } 14. 15. } A quick rundown: first, it queries the database looking for any users with exactly the same username and password. If it doesnt find any, then the number of rows will be 0, and the function returns false. If somebody was found, then it uses another of Codeigniters active record functions to load it as an object. This objects comes as an array of DB rows, each containing an object with that rows information. Since we want the first and only row, we take it out of $result, and then return the id from it. We will need to check whether the user is logged in whilst on the profile page. To do this, we simply insert two lines of code into the constructor of the profile controller. This will check that the session contains a userid. If it doesnt, then redirect to the login page. If it does, then all is fine, and it gets turned into a public variable. Whilst were changing the constructor, we will load the two models that we will need for the profile page: view plaincopy to clipboardprint? 1. function Profile() 2. { 3. parent::Controller(); 4. 5. $this->load->model('users'); 6. $this->load->model('files'); 7. 8. $this->userid = $this->session->userdata('userid'); 9. if (!isset($this->userid) or $this->userid=='') redirect('login'); 10. } The final thing we need to do is make it possible to logout. This is achieved by simply setting the userid to nothing, deleting it. All it requires is one simple function: view plaincopy to clipboardprint? 1. function logout() 2. { 3. $this->session->set_userdata(array('userid'=>'')); 4. redirect('login'); 5. }

Step 4: Viewing and Uploading Files


Right then, weve just logged in for the first time. What are we greeted with?

net.tutsplus.com/tutorials/php/creating-a-file-hosting-site-with-codeigniter/

5/12

29/12/13

Creating a File Hosting Site with CodeIgniter | Nettuts+

Not bad, not bad, although that sample file isnt being generated from our database, its static. Well rectify that soon, but first we need to change the permissions of the file folder so that Codeigniter can read and write on it. I changed it to 777 Permissions:

Now that thats out of the way, lets get back to some coding! We need to load all the users files out of the database, and to do that were going to need a model! This time however, were going to create it in the files.php model, so we keep our user table and file table separate. Insert this function: view plaincopy to clipboardprint? 1. function get($userid) 2. { 3. $query = $this->db->get_where('files', array('owner'=>$userid)); 4. return $query->result(); 5. } This again draws from earlier sections of this tutorial, so you should be able to understand it. Basically, it gets all the rows where the owner = the users id, and returns them in a nice array of objects. Lets create something in the profiles controller to interface with it, and to pass the info onto the view. Amend the index function with this:

net.tutsplus.com/tutorials/php/creating-a-file-hosting-site-with-codeigniter/

6/12

29/12/13

Creating a File Hosting Site with CodeIgniter | Nettuts+

view plaincopy to clipboardprint? 1. function index() 2. { 3. $data['files'] = $this->files->get($this->userid); 4. $this->load->view('profile', $data); 5. } Again, a very simple function. It takes the results passed to it from the files model, and packages them to the view. Codeigniter passes data to the view usually through an array (in this case data). It will then automatically explode the array into lots of variables, so when we go to the view, it will be able to access the database results through $file, rather than $data['file']. Lets put this lovely database result into the view! Stick this into profile.php, replacing the code that the HTML comment tells you to. view plaincopy to clipboardprint? 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. <?php foreach($files as $file): ?> <div class="section"> <span><?=$file->name?></span> <div style="float: right;"> <span><a href="<?=base_url()?>files/<?=$file->name?>">View</a></span> <span><a href="<?=site_url("profile/delete/".$file->id)?>">Delete</a></span> </div> </div> <?php endforeach; ?>

The foreach loop loads each row of the array in turn, and makes it accessible via the $file object. We then, using the sample section as a template, fill in all the links and the name with information for the new $file object. We will how the delete function works later, and how the view link works after weve uploaded something. If you open this in your browser now, you wont see anything. This is because we havent got any files uploaded! Well, we need to rectify that, so well need to make an uploading form. Lets do the controller first; open profile.php and add this function: view plaincopy to clipboardprint? 1. function upload() 2. { 3. if(isset($_FILES['file'])){ 4. $file = read_file($_FILES['file']['tmp_name']);
net.tutsplus.com/tutorials/php/creating-a-file-hosting-site-with-codeigniter/ 7/12

29/12/13

Creating a File Hosting Site with CodeIgniter | Nettuts+

5. $name = basename($_FILES['file']['name']); 6. 7. write_file('files/'.$name, $file); 8. 9. $this->files->add($name); 10. redirect('profile'); 11. } 12. 13. else $this->load->view('upload'); 14. } This function adds quite a few new things: especially Codeigniters file handling. It starts off fairly simply, checking to see whether a form has been submitted by looking for a file. If the file doesnt exist, it simply shows the upload view (which well be updating next). If the file does exist, then it extracts reads the temporary file that the server has generated. The directory of the temporary file can be found at $_FILES['your_file']['tmp_name'], and the file can be read from this directory by Codeigniters read_file. This loads all of the files information into the $file variable. The next line gets the files name from the global $_FILES in a similar way to getting the temporary directory. Armed with these two pieces of information, codeigniter writes the file to the files folder in the same directory as its index file. Lastly, the file needs to be added to the database. Again, were going this with a model, this time the add function in files. Well see how that works in a minutes, but we now need to create the uploading form in the view. Add this where the upload.phps HTML comment tells you to: view plaincopy to clipboardprint? 1. <form enctype="multipart/form-data" action="<?=site_url('profile/upload')?>" method="post"> 2. 3. <div id="boxtop"></div><div id="boxmid"> 4. 5. <div class="section"> 6. <span>File:</span> 7. <input type="file" name="file" /> 8. </div> 9. 10. </div><div id="boxbot"></div> 11. 12. <div class="text" style="float: left;"><p>Before uploading, check out</p> <p>the <a href=#>Terms of Service</a>.</p></div> 13. <div class="text" style="float: right;"> 14. 15. <input type="submit" value="Upload" name="upload" class="submit" /> 16. </div> 17. <br style="clear:both; height: 0px;" /> 18. 19. </form> Replace the current HTML with this. The important thing to note here is that when were uploading files, we use an input type=file, which allows us to pick a file to upload. Also, we have to specify an enctype in our form tag, so that the server knows that its recieving a file and to save it. Not too interesting to us back-end coders, but still crucial! Lets have a quick look at what weve created:

net.tutsplus.com/tutorials/php/creating-a-file-hosting-site-with-codeigniter/

8/12

29/12/13

Creating a File Hosting Site with CodeIgniter | Nettuts+

Now we move onto the final bit of the file uploading script, the model. This adds the file to the database, with its name and owner, so the server knows which files belong to whom. Lets take a look; add this to your files model: view plaincopy to clipboardprint? 1. function add($file) 2. { 3. $this->db->insert('files', array('owner'=>$this->session->userdata('userid'),'name'=>$file )); 4. } Again leveraging Codeigniters active record functionality, we add a row to the database with the name of the file and the owner. We get the owner by finding the users id from the session data that we saved earlier when logging on. All in all, a very simple function. Lets trying uploading a nice photo, eh?

Et, Voila!

net.tutsplus.com/tutorials/php/creating-a-file-hosting-site-with-codeigniter/

9/12

29/12/13

Creating a File Hosting Site with CodeIgniter | Nettuts+

Looking into the files folder, we see that the file that we uploaded has appeared there, as if by magic (Codeigniter magic!), and we see why the view link works, since it simply points directly to the file in the directory. With this done, all that remains for this tutorial is deleting files.

Step 5: Deleting Files


Ok, the last bit. This shouldnt take so long, since youll be able to utilize the ideas that you learnt earlier to understand this. First well add this code to our profiles controller: view plaincopy to clipboardprint? 1. function delete($id) 2. { 3. //This deletes the file from the database, before returning the name of the file. 4. $name = $this->files->delete($id); 5. unlink('files/'.$name); 6. redirect('profile'); 7. } And this code to our files model: view plaincopy to clipboardprint? 1. function delete($fileid) 2. { 3. $query = $this->db->get_where('files',array('id'=>$fileid)); 4. $result = $query->result(); 5. $query = $this->db->delete('files', array('id'=>$fileid)); 6. return $result[0]->name; 7. } The first controller should be very easy to understand. It calls the delete function from the files model (which we defined at the same time), which generates the name of the file. It then uses a basic PHP function to delete the file with that name in the files directory. Finally, it sends back to the users profile (which is now minus one file).
net.tutsplus.com/tutorials/php/creating-a-file-hosting-site-with-codeigniter/ 10/12

29/12/13

Creating a File Hosting Site with CodeIgniter | Nettuts+

The model is slightly more complex. It needs to return the name of the file as well as deleting it, so first it queries the database to get the files details. It loads this into the $result variable, and then goes on to delete the file. It then returns the name column of the first row of the array (the only row that the query returned), which is then used in the above controller. Lets try to delete a function:

And click delete

Hooray! It worked. I guess were all done then!

Final Thoughts
Delete Files Of course, this code should not be run on a server without some serious improvements. Here are a few major problems with it: The passwords are all unencrypted. This means that if anyone should break into your database, they will be able to steal all of your users data with minimal effort. As Im sure youll all agree: not good. This could easily be solved by adding some simple hashing to the passwords. The files are not private. A user may want to ensure that the files they upload are only visible by them, and not by someone who just guesses a bunch of urls. This would probably require another controller for serving the files (which checks for session data). The script does not check that files exist before writing files. This could cause conflicts with your files, or it could result in file data being overwritten. Whichever: not good. This could be solved with a simple DB check to ensure that the file has not been taken, and could be minimized by giving users their own directories within the files folder. No errors are being generated. This doesnt exactly help the user find out what theyre doing wrong, and although this isnt (too) much of a problem on such a small site with such limited actions, it still could be improved. All in all, youve created quite a powerful little web application, especially due to the small amount of code that you had to write. Due to Codeigniters nature, its quite easily extended, both to resolve the above problems, and to add new features, like renaming files. I also hope that this tutorial taught you a bit about using MVC concepts, and the power that they bring: by simply adjusted the models on our application, we can swap our the DB for text files, XML or anything, and by changing the views, we can completely re-theme without breaking functionality. Amazing! Subscribe to the NETTUTS RSS Feed for more daily web development tuts and articles.
Lik e 66 people like this. Be the first of your friends.

net.tutsplus.com/tutorials/php/creating-a-file-hosting-site-with-codeigniter/

11/12

29/12/13

Creating a File Hosting Site with CodeIgniter | Nettuts+

Tags:codeigniter

By Henry Irish
This author has yet to write their bio.

Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more

net.tutsplus.com/tutorials/php/creating-a-file-hosting-site-with-codeigniter/

12/12