To build a registration form with an image, we will use the PHP native move_uploaded_file
function. The logic involves inserting the file path into your database. This is an efficient way of fetching the image from your database and will speed up the loading time of your web page.
In this tutorial, we will build a registration form with image upload. So when users register, they need to upload an image.
We will need a simple database table to store user-related information, such as email, password as well as the photo uploaded.
Run the command below in your MySQL console to create a users
table:
CREATE TABLE users (
id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
email VARCHAR(30) UNIQUE NOT NULL,
password VARCHAR(250) NOT NULL,
photo VARCHAR(250) NOT NULL
)
Next, we will create a function that can build a PDO connection.
function connection($host, $database, $username, $password)
{
try {
$conn = new PDO("mysql:host=$host;dbname=$database", $username, $password);
// set the PDO error mode to exception
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $conn;
} catch (PDOException $e) {
echo "Connection failed: ".$e->getMessage();
}
}
This function uses PDO, which is the common practice in PHP when working with various databases.
Now we need to create a function to work with file upload. Let's call it upload
. This function takes a file object and uploads it to the destination specified:
function upload($file, $des) {
$name = $file['name'];
$tmp_name = $file['tmp_name'];
$size = $file['size'];
$error = $file['error'];
$ext = explode('.', $name);
$ext = strtolower(end($ext));
$allowed = ['jpg', 'jpeg', 'png', 'gif'];
if (in_array($ext, $allowed)) {
if ($error === 0) {
if ($size <= 1000000) {
$new_name = uniqid('', true) . '.' . $ext;
$destination = $des . $new_name;
if (move_uploaded_file($tmp_name, $destination)) {
return true;
}
} else {
echo "Your file is too big!";
}
} else {
echo "There was an error uploading your file!";
}
} else {
echo "You cannot upload files of this type!";
}
}
The key function is move_uploaded_file
, which takes care of moving files for us.
This function will only return true
when the file is successfully moved, otherwise, it will return a string to indicate errors.
This function will upload all the files into a folder uploads
and store the path to the photo
column of users
table. So you will need to create an empty folder called uploads
.
The last piece of the PHP function takes users' information and stores them to the database table users
:
function register($connection, $email, $password, $photo)
{
$passwordHash = password_hash($password, PASSWORD_DEFAULT);
$sql = "INSERT INTO users ( email, password, photo) VALUES ( :email, :password, :photo)";
$stmt = $connection->prepare($sql);
$stmt->execute(['email' => $email, 'password' => $passwordHash, 'photo' => $photo]);
}
Please note we should never store a plain password in a database. Here we are using password_hash
to have the password before storing them.
Let's consolidate all the functions above and put them in a centralized file functions.php
:
<?php
// sql statement to create a table for users
$sql = "CREATE TABLE users (
id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
email VARCHAR(30) NOT NULL,
password VARCHAR(30) NOT NULL,
photo VARCHAR(250) NOT NULL
)";
function connection($host, $database, $username, $password)
{
try {
$conn = new PDO("mysql:host=$host;dbname=$database", $username, $password);
// set the PDO error mode to exception
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $conn;
} catch (PDOException $e) {
echo "Connection failed: ".$e->getMessage();
}
}
function upload($file, $des) {
$name = $file['name'];
$tmp_name = $file['tmp_name'];
$size = $file['size'];
$error = $file['error'];
$ext = explode('.', $name);
$ext = strtolower(end($ext));
$allowed = ['jpg', 'jpeg', 'png', 'gif'];
if (in_array($ext, $allowed)) {
if ($error === 0) {
if ($size <= 1000000) {
$new_name = uniqid('', true) . '.' . $ext;
$destination = $des . $new_name;
if (move_uploaded_file($tmp_name, $destination)) {
return true;
}
} else {
echo "Your file is too big!";
}
} else {
echo "There was an error uploading your file!";
}
} else {
echo "You cannot upload files of this type!";
}
}
function register($connection, $email, $password, $photo)
{
$passwordHash = password_hash($password, PASSWORD_DEFAULT);
$sql = "INSERT INTO users ( email, password, photo) VALUES ( :email, :password, :photo)";
$stmt = $connection->prepare($sql);
$stmt->execute(['email' => $email, 'password' => $passwordHash, 'photo' => $photo]);
}
?>
Lastly, we build the registration page using Tailwind CSS:
<?php
include 'functions.php';
$msg = '';
$success = true;
if (!empty($_POST)) {
$email = $_POST['email'];
$password = $_POST['password'];
$confirmPassword = $_POST['confirm_password'];
if ($password !== $confirmPassword) {
$success = false;
$msg = 'Passwords do not match!';
}
if ($success) {
$filePath = dirname(__FILE__).'/uploads/';
$success = $msg = upload($_FILES['photo'], $filePath);
}
if ($success) {
$connection = connection('localhost', 'reg_form', 'root', 'root');
register($connection, $email, $password, $filePath);
$msg = 'You account has been registered!';
}
}
?>
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body>
<div class="">
<div class="max-w-xl mx-auto h-screen flex flex-col items-center justify-center space-y-4">
<?php if (!empty($msg) && !$success): ?>
<div class="w-full bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative" role="alert">
<strong class="font-bold">Error!</strong>
<span class="block sm:inline"><?= $msg; ?></span>
</div>
<?php endif; ?>
<?php if (!empty($msg) && $success): ?>
<div class="w-full bg-green-100 border border-green-400 text-green-700 px-4 py-3 rounded relative"
role="alert">
<strong class="font-bold">Success!</strong>
<span class="block sm:inline"><?= $msg; ?></span>
</div>
<?php endif; ?>
<form class="bg-white shadow-md rounded px-8 pt-6 pb-8 mb-4 flex flex-col w-full"
enctype="multipart/form-data"
action="index.php"
method="post">
<div class="mb-6">
<label class="block text-gray-700 text-sm font-bold mb-2" for="password">
Email
</label>
<input class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
name="email"
id="email"
type="text"
placeholder="Email">
</div>
<div class="mb-6">
<label class="block text-gray-700 text-sm font-bold mb-2" for="password">
Password
</label>
<input class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
name="password"
id="password"
type="password"
placeholder="Password">
</div>
<div class="mb-6">
<label class="block text-gray-700 text-sm font-bold mb-2" for="password">
Confirm Password
</label>
<input class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
name="confirm_password"
id="confirm_password"
type="password"
placeholder="Confirm Password">
</div>
<div class="mb-6">
<label class="block text-gray-700 text-sm font-bold mb-2" for="password">
Photo
</label>
<input class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
name="photo"
id="file"
type="file"
placeholder="Photo">
</div>
<div class="mb-6">
<button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline"
type="submit">
Sign Up
</button>
</div>
</form>
</div>
</div>
</body>
</html>
Take a look at the top of the page, that is where we make use of the functions to store user information:
<?php
include 'functions.php';
$msg = '';
$success = true;
if (!empty($_POST)) {
$email = $_POST['email'];
$password = $_POST['password'];
$confirmPassword = $_POST['confirm_password'];
if ($password !== $confirmPassword) {
$success = false;
$msg = 'Passwords do not match!';
}
if ($success) {
$filePath = dirname(__FILE__).'/uploads/';
$success = $msg = upload($_FILES['photo'], $filePath);
}
if ($success) {
$connection = connection('localhost', 'reg_form', 'root', 'root');
register($connection, $email, $password, $filePath);
$msg = 'You account has been registered!';
}
}
We first include the shared functions.php
file. When a POST
is sent, we validate the password and make sure the file can be uploaded. Lastly, we store them in the database.
Note that for this piece of code to work for you, you need to update the credentials at $connection = connection('localhost', 'reg_form', 'root', 'root');
, you should use your credentials to connect to the database.
Now everything should work as expected: