PHP Tutorial

Step 14

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:

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.