PHP Tutorial
In this tutorial we will create a simple twitter copycat. In step 15 we will allow users to upload images into their profiles.
Step 15
1. We will now allow users to upload a photo into their profile. This photo will be displayed alongside their tweets.
We start by adding a new input field to the user registration form (templates/users/register.tpl):
<label>Photo:<br>
<input type="file" name="photo">
</label>
When uploading files, our form has to use the post method and its enctype must be multipart/form-data:
<form action="{$BASE_URL}actions/users/register.php" method="post" enctype="multipart/form-data">
2. Our actions/users/register.php file we now receive this file in a special $_FILES array. This array contains the following fields:
- error: error message, if any
- name: original filename
- type: the file type (sen’t by the browser, don’t trust this value)
- size: the file size in bytes
- tmp_name: the temporary file where the file has been stored
3. To move our image to its final destination we use the move_uploaded_file function. This function verifies if the file that is being moved has indeed been uploaded by the user (for security reasons);
We only want to move the photo if the user has been created. So we will had this inside our try/catch block:
$photo = $_FILES['photo'];
$extension = end(explode(".", $photo["name"]));
try {
createUser($realname, $username, $password);
move_uploaded_file($photo["tmp_name"], $BASE_DIR . "images/users/" . $username . '.' . $extension); // this is dangerous
} catch (PDOException $e) {
...
}
Don’t forget to create the images/users folder.
4. Now we just have to show the image next to each tweet. In templates/tweets/list.tpl:
<article class="tweet-data">
<img src="{$BASE_URL}images/users/{$tweet.username}.png">
<span class="realname">{$tweet.realname}</span>
<a href="{$BASE_URL}pages/tweets/list_user.php?username={$tweet.username}" class="username">@{$tweet.username}</a>
<span class="time">{$tweet.time}</span>
<div class="tweet-text">{$tweet.text}</div>
</article>
5. In some cases, the stored file will have the wrong permissions you can change those permissions directly in PHP usig the chmod function. Right after moving the uploaded file:
chmod($BASE_DIR . "images/users/" . $username . '.' . $extension, 0644);
6. And finally some styling:
.tweet-data {
min-height: 64px;
}
.tweet-data img {
width: 64px;
height: 64px;
float: left;
margin-right: 10px;
}
7. We could also create a default image for users without a photo. For example in images/assets/default.png.
Testing if a file exists is easy with the file_exists function. We could pass some information about which file to display into smarty.
In our pages/tweets/list_all.php page, let’s add the following code after retrieving our tweets from the database:
foreach ($tweets as $key => $tweet) {
unset($photo);
if (file_exists($BASE_DIR.'images/users/'.$tweet['username'].'.png'))
$photo = 'images/users/'.$tweet['username'].'.png';
if (file_exists($BASE_DIR.'images/users/'.$tweet['username'].'.jpg'))
$photo = 'images/users/'.$tweet['username'].'.jpg';
if (!$photo) $photo = 'images/assets/default.png';
$tweets[$key]['photo'] = $photo;
}
Then in our list.tpl template:
<img src="{$BASE_URL}{$tweet.photo}">
The complete code after step 15 can be found here.