OOP CRUD MVC Web App With PDO Using Core PHP
This is a simple PHP web application developed using OOP Pattern, PDO, and Core PHP. This project will help you learn how to develop a web application with MVC (Model-View-Controller). For those who are not familiar in MVC, the MVC (Model-View-Controller) is an application/software design pattern comprised of three interconnected parts which are the model, view, and controller.
Talking about the web application, this has a registration page which the user can create their new account, and also it has a secure login feature. The web application is a kind of the application of a post which user can create, edit, read, and delete posts. The delete and edit post-action buttons are only visible to users who created the post. The application is composed of 3 Controllers which are the Pages, Posts, and Users. The Pages Controller handles the public pages, Posts Controllers handles the posts side, and Users Controllers handles the users' login and registrations.
Controllers:
Pages.php
- <?php
- class Pages extends Controller {
- public function __construct(){
- }
- public function index(){
- if(isLoggedIn()){
- redirect('posts');
- }
- $data = [
- 'title' => 'SharePosts',
- 'description' => 'Simple social network built on the Emmizy MVC framework',
- 'info' => 'You can contact me with the following details below if you like my program and willing to offer me a contract and work on your project',
- 'name' => 'Omonzebaguan Emmanuel',
- 'location' => 'Nigeria, Edo State',
- 'contact' => '+2348147534847',
- ];
- $this->view('pages/index', $data);
- }
- public function about(){
- $data = [
- 'title' => 'About Us',
- 'description' => 'App to share posts with other users'
- ];
- $this->view('pages/about', $data);
- }
- public function contact(){
- $data = [
- 'title' => 'Contact Us',
- 'description' => 'You can contact us through this medium',
- 'info' => 'You can contact me with the following details below if you like my program and willing to offer me a contract and work on your project',
- 'name' => 'Omonzebaguan Emmanuel',
- 'location' => 'Nigeria, Edo State',
- 'contact' => '+2348147534847',
- ];
- $this->view('pages/contact', $data);
- }
- }
Posts.php
- <?php
- class Posts extends Controller{
- public function __construct()
- {
- if(!isLoggedIn()){
- redirect('users/login');
- }
- //new model instance
- $this->postModel = $this->model('Post');
- $this->userModel = $this->model('User');
- }
- public function index(){
- $posts = $this->postModel->getPosts();
- $data = [
- 'posts' => $posts
- ];
- $this->view('posts/index', $data);
- }
- //add new post
- public function add(){
- if($_SERVER['REQUEST_METHOD'] == 'POST'){
- $data = [
- 'user_id' => $_SESSION['user_id'],
- 'title_err' => '',
- 'body_err' => '',
- ];
- $data['title_err'] = 'Please enter post title';
- }
- $data['body_err'] = 'Please enter the post content';
- }
- //validate error free
- if($this->postModel->addPost($data)){
- flash('post_message', 'Your post have been added');
- redirect('posts');
- }else{
- }
- //laod view with error
- }else{
- $this->view('posts/add', $data);
- }
- }else{
- $data = [
- ];
- $this->view('posts/add', $data);
- }
- }
- //show single post
- public function show($id){
- $post = $this->postModel->getPostById($id);
- $user = $this->userModel->getUserById($post->user_id);
- $data = [
- 'post' => $post,
- 'user' => $user
- ];
- $this->view('posts/show', $data);
- }
- //edit post
- public function edit($id){
- if($_SERVER['REQUEST_METHOD'] == 'POST'){
- $data = [
- 'id' => $id,
- 'user_id' => $_SESSION['user_id'],
- 'title_err' => '',
- 'body_err' => '',
- ];
- //validate the title
- $data['title_err'] = 'Please enter post title';
- }
- //validate the body
- $data['body_err'] = 'Please enter the post content';
- }
- //validate error free
- if($this->postModel->updatePost($data)){
- flash('post_message', 'Your post have been updated');
- redirect('posts');
- }else{
- }
- //laod view with error
- }else{
- $this->view('posts/edit', $data);
- }
- }else{
- //check for the owner and call method from post model
- $post = $this->postModel->getPostById($id);
- if($post->user_id != $_SESSION['user_id']){
- redirect('posts');
- }
- $data = [
- 'id' => $id,
- 'title' => $post->title,
- 'body' => $post->body
- ];
- $this->view('posts/edit', $data);
- }
- }
- //delete post
- public function delete($id){
- if($_SERVER['REQUEST_METHOD'] == 'POST'){
- //check for owner
- $post = $this->postModel->getPostById($id);
- if($post->user_id != $_SESSION['user_id']){
- redirect('posts');
- }
- //call delete method from post model
- if($this->postModel->deletePost($id)){
- flash('post_message', 'Post Removed');
- redirect('posts');
- }else{
- }
- }else{
- redirect('posts');
- }
- }
- }
Users.php
- <?php
- class Users extends Controller{
- public function __construct()
- {
- $this->userModel = $this->model('User');
- }
- public function register(){
- if ($_SERVER['REQUEST_METHOD'] == 'POST'){
- // process form
- $data = [
- 'name_err' => '',
- 'email_err' => '',
- 'password_err' => '',
- 'confirm_password_err' => ''
- ];
- //valide name
- $data['name_err'] = 'Please enter name';
- }
- //validate email
- $data['email_err'] = 'Please enter email';
- }else{
- //check for email
- if($this->userModel->findUserByEmail($data['email'])){
- $data['email_err'] = 'Email already exist';
- }
- }
- //validate password
- $data['password_err'] = 'Please enter your password';
- $data['password_err'] = 'Password must be atleast six characters';
- }
- //validate confirm password
- $data['confirm_password_err'] = 'Please confirm password';
- }else{
- if($data['password'] != $data['confirm_password'])
- {
- $data['confirm_password_err'] = 'Password does not match';
- }
- }
- //make sure error are empty
- $data['password'] = password_hash($data['password'], PASSWORD_DEFAULT);
- if($this->userModel->register($data)){
- flash('register_success', 'you are registerd you can login now');
- redirect('users/login');
- }
- }else{
- $this->view('users/register', $data);
- }
- }else{
- //init data
- $data = [
- 'name' => '',
- 'email' => '',
- 'password' => '',
- 'confirm_password' => '',
- 'name_err' => '',
- 'email_err' => '',
- 'password_err' => '',
- 'confirm_password_err' => ''
- ];
- //load view
- $this->view('users/register', $data);
- }
- }
- public function login(){
- if ($_SERVER['REQUEST_METHOD'] == 'POST'){
- // process form
- $data = [
- 'email_err' => '',
- 'password_err' => ''
- ];
- //validate email
- $data['email_err'] = 'Please enter email';
- }else{
- if($this->userModel->findUserByEmail($data['email'])){
- //user found
- }else{
- $data['email_err'] = 'User not found';
- }
- }
- //validate password
- $data['password_err'] = 'Please enter your password';
- $data['password_err'] = 'Password must be atleast six characters';
- }
- //make sure error are empty
- $loggedInUser = $this->userModel->login($data['email'], $data['password']);
- if($loggedInUser){
- //create session
- $this->createUserSession($loggedInUser);
- }else{
- $data['password_err'] = 'Password incorrect';
- $this->view('users/login', $data);
- }
- }else{
- $this->view('users/login', $data);
- }
- }else{
- //init data f f
- $data = [
- 'email' => '',
- 'password' => '',
- 'email_err' => '',
- 'password_err' => ''
- ];
- //load view
- $this->view('users/login', $data);
- }
- }
- //setting user section variable
- public function createUserSession($user){
- $_SESSION['user_id'] = $user->id;
- $_SESSION['name'] = $user->name;
- $_SESSION['email'] = $user->email;
- redirect('posts/index');
- }
- //logout and destroy user session
- public function logout(){
- redirect('users/login');
- }
- }
The application has of 2 model files for Posts and Users. The models consist all the scripts that manages the data in the database and retrieves data.
Models:
Posts.php
- <?php
- class Post {
- private $db;
- public function __construct()
- {
- $this->db = new Database;
- }
- public function getPosts(){
- $this->db->query('SELECT *,
- posts.id as postId,
- user.id as userId,
- posts.created_at as postCreated,
- user.created_at as userCreated
- FROM posts
- INNER JOIN user
- ON posts.user_id = user.id
- ORDER BY posts.created_at DESC');
- $result = $this->db->resultSet();
- return $result;
- }
- public function addPost($data){
- $this->db->query('INSERT INTO posts(user_id, title, body) VALUES (:user_id, :title, :body)');
- $this->db->bind(':user_id', $data['user_id']);
- $this->db->bind(':title', $data['title']);
- $this->db->bind(':body', $data['body']);
- //execute
- if($this->db->execute()){
- return true;
- }else{
- return false;
- }
- }
- public function getPostById($id){
- $this->db->query('SELECT * FROM posts WHERE id = :id');
- $this->db->bind(':id', $id);
- $row = $this->db->single();
- return $row;
- }
- public function updatePost($data){
- $this->db->query('UPDATE posts SET title = :title, body = :body WHERE id = :id');
- $this->db->bind(':id', $data['id']);
- $this->db->bind(':title', $data['title']);
- $this->db->bind(':body', $data['body']);
- //execute
- if($this->db->execute()){
- return true;
- }else{
- return false;
- }
- }
- //delete a post
- public function deletePost($id){
- $this->db->query('DELETE FROM posts WHERE id = :id');
- $this->db->bind(':id', $id);
- if($this->db->execute()){
- return true;
- }else{
- return false;
- }
- }
- }
Users.php
- <?php
- class User {
- private $db;
- public function __construct()
- {
- $this->db = new Database;
- }
- //register new user
- public function register($data){
- $this->db->query('INSERT INTO user (name, email, password) VALUES (:name, :email, :password)');
- $this->db->bind(':name', $data['name']);
- $this->db->bind(':email', $data['email']);
- $this->db->bind(':password', $data['password']);
- if($this->db->execute()){
- return true;
- }else{
- return false;
- }
- }
- //find user by email
- public function findUserByEmail($email){
- $this->db->query('SELECT * FROM user WHERE email = :email');
- $this->db->bind(':email', $email);
- $row = $this->db->single();
- //check the row
- if($this->db->rowCount() > 0){
- return true;
- }else{
- return false;
- }
- }
- public function login($email, $password){
- $this->db->query('SELECT * FROM user where email = :email');
- $this->db->bind(':email', $email);
- $row = $this->db->single();
- $hash_password = $row->password;
- if(password_verify($password, $hash_password)){
- return $row;
- }else{
- return false;
- }
- }
- public function getUserById($id){
- $this->db->query('SELECT * FROM user WHERE id = :id');
- $this->db->bind(':id', $id);
- $row = $this->db->single();
- return $row;
- }
- }
And for the views, these are the files that contain the user-interface scripts such as the login page, posts page, and registration page interfaces. The application also uses .htaccess
that rewrites the rules for redirecting the URL to the exact subdirectory/link/filename and this will give users user-friendly URLs. It uses also Bootstrap Framework that helps us make pleasant user interfaces.
Demo
This web application is free to download. Feel Free to download and modify the source code to enhance and develop your programming capabilities in PHP Language.
How to Run
Requirements- Download and Install any local web server such as XAMPP/WAMP.
- Download the provided source code zip file. (download button is located below)
- Open your XAMPP/WAMP's Control Panel and start the
Apache
andMySQL
. - Extract the downloaded source code zip file.
- If you are using XAMPP, copy the extracted source code folder and paste it into the XAMPP's "htdocs" directory. And If you are using WAMP, paste it into the "www" directory.
- Browse the
PHPMyAdmin
in a browser. i.e.http://localhost/phpmyadmin
- Create a new database naming
shareposts
. - Import the provided
SQL
file. The file is known asshareposts.sql
located inside the database folder. - Browse the Web Application in a browser. i.e.
http://localhost/shareposts
.
I hope this will help you with what you are looking for and helps you to understand and learn to develop a web application using Core PHP/MVX/OOP/PDO.
Enjoy :)
Note: Due to the size or complexity of this submission, the author has submitted it as a .zip file to shorten your download time. After downloading it, you will need a program like Winzip to decompress it.
Virus note: All files are scanned once-a-day by SourceCodester.com for viruses, but new viruses come out every day, so no prevention program can catch 100% of them.
FOR YOUR OWN SAFETY, PLEASE:
1. Re-scan downloaded files using your personal virus checker before using it.
2. NEVER, EVER run compiled files (.exe's, .ocx's, .dll's etc.)--only run source code.
Add new comment
- 14570 views