Home PHP

PHP, MySQL and OOP CRUD Tutorial – Step By Step Guide!

php-object-oriented-crud-example-oop

Previously, we learned how to program with PHP and MySQL CRUD tutorial for beginners. This time, we will learn object-oriented programming with PHP & MySQL. Again, we will have CRUD (Create, Read, Update, Delete, Search and more) operations example. Thank you for being a part of this journey!

This post will include the following contents:

1.0 Overview
2.0 Program Output
3.0 Database Table Structure

4.0 Create the Template Files
4.1 Download jQuery, Bootstrap, and Bootbox.js
4.2 Header Code with header.php
4.3 Footer Code with footer.php

5.0 Creating Record in PHP the OOP Way
5.1 Create a file: create_product.php
5.2 Create a “Read Products” Button
5.3 Get a Database Connection
5.4 Create the Database Configuration Class
5.5 Create a Form in create_product.php
5.6 Loop Through the Categories Records to show as Drop-down
5.7 Create the Object Class for Categories
5.8 Prepare readName() method
5.9 Code when the Form was Submitted
5.10 Create the Object Class for Products

6.0 Reading and Paging Record in PHP the OOP Way
6.1 Create File: index.php
6.2 Add a “Create Product” button
6.3 Configure Pagination Variables
6.4 Retrieve Records from the Database
6.5 Add readAll() Method in product.php
6.6 Display data from the database
6.7 Put the Read, Edit and Delete Action Buttons
6.8 Create paging.php for Paging Buttons
6.9 Add the countAll() method in product.php
6.10 Include paging.php in index.php

7.0 Updating Record in PHP the OOP Way
7.1 Create File: update_product.php
7.2 Create a “Read Products” Button
7.3 Retrieve One Product Information Based on the Given ID.
7.4 Add readOne() method in the Product Object Class.
7.5 Put the Values in the Form.
7.6 Loop Through the Categories Records to show as Drop-down
7.7 Code When Form was Submitted
7.8 Update Code in the Product Class

8.0 Read One Record in PHP the OOP Way
8.1 Create read_one.php file
8.2 Read one record based on given record ID
8.3 Display record on HTML table

9.0 Deleting Record in PHP the OOP Way
9.1 Put this JavaScript Code in footer.php
9.2 Create delete_product.php
9.3 Delete Code in Product Class

10.0 Search Records in PHP the OOP Way
10.1 Change index.php
10.2 Create read_template.php
10.3 Create core.php in “config” folder
10.4 Change paging.php code
10.5 Include core.php and read_template.php
10.6 Create search.php
10.7 Add search() and countAll_BySearch() methods
10.8 Output

11.0 File Upload in PHP the OOP Way
11.1 Change HTML form
11.2 Set value of “image” field
11.3 Change create() method
11.4 Call uploadPhoto() method
11.5 Add uploadPhoto() method
11.6 Validate submitted file
11.7 Return error messages
11.8 Show uploaded image file

12.0 Download LEVEL 1 Source Code
13.0 Download LEVEL 2 Source Code
14.0 Download LEVEL 3 Source Code
15.0 Download ALL LEVELS in Separate Packages

16.0 What’s Next?
17.0 Related Source Codes
18.0 Some Notes

1.0 Overview

Our tutorial for today is about creating a simple database application. We can achieve it with the help of this PHP OOP CRUD tutorial. You can use this knowledge in your current or future projects.

We use Bootstrap so that our application will have a decent UI. If you’re not yet familiar what Bootstrap is, and you want to learn how to use it in few steps, I highly recommend following our Bootstrap tutorial first.

There are so many PHP object oriented programming tutorials on the web today, they have different examples and implementations. Some might be completely correct, some maybe not.

I’m writing this tutorial with a clear goal: to give the best PHP OOP CRUD tutorial for beginners. I welcome your comments and suggestions to help me achieve this.

We want to learn the correct PHP OOP implementation. There are PHP frameworks such as CakePHP, CodeIgniter, and Laravel that correctly do it.

Those things are one step higher. For now, we will learn object oriented programming with PHP & MySQL. Working with a PHP framework should be easy after following this tutorial.

2.0 Program Output – PHP OOP CRUD Tutorial

We usually have three LEVELS of source code output. But WHY? Because I believe in "Learning Progression" to ensure efficient learning. Learn more

Below are some screenshots of our script’s output. You can click an image to view the larger version of it. Use the left and right arrow to navigate through the screenshots.

Please note that the following images are just output previews. New features might be added already the time you are reading this.

2.1 LEVEL 1 Source Code Output


2.2 LEVEL 2 Source Code Output


2.3 LEVEL 3 Source Code Output


The LEVEL 2 and LEVEL 3 source code outputs proves that you can add and customize more features. It’s easier and faster if you will learn by following our tutorial below.

Downloading our source codes is your huge advantage as well. For now, let’s proceed to the step by step tutorial of our LEVEL 1 source code. Enjoy!

3.0 Database Table Structure

The files products.sql and categories.sql are also included in the code download, located at the sql/ folder.

3.1 Products Table

We use products as objects in this PHP OOP CRUD Tutorial. Database table and dummy data were provided below, you can instantly run this in your PhpMyAdmin after creating your database.

-- Table structure for table `products`
CREATE TABLE IF NOT EXISTS `products` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(32) NOT NULL,
  `description` text NOT NULL,
  `price` int(11) NOT NULL,
  `category_id` int(11) NOT NULL,
  `created` datetime NOT NULL,
  `modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=38 ;

-- Dumping data for table `products`
INSERT INTO `products` (`id`, `name`, `description`, `price`, `category_id`, `created`, `modified`) VALUES
(1, 'LG P880 4X HD', 'My first awesome phone!', 336, 3, '2014-06-01 01:12:26', '2014-05-31 17:12:26'),
(2, 'Google Nexus 4', 'The most awesome phone of 2013!', 299, 2, '2014-06-01 01:12:26', '2014-05-31 17:12:26'),
(3, 'Samsung Galaxy S4', 'How about no?', 600, 3, '2014-06-01 01:12:26', '2014-05-31 17:12:26'),
(6, 'Bench Shirt', 'The best shirt!', 29, 1, '2014-06-01 01:12:26', '2014-05-31 02:12:21'),
(7, 'Lenovo Laptop', 'My business partner.', 399, 2, '2014-06-01 01:13:45', '2014-05-31 02:13:39'),
(8, 'Samsung Galaxy Tab 10.1', 'Good tablet.', 259, 2, '2014-06-01 01:14:13', '2014-05-31 02:14:08'),
(9, 'Spalding Watch', 'My sports watch.', 199, 1, '2014-06-01 01:18:36', '2014-05-31 02:18:31'),
(10, 'Sony Smart Watch', 'The coolest smart watch!', 300, 2, '2014-06-06 17:10:01', '2014-06-05 18:09:51'),
(11, 'Huawei Y300', 'For testing purposes.', 100, 2, '2014-06-06 17:11:04', '2014-06-05 18:10:54'),
(12, 'Abercrombie Lake Arnold Shirt', 'Perfect as gift!', 60, 1, '2014-06-06 17:12:21', '2014-06-05 18:12:11'),
(13, 'Abercrombie Allen Brook Shirt', 'Cool red shirt!', 70, 1, '2014-06-06 17:12:59', '2014-06-05 18:12:49'),
(25, 'Abercrombie Allen Anew Shirt', 'Awesome new shirt!', 999, 1, '2014-11-22 18:42:13', '2014-11-21 19:42:13'),
(26, 'Another product', 'Awesome product!', 555, 2, '2014-11-22 19:07:34', '2014-11-21 20:07:34'),
(27, 'Bag', 'Awesome bag for you!', 999, 1, '2014-12-04 21:11:36', '2014-12-03 22:11:36'),
(28, 'Wallet', 'You can absolutely use this one!', 799, 1, '2014-12-04 21:12:03', '2014-12-03 22:12:03'),
(30, 'Wal-mart Shirt', '', 555, 2, '2014-12-13 00:52:29', '2014-12-12 01:52:29'),
(31, 'Amanda Waller Shirt', 'New awesome shirt!', 333, 1, '2014-12-13 00:52:54', '2014-12-12 01:52:54'),
(32, 'Washing Machine Model PTRR', 'Some new product.', 999, 1, '2015-01-08 22:44:15', '2015-01-07 23:44:15');

3.2 Categories Table

We are going to have “Fashion”, “Electronics” and “Motors” as categories in our example. I got those three category ideas from eBay, haha!

-- Table structure for table `categories`
CREATE TABLE IF NOT EXISTS `categories` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(256) NOT NULL,
  `created` datetime NOT NULL,
  `modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=4 ;

-- Dumping data for table `categories`
INSERT INTO `categories` (`id`, `name`, `created`, `modified`) VALUES
(1, 'Fashion', '2014-06-01 00:35:07', '2014-05-30 17:34:33'),
(2, 'Electronics', '2014-06-01 00:35:07', '2014-05-30 17:34:33'),
(3, 'Motors', '2014-06-01 00:35:07', '2014-05-30 17:34:54');

4.0 Create the Template Files

To reduce some mess from our code, we will create these two template files: header.php and footer.php.

I’m actually not sure what these files are called so for now we’ll call them “template files”. It wraps the main content of our web pages. We can imagine it like this:

<?php
include_once 'header.php';
?>
// main content of web page must be here!
<?php
include_once 'footer.php';
?>

4.1 Download jQuery, Bootstrap, and Bootbox.js

First, please create a “libs” folder. This folder will contain our library files.

Inside the “libs” folder, create a “js” folder. This will contain our JavaScript library files.

Still inside the “libs” folder, create a “css” folder. This will contain our user interface, style or any CSS related files.

jQuery will make Bootstrap and Booxbox work. Download it here and put it inside “/libs/js/” folder. If you don’t know jQuery yes, please learn our tutorial here.

Bootstrap will make our simple app look visually good. Download it here, extract and put it inside “/libs/css/” folder. If you don’t know Bootstrap yet, please learn from our tutorial here.

Bootbox will help us. Download it here and put it inside “/libs/js/” folder.

4.2 Header Code with header.php

This header.php file will be included at the beginning of some of our core files so that we won’t have to write the same header codes every time. Very useful and time saver for this PHP OOP CRUD Tutorial.

<!DOCTYPE html>
<html lang="en">
<head>

    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <title><?php echo $page_title; ?></title>

    <!-- some custom CSS -->
    <style>
    .left-margin{
        margin:0 .5em 0 0;
    }

    .right-button-margin{
        margin: 0 0 1em 0;
        overflow: hidden;
    }

    /* some changes in bootstrap modal */
    .modal-body {
        padding: 20px 20px 0px 20px !important;
        text-align: center !important;
    }

    .modal-footer{
        text-align: center !important;
    }
	</style>

    <!-- Bootstrap CSS -->
    <link href="libs/css/bootstrap/dist/css/bootstrap.css" rel="stylesheet" media="screen" />

</head>
<body>

    <!-- container -->
    <div class="container">

		<?php
		// show page header
		echo "<div class='page-header'>";
			echo "<h1>{$page_title}</h1>";
		echo "</div>";
		?>

4.3 Footer Code with footer.php

This footer.php file will be included at the end of some of our core files so that we won’t have to write the same footer codes every time.

    </div>
    <!-- /container -->

<!-- jQuery library -->
<script src="libs/js/jquery.js"></script>

<!-- bootstrap JavaScript -->
<script src="libs/css/bootstrap/dist/js/bootstrap.min.js"></script>
<script src="libs/css/bootstrap/docs-assets/js/holder.js"></script>

<!-- bootbox library -->
<script src="libs/js/bootbox.min.js"></script>

<!-- HTML5 Shiv and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->

</body>
</html>

5.0 Creating Record in PHP the OOP Way

5.1 Create a file: create_product.php

First, create a file with a name “create_product.php” and put the following code inside it.

<?php
// set page headers
$page_title = "Create Product";
include_once "header.php";

// contents will be here

// footer
include_once "footer.php";
?>

5.2 Create a “Read Products” Button

The following code will render a button. Replace the comments “contents will be here” of the previous section with the following.

echo "<div class='right-button-margin'>";
    echo "<a href='index.php' class='btn btn-default pull-right'>Read Products</a>";
echo "</div>";

5.3 Get a Database Connection

We can use it for retrieving categories or saving new product record later. Put the following code before “set page headers” comments of section 5.1 above.

// include database and object files
include_once 'config/database.php';
include_once 'objects/product.php';
include_once 'objects/category.php';

// get database connection
$database = new Database();
$db = $database->getConnection();

// pass connection to objects
$product = new Product($db);
$category = new Category($db);

5.4 Create the Database Configuration Class

Getting a database connection will not work without this class. This class file will be included in most PHP files of our PHP OOP CRUD Tutorial. Create a “config” folder and inside that folder, create a “database.php” file. Open that file and put the following code.

<?php
class Database{

	// specify your own database credentials
	private $host = "change_to_your_db_host";
	private $db_name = "change_to_your_db_name";
	private $username = "change_to_your_db_username";
	private $password = "change_to_your_db_password";
	public $conn;

	// get the database connection
	public function getConnection(){

		$this->conn = null;

		try{
			$this->conn = new PDO("mysql:host=" . $this->host . ";dbname=" . $this->db_name, $this->username, $this->password);
		}catch(PDOException $exception){
			echo "Connection error: " . $exception->getMessage();
		}

		return $this->conn;
	}
}
?>

5.5 Create a Form in create_product.php

The following code will render an HTML form. Put the following code under section 5.2 code.

<!-- HTML form for creating a product -->
<form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>" method="post">

	<table class='table table-hover table-responsive table-bordered'>

		<tr>
			<td>Name</td>
			<td><input type='text' name='name' class='form-control' /></td>
		</tr>

		<tr>
			<td>Price</td>
			<td><input type='text' name='price' class='form-control' /></td>
		</tr>

		<tr>
			<td>Description</td>
			<td><textarea name='description' class='form-control'></textarea></td>
		</tr>

		<tr>
			<td>Category</td>
			<td>
			<!-- categories from database will be here -->
			</td>
		</tr>

		<tr>
			<td></td>
			<td>
				<button type="submit" class="btn btn-primary">Create</button>
			</td>
		</tr>

	</table>
</form>

5.6 Loop Through the Categories Records to show as Drop-down

The following code will retrieve categories and put it in a “select” drop-down. The previous section has a comment “categories from database will be here”, replace that comment with the following code.

	<?php
	// read the product categories from the database
	$stmt = $category->read();

	// put them in a select drop-down
	echo "<select class='form-control' name='category_id'>";
		echo "<option>Select category...</option>";

		while ($row_category = $stmt->fetch(PDO::FETCH_ASSOC)){
			extract($row_category);
			echo "<option value='{$id}'>{$name}</option>";
		}

	echo "</select>";
	?>

5.7 Create the Object Class for Categories

Of course, the previous section won’t work without the category object class. We’ll call it category.php and put it inside objects/ folder.

<?php
class Category{

	// database connection and table name
	private $conn;
	private $table_name = "categories";

	// object properties
	public $id;
	public $name;

	public function __construct($db){
		$this->conn = $db;
	}

	// used by select drop-down list
	function read(){
		//select all data
		$query = "SELECT
					id, name
				FROM
					" . $this->table_name . "
				ORDER BY
					name";	

		$stmt = $this->conn->prepare( $query );
		$stmt->execute();

		return $stmt;
	}
?>

5.8 Prepare readName() method

It will get the category name instead of showing just an ID. Add the following code inside our category.php, this method will be used on section 6.6 code.

// used to read category name by its ID
function readName(){
	
	$query = "SELECT name FROM " . $this->table_name . " WHERE id = ? limit 0,1";

	$stmt = $this->conn->prepare( $query );
	$stmt->bindParam(1, $this->id);
	$stmt->execute();

	$row = $stmt->fetch(PDO::FETCH_ASSOC);
	
	$this->name = $row['name'];
}

5.9 Code when the Form was Submitted

The user will enter the values in the HTML form and when the create (submit) button was clicked, values will be sent via POST request, the code below will save it in the database.

Put the following code before the HTML form in section 5.5 above.

// if the form was submitted - PHP OOP CRUD Tutorial
if($_POST){

	// set product property values
	$product->name = $_POST['name'];
	$product->price = $_POST['price'];
	$product->description = $_POST['description'];
	$product->category_id = $_POST['category_id'];

	// create the product
	if($product->create()){
		echo "<div class='alert alert-success'>Product was created.</div>";
	}

	// if unable to create the product, tell the user
	else{
		echo "<div class='alert alert-danger'>Unable to create product.</div>";
	}
}

5.10 Create the Object Class for Products

The previous section will not work without the product object. Create a folder with a name “objects” and inside that folder, create the “product.php” file. Open that file and put the following code.

<?php
class Product{

	// database connection and table name
	private $conn;
	private $table_name = "products";

	// object properties
	public $id;
	public $name;
	public $price;
	public $description;
	public $category_id;
	public $timestamp;

	public function __construct($db){
		$this->conn = $db;
	}

	// create product
	function create(){

		//write query
		$query = "INSERT INTO
					" . $this->table_name . "
				SET
					name=:name, price=:price, description=:description, category_id=:category_id, created=:created";

		$stmt = $this->conn->prepare($query);

		// posted values
		$this->name=htmlspecialchars(strip_tags($this->name));
		$this->price=htmlspecialchars(strip_tags($this->price));
		$this->description=htmlspecialchars(strip_tags($this->description));
		$this->category_id=htmlspecialchars(strip_tags($this->category_id));

		// to get time-stamp for 'created' field
		$this->timestamp = date('Y-m-d H:i:s');

		// bind values 
		$stmt->bindParam(":name", $this->name);
		$stmt->bindParam(":price", $this->price);
		$stmt->bindParam(":description", $this->description);
		$stmt->bindParam(":category_id", $this->category_id);
		$stmt->bindParam(":created", $this->timestamp);

		if($stmt->execute()){
			return true;
		}else{
			return false;
		}

	}
}
?>

6.0 Reading and Paging Record in PHP the OOP Way

In this part of our PHP OOP CRUD tutorial, we will list the records from the database.

6.1 Create File: index.php

Create a new file and name it “index.php”. This file will show the main page of our web app. Put the following code inside it.

<?php
// set page header
$page_title = "Read Products";
include_once "header.php";

// contents will be here

// set page footer
include_once "footer.php";
?>

6.2 Add a “Create Product” button

The following code will render a button. This button, when clicked, will let us go back to the records list. Replace the “contents will be here” comments in the previous section with the following code.

echo "<div class='right-button-margin'>";
	echo "<a href='create_product.php' class='btn btn-default pull-right'>Create Product</a>";
echo "</div>";

6.3 Configure Pagination Variables

Pagination is very important if you have thousands of data from the database. Put the following code before the “set page header” comment of section 6.1 above.

// page given in URL parameter, default page is one
$page = isset($_GET['page']) ? $_GET['page'] : 1;

// set number of records per page
$records_per_page = 3;

// calculate for the query LIMIT clause
$from_record_num = ($records_per_page * $page) - $records_per_page;

6.4 Retrieve Records from the Database

Now we will retrieve data from the database. Put the following code after the previous section’s code.

// include database and object files
include_once 'config/database.php';
include_once 'objects/product.php';
include_once 'objects/category.php';

// instantiate database and objects
$database = new Database();
$db = $database->getConnection();

$product = new Product($db);
$category = new Category($db);

// query products
$stmt = $product->readAll($from_record_num, $records_per_page);
$num = $stmt->rowCount();

6.5 Add readAll() Method in product.php

Retrieving records in the previous section won’t work without this method. Put the following code inside our “product.php” file which is inside the “objects” folder.

function readAll($from_record_num, $records_per_page){

	$query = "SELECT
				id, name, description, price, category_id
			FROM
				" . $this->table_name . "
			ORDER BY
				name ASC
			LIMIT
				{$from_record_num}, {$records_per_page}";

	$stmt = $this->conn->prepare( $query );
	$stmt->execute();

	return $stmt;
}

6.6 Display data from the database

This time, we will show the list of records to the user. An HTML table will hold our data. Put the following code after the section 6.2 code.

// display the products if there are any
if($num>0){

	echo "<table class='table table-hover table-responsive table-bordered'>";
		echo "<tr>";
			echo "<th>Product</th>";
			echo "<th>Price</th>";
			echo "<th>Description</th>";
			echo "<th>Category</th>";
			echo "<th>Actions</th>";
		echo "</tr>";

		while ($row = $stmt->fetch(PDO::FETCH_ASSOC)){

			extract($row);

			echo "<tr>";
				echo "<td>{$name}</td>";
				echo "<td>{$price}</td>";
				echo "<td>{$description}</td>";
				echo "<td>";
					$category->id = $category_id;
					$category->readName();
					echo $category->name;
				echo "</td>";

				echo "<td>";
					// read one, edit and delete button will be here
				echo "</td>";

			echo "</tr>";

		}

	echo "</table>";

	// paging buttons will be here
}

// tell the user there are no products
else{
	echo "<div class='alert alert-info'>No products found.</div>";
}

6.7 Put the Read, Edit and Delete Action Buttons

The following code will render three buttons: Read, Edit and Delete button.

Inside the “while” loop of the previous section, there is a comment “read one, edit and delete button will be here”, replace that with the following code.

    // read product button
    echo "<a href='read_one.php?id={$id}' class='btn btn-primary left-margin'>";
        echo "<span class='glyphicon glyphicon-list'></span> Read";
    echo "</a>";

    // edit product button
    echo "<a href='update_product.php?id={$id}' class='btn btn-info left-margin'>";
    	echo "<span class='glyphicon glyphicon-edit'></span> Edit";
    echo "</a>";

    // delete product button
    echo "<a delete-id='{$id}' class='btn btn-danger delete-object'>";
    	echo "<span class='glyphicon glyphicon-remove'></span> Delete";
    echo "</a>";

6.8 Create paging.php for Paging Buttons

The following code will show our pagination buttons. Create a new file and name it “paging.php”. Open that file and put the following code.

<?php
echo "<ul class='pagination'>";

// button for first page
if($page>1){
    echo "<li><a href='{$page_url}' title='Go to the first page.'>";
        echo "<<";
    echo "</a></li>";
}

// calculate total pages
$total_pages = ceil($total_rows / $records_per_page);

// range of links to show
$range = 2;

// display links to 'range of pages' around 'current page'
$initial_num = $page - $range;
$condition_limit_num = ($page + $range)  + 1;

for ($x=$initial_num; $x<$condition_limit_num; $x++) {

    // be sure '$x is greater than 0' AND 'less than or equal to the $total_pages'
    if (($x > 0) && ($x <= $total_pages)) {

        // current page
        if ($x == $page) {
            echo "<li class='active'><a href=\"#\">$x <span class=\"sr-only\">(current)</span></a></li>";
        } 

        // not current page
        else {
            echo "<li><a href='{$page_url}page=$x'>$x</a></li>";
        }
    }
}

// button for last page
if($page<$total_pages){
    echo "<li><a href='" .$page_url. "page={$total_pages}' title='Last page is {$total_pages}.'>";
        echo ">>";
    echo "</a></li>";
}

echo "</ul>";
?>

6.9 Add the countAll() method in objects/product.php

The following code will be used to count the total number of records in the database. This will be used for pagination.

Open your product.php file which is inside the “objects” folder. Add the following method in the class.

// used for paging products
public function countAll(){

	$query = "SELECT id FROM " . $this->table_name . "";

	$stmt = $this->conn->prepare( $query );
	$stmt->execute();

	$num = $stmt->rowCount();

	return $num;
}

6.10 Include paging.php in index.php

The following code will show our pagination buttons under our records list. Put the following code after the closing “table” tag of section 6.6 above.

// the page where this paging is used
$page_url = "index.php?";

// count all products in the database to calculate total pages
$total_rows = $product->countAll();

// paging buttons here
include_once 'paging.php';

7.0 Updating Record in PHP the OOP Way

I know our PHP OOP CRUD tutorial is kinda long. Please take a break or drink some coffee first!

7.1 Create File: update_product.php

Create update_product.php file, open that file and put the following code.

<?php
// set page header
$page_title = "Update Product";
include_once "header.php";

// contents will be here

// set page footer
include_once "footer.php";
?>

7.2 Create a “Read Products” Button

The following code will render a button. This button, when clicked, will let us go back to the records list. Replace the previous section’s “contents will be here” comments with the following code.

echo "<div class='right-button-margin'>";
	echo "<a href='index.php' class='btn btn-default pull-right'>Read Products</a>";
echo "</div>";

7.3 Retrieve One Product Information Based on the Given ID.

The following code will retrieve data that will populate our HTML form. This is important because this will let the user know what exactly the record he is updating.

Put the following code before the “set page header” comment of section 7.1 above.

// get ID of the product to be edited
$id = isset($_GET['id']) ? $_GET['id'] : die('ERROR: missing ID.');

// include database and object files
include_once 'config/database.php';
include_once 'objects/product.php';
include_once 'objects/category.php';

// get database connection
$database = new Database();
$db = $database->getConnection();

// prepare objects
$product = new Product($db);
$category = new Category($db);

// set ID property of product to be edited
$product->id = $id;

// read the details of product to be edited
$product->readOne();

7.4 Add readOne() method in the Product Object Class.

The readOne() method used in the previous section will not work without the following code inside /objects/product.php file.

function readOne(){

	$query = "SELECT
				name, price, description, category_id
			FROM
				" . $this->table_name . "
			WHERE
				id = ?
			LIMIT
				0,1";

	$stmt = $this->conn->prepare( $query );
	$stmt->bindParam(1, $this->id);
	$stmt->execute();

	$row = $stmt->fetch(PDO::FETCH_ASSOC);

	$this->name = $row['name'];
	$this->price = $row['price'];
	$this->description = $row['description'];
	$this->category_id = $row['category_id'];
}

7.5 Put the Values in the Form.

Now we can put the latest values to each form elements.

<form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"] . "?id={$id}");?>" method="post">
	<table class='table table-hover table-responsive table-bordered'>

		<tr>
			<td>Name</td>
			<td><input type='text' name='name' value='<?php echo $product->name; ?>' class='form-control' /></td>
		</tr>

		<tr>
			<td>Price</td>
			<td><input type='text' name='price' value='<?php echo $product->price; ?>' class='form-control' /></td>
		</tr>

		<tr>
			<td>Description</td>
			<td><textarea name='description' class='form-control'><?php echo $product->description; ?></textarea></td>
		</tr>

		<tr>
			<td>Category</td>
			<td>
				<!-- categories select drop-down will be here -->
			</td>
		</tr>

		<tr>
			<td></td>
			<td>
				<button type="submit" class="btn btn-primary">Update</button>
			</td>
		</tr>

	</table>
</form>

7.6 Loop Through the Categories Records to show as Drop-down

The following code will list the categories in a drop-down.

Notice that we put “if($product->category_id==$id){…” inside the while loop. This is to pre-select the option of the current record.

Replace the previouse section’s comments “categories select drop-down will be here” with the following code.

<?php
$stmt = $category->read();

// put them in a select drop-down
echo "<select class='form-control' name='category_id'>";

	echo "<option>Please select...</option>";
	while ($row_category = $stmt->fetch(PDO::FETCH_ASSOC)){
		extract($row_category);

		// current category of the product must be selected
		if($product->category_id==$id){
			echo "<option value='$id' selected>";
		}else{
			echo "<option value='$id'>";
		}

		echo "$name</option>";
	}
echo "</select>";
?>

7.7 Code When Form was Submitted

The following code will assign the “posted” values to the object properties. Once assigned, it will update the database with those values using the update() method.

// if the form was submitted
if($_POST){

	// set product property values
	$product->name = $_POST['name'];
	$product->price = $_POST['price'];
	$product->description = $_POST['description'];
	$product->category_id = $_POST['category_id'];

	// update the product
	if($product->update()){
		echo "<div class='alert alert-success alert-dismissable'>";
			echo "Product was updated.";
		echo "</div>";
	}

	// if unable to update the product, tell the user
	else{
		echo "<div class='alert alert-danger alert-dismissable'>";
			echo "Unable to update product.";
		echo "</div>";
	}
}

7.8 Update Code in the Product Class

The following code will make the previous section’s “$product->update()” method work. Open our “product.php” which is inside the “objects” folder and add the following code.

function update(){

	$query = "UPDATE
				" . $this->table_name . "
			SET
				name = :name,
				price = :price,
				description = :description,
				category_id  = :category_id
			WHERE
				id = :id";

	$stmt = $this->conn->prepare($query);

	// posted values
	$this->name=htmlspecialchars(strip_tags($this->name));
	$this->price=htmlspecialchars(strip_tags($this->price));
	$this->description=htmlspecialchars(strip_tags($this->description));
	$this->category_id=htmlspecialchars(strip_tags($this->category_id));
	$this->id=htmlspecialchars(strip_tags($this->id));

	// bind parameters
	$stmt->bindParam(':name', $this->name);
	$stmt->bindParam(':price', $this->price);
	$stmt->bindParam(':description', $this->description);
	$stmt->bindParam(':category_id', $this->category_id);
	$stmt->bindParam(':id', $this->id);

	// execute the query
	if($stmt->execute()){
		return true;
	}

	return false;
	
}

8.0 Read One Record in PHP the OOP Way

We previously made the code for “update record”, this section for reading one record from a database will be easier to do.

8.1 Create read_one.php file

This is the page where the data of a single record will be displayed. Create a new file and name it “read_one.php”, open that file and put the following code.

<?php
// set page headers
$page_title = "Read One Product";
include_once "header.php";

// read products button
echo "<div class='right-button-margin'>";
	echo "<a href='index.php' class='btn btn-primary pull-right'>";
		echo "<span class='glyphicon glyphicon-list'></span> Read Products";
	echo "</a>";
echo "</div>";

// set footer
include_once "footer.php";
?>

8.2 Read one record based on given record ID

The following code will read a single record from the database. Put the following code before the “set page headers” comments of the previous section.

// get ID of the product to be read
$id = isset($_GET['id']) ? $_GET['id'] : die('ERROR: missing ID.');

// include database and object files
include_once 'config/database.php';
include_once 'objects/product.php';
include_once 'objects/category.php';

// get database connection
$database = new Database();
$db = $database->getConnection();

// prepare objects
$product = new Product($db);
$category = new Category($db);

// set ID property of product to be read
$product->id = $id;

// read the details of product to be read
$product->readOne();

8.3 Display record on HTML table

This time, we will display the record details on an HTML table. Put the following code under the closing “div” tag of “Read Products” button.

// HTML table for displaying a product details
echo "<table class='table table-hover table-responsive table-bordered'>";

	echo "<tr>";
		echo "<td>Name</td>";
		echo "<td>{$product->name}</td>";
	echo "</tr>";

	echo "<tr>";
		echo "<td>Price</td>";
		echo "<td>&#36;{$product->price}</td>";
	echo "</tr>";

	echo "<tr>";
		echo "<td>Description</td>";
		echo "<td>{$product->description}</td>";
	echo "</tr>";

	echo "<tr>";
		echo "<td>Category</td>";
		echo "<td>";
            // display category name
            $category->id=$product->category_id;
		    $category->readName();
            echo $category->name;
		echo "</td>";
	echo "</tr>";

echo "</table>";

9.0 Deleting Record in PHP the OOP Way

This is the last coding part of our PHP OOP CRUD Tutorial. Enjoy every code!

9.1 Put this JavaScript Code in footer.php

Put the following JavaScript code before the closing “body” tag in footer.php file. We used Bootbox.js to make a Bootstrap-style confirm dialog box.

<script>
// JavaScript for deleting product
$(document).on('click', '.delete-object', function(){

    var id = $(this).attr('delete-id');

    bootbox.confirm({
        message: "<h4>Are you sure?</h4>",
        buttons: {
            confirm: {
                label: '<span class="glyphicon glyphicon-ok"></span> Yes',
                className: 'btn-danger'
            },
            cancel: {
                label: '<span class="glyphicon glyphicon-remove"></span> No',
                className: 'btn-primary'
            }
        },
        callback: function (result) {

            if(result==true){
                $.post('delete_product.php', {
                    object_id: id
                }, function(data){
                    location.reload();
                }).fail(function() {
                    alert('Unable to delete.');
                });
            }
        }
    });

	return false;
});
</script>

9.2 Create delete_product.php

Create a new file and name it “delete_product.php”. This file accepts the ID posted by the JavaScript code in the previous section. A record will be deleted from the database based on posted ID.

Open delete_product.php and put the following code.

<?php
// check if value was posted
if($_POST){

	// include database and object file
	include_once 'config/database.php';
	include_once 'objects/product.php';

	// get database connection
	$database = new Database();
	$db = $database->getConnection();

	// prepare product object
	$product = new Product($db);
	
	// set product id to be deleted
	$product->id = $_POST['object_id'];
	
	// delete the product
	if($product->delete()){
		echo "Object was deleted.";
	}
	
	// if unable to delete the product
	else{
		echo "Unable to delete object.";
	}
}
?>

9.3 Delete Code in Product Class

The previous section will not work with the “delete()” method in the product object. Open “product.php” which is inside the “objects” folder and put the following code.

// delete the product
function delete(){

	$query = "DELETE FROM " . $this->table_name . " WHERE id = ?";
	
	$stmt = $this->conn->prepare($query);
	$stmt->bindParam(1, $this->id);

	if($result = $stmt->execute()){
		return true;
	}else{
		return false;
	}
}

10.0 Search Records in PHP the OOP Way

We’ll continue by adding the search feature. This will answer the question: How to search data from database in php? This is a very useful feature because you enable your users to easily search a certain data from our MySQL database.

Please note that this is a bonus section. The code in this section is not included in our LEVEL 1 source code download.

10.1 Change index.php

We have to change index.php because we are adding a “search” feature and we want our code to be short. Our index.php will now look like the following code.

<?php
// core.php holds pagination variables
include_once 'config/core.php';

// include database and object files
include_once 'config/database.php';
include_once 'objects/product.php';
include_once 'objects/category.php';

// instantiate database and product object
$database = new Database();
$db = $database->getConnection();

$product = new Product($db);
$category = new Category($db);

$page_title = "Read Products";
include_once "header.php";

// query products
$stmt = $product->readAll($from_record_num, $records_per_page);

// specify the page where paging is used
$page_url = "index.php?";

// count total rows - used for pagination
$total_rows=$product->countAll();

// read_template.php controls how the product list will be rendered
include_once "read_template.php";

// footer.php holds our javascript and closing html tags
include_once "footer.php";
?>

10.2 Create read_template.php

Why do we need this template? We need it because exactly the same code can be used by index.php and search.php for displaying a list of records. Using a template means lesser code.

This template holds our search form as well.

<?php
// search form
echo "<form role='search' action='search.php'>";
    echo "<div class='input-group col-md-3 pull-left margin-right-1em'>";
        $search_value=isset($search_term) ? "value='{$search_term}'" : "";
        echo "<input type='text' class='form-control' placeholder='Type product name or description...' name='s' id='srch-term' required {$search_value} />";
        echo "<div class='input-group-btn'>";
            echo "<button class='btn btn-primary' type='submit'><i class='glyphicon glyphicon-search'></i></button>";
        echo "</div>";
    echo "</div>";
echo "</form>";

// create product button
echo "<div class='right-button-margin'>";
	echo "<a href='create_product.php' class='btn btn-primary pull-right'>";
		echo "<span class='glyphicon glyphicon-plus'></span> Create Product";
	echo "</a>";
echo "</div>";

// display the products if there are any
if($total_rows>0){

	echo "<table class='table table-hover table-responsive table-bordered'>";
		echo "<tr>";
			echo "<th>Product</th>";
			echo "<th>Price</th>";
			echo "<th>Description</th>";
			echo "<th>Category</th>";
			echo "<th>Actions</th>";
		echo "</tr>";

		while ($row = $stmt->fetch(PDO::FETCH_ASSOC)){

			extract($row);

			echo "<tr>";
				echo "<td>{$name}</td>";
				echo "<td>{$price}</td>";
				echo "<td>{$description}</td>";
				echo "<td>";
					$category->id = $category_id;
					$category->readName();
					echo $category->name;
				echo "</td>";

				echo "<td>";

					// read product button
					echo "<a href='read_one.php?id={$id}' class='btn btn-primary left-margin'>";
						echo "<span class='glyphicon glyphicon-list'></span> Read";
					echo "</a>";

					// edit product button
					echo "<a href='update_product.php?id={$id}' class='btn btn-info left-margin'>";
						echo "<span class='glyphicon glyphicon-edit'></span> Edit";
					echo "</a>";

					// delete product button
					echo "<a delete-id='{$id}' class='btn btn-danger delete-object'>";
						echo "<span class='glyphicon glyphicon-remove'></span> Delete";
					echo "</a>";

				echo "</td>";

			echo "</tr>";

		}

	echo "</table>";

	// paging buttons
	include_once 'paging.php';
}

// tell the user there are no products
else{
	echo "<div class='alert alert-danger'>No products found.</div>";
}
?>

10.3 Create core.php in “config” folder

Create a new folder and name it “config”. Inside that folder, create a new file and name it “core.php”.

This file will hold our pagination variables. Using a core.php file is a good practice, it can be used to hold other configuration values that you might need in the future.

Open core.php and put the following code.

<?php
// page given in URL parameter, default page is one
$page = isset($_GET['page']) ? $_GET['page'] : 1; 

// set number of records per page
$records_per_page = 5;

// calculate for the query LIMIT clause
$from_record_num = ($records_per_page * $page) - $records_per_page;
?>

10.4 Change paging.php code

The new paging.php code will look like the following.

<?php
echo "<ul class=\"pagination\">";

// button for first page
if($page>1){
    echo "<li><a href='{$page_url}' title='Go to the first page.'>";
        echo "First Page";
    echo "</a></li>";
}

// count all products in the database to calculate total pages
$total_pages = ceil($total_rows / $records_per_page);

// range of links to show
$range = 2;

// display links to 'range of pages' around 'current page'
$initial_num = $page - $range;
$condition_limit_num = ($page + $range)  + 1;

for ($x=$initial_num; $x<$condition_limit_num; $x++) {

    // be sure '$x is greater than 0' AND 'less than or equal to the $total_pages'
    if (($x > 0) && ($x <= $total_pages)) {

        // current page
        if ($x == $page) {
            echo "<li class='active'><a href=\"#\">$x <span class=\"sr-only\">(current)</span></a></li>";
        }

        // not current page
        else {
            echo "<li><a href='{$page_url}page=$x'>$x</a></li>";
        }
    }
}

// button for last page
if($page<$total_pages){
    echo "<li><a href='" .$page_url . "page={$total_pages}' title='Last page is {$total_pages}.'>";
        echo "Last Page";
    echo "</a></li>";
}

echo "</ul>";
?>

10.5 Include core.php and read_template.php

The core.php file will be included at the beginning of index.php file. The read_template.php will be included before the footer.php inclusion. The new index.php will look like the following code

<?php
// core.php holds pagination variables
include_once 'config/core.php';

// include database and object files
include_once 'config/database.php';
include_once 'objects/product.php';
include_once 'objects/category.php';

// instantiate database and product object
$database = new Database();
$db = $database->getConnection();

$product = new Product($db);
$category = new Category($db);

$page_title = "Read Products";
include_once "header.php";

// query products
$stmt = $product->readAll($from_record_num, $records_per_page);

// specify the page where paging is used
$page_url = "index.php?";

// count total rows - used for pagination
$total_rows=$product->countAll();

// read_template.php controls how the product list will be rendered
include_once "read_template.php";

// footer.php holds our javascript and closing html tags
include_once "footer.php";
?>

10.6 Create search.php

This is the most important file of this section. This file will display the records based on a user’s search term.

Create a new file and name it “search.php”. Open that file and put the following code.

<?php
// core.php holds pagination variables
include_once 'config/core.php';

// include database and object files
include_once 'config/database.php';
include_once 'objects/product.php';
include_once 'objects/category.php';

// instantiate database and product object
$database = new Database();
$db = $database->getConnection();

$product = new Product($db);
$category = new Category($db);

// get search term
$search_term=isset($_GET['s']) ? $_GET['s'] : '';

$page_title = "You searched for \"{$search_term}\"";
include_once "header.php";

// query products
$stmt = $product->search($search_term, $from_record_num, $records_per_page);

// specify the page where paging is used
$page_url="search.php?s={$search_term}&";

// count total rows - used for pagination
$total_rows=$product->countAll_BySearch($search_term);

// read_template.php controls how the product list will be rendered
include_once "read_template.php";

// footer.php holds our javascript and closing html tags
include_once "footer.php";
?>

10.7 Add search() and countAll_BySearch() methods

Open “product.php” file which is inside the “objects” folder. Add the following methods in the class.

// read products by search term
public function search($search_term, $from_record_num, $records_per_page){

	// select query
	$query = "SELECT
				c.name as category_name, p.id, p.name, p.description, p.price, p.category_id, p.created
			FROM
				" . $this->table_name . " p
				LEFT JOIN
					categories c
						ON p.category_id = c.id
			WHERE
				p.name LIKE ? OR p.description LIKE ?
			ORDER BY
				p.name ASC
			LIMIT
				?, ?";

	// prepare query statement
	$stmt = $this->conn->prepare( $query );

	// bind variable values
	$search_term = "%{$search_term}%";
	$stmt->bindParam(1, $search_term);
	$stmt->bindParam(2, $search_term);
	$stmt->bindParam(3, $from_record_num, PDO::PARAM_INT);
	$stmt->bindParam(4, $records_per_page, PDO::PARAM_INT);

	// execute query
	$stmt->execute();

	// return values from database
	return $stmt;
}

public function countAll_BySearch($search_term){

	// select query
	$query = "SELECT
				COUNT(*) as total_rows
			FROM
				" . $this->table_name . " p
				LEFT JOIN
					categories c
						ON p.category_id = c.id
			WHERE
				p.name LIKE ?";

	// prepare query statement
	$stmt = $this->conn->prepare( $query );

	// bind variable values
	$search_term = "%{$search_term}%";
	$stmt->bindParam(1, $search_term);

	$stmt->execute();
	$row = $stmt->fetch(PDO::FETCH_ASSOC);

	return $row['total_rows'];
}

10.8 Output

php-mysql-oop-crud-tutorial

11.0 File Upload in PHP the OOP Way

In this section, we will add a “file upload” feature. This feature is included in the LEVEL 2 source code download.

11.1 Change HTML form

Open create_product.php and find the “form” tag. Change that line to the following code. The “enctype” enables the form to submit a file to the server.

<form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>" method="post" enctype="multipart/form-data">

On the same HTML table, find the closing “tr” tag of the “Price” field. Add the following code. This adds an input field where the user can browse the file he wants to upload.

<tr>
	<td>Photo</td>
	<td><input type="file" name="image" /></td>
</tr>

11.2 Set value of “image” field

Open create_product.php and add the new “image” field. The value will be the file name of the submitted file. We used the built-in sha1_file() function the make the file name unique.

$image=!empty($_FILES["image"]["name"])
		? sha1_file($_FILES['image']['tmp_name']) . "-" . basename($_FILES["image"]["name"]) : "";
$product->image = $image;

11.3 Change create() method

Open “objects” folder and open the “product.php” file inside it. Find the “create()” method.

Add the “image” field by changing the query to:

// insert query
$query = "INSERT INTO " . $this->table_name . "
			SET name=:name, price=:price, description=:description,
				category_id=:category_id, image=:image, created=:created";

On the sanitize section, it will be:

$this->image=htmlspecialchars(strip_tags($this->image));

Then bind the value.

$stmt->bindParam(":image", $this->image);

Add the “image” property at the top of the class, maybe after public $description;

public $image;

Using the PhpMyAdmin, add an “image” field in the products table. Set the type to VARCHAR with 512 in length.

11.4 Call uploadPhoto() method

Open create_product.php and find this line.

// product was created in database
echo "<div class='alert alert-success'>Product was created.</div>";

Put the following code under code above. This will call the uploadPhoto() method that will try to upload the file to server.

// try to upload the submitted file
// uploadPhoto() method will return an error message, if any.
echo $product->uploadPhoto();

11.5 Add uploadPhoto() method

The previous section will not work without the complete code of uploadPhoto() method.

Open “objects” folder and open the “product.php” file inside it. Add the following method inside the class.

// will upload image file to server
function uploadPhoto(){

	$result_message="";

	// now, if image is not empty, try to upload the image
	if($this->image){

		// sha1_file() function is used to make a unique file name
		$target_directory = "uploads/";
		$target_file = $target_directory . $this->image;
		$file_type = pathinfo($target_file, PATHINFO_EXTENSION);

		// error message is empty
		$file_upload_error_messages="";

	}

	return $result_message;
}

11.6 Validate submitted file

Now we will validate the submitted file by:

  • Identifying if it’s a real or fake image.
  • Limit the allowed file types.
  • Prevent multiple file on the server.
  • Deny uploading files with large file size.
  • Making sure the “uploads” directory exists.

Add the following code after $file_upload_error_messages=””; of the previous section.

// make sure that file is a real image
$check = getimagesize($_FILES["image"]["tmp_name"]);
if($check!==false){
	// submitted file is an image
}else{
	$file_upload_error_messages.="<div>Submitted file is not an image.</div>";
}

// make sure certain file types are allowed
$allowed_file_types=array("jpg", "jpeg", "png", "gif");
if(!in_array($file_type, $allowed_file_types)){
	$file_upload_error_messages.="<div>Only JPG, JPEG, PNG, GIF files are allowed.</div>";
}

// make sure file does not exist
if(file_exists($target_file)){
	$file_upload_error_messages.="<div>Image already exists. Try to change file name.</div>";
}

// make sure submitted file is not too large, can't be larger than 1 MB
if($_FILES['image']['size'] > (1024000)){
	$file_upload_error_messages.="<div>Image must be less than 1 MB in size.</div>";
}

// make sure the 'uploads' folder exists
// if not, create it
if(!is_dir($target_directory)){
	mkdir($target_directory, 0777, true);
}

11.7 Return error messages

If the file is valid, we will upload the file to server. Specifically, in the “uploads” folder. If there’s any error, we will return it to be shown to the user.

// if $file_upload_error_messages is still empty
if(empty($file_upload_error_messages)){
	// it means there are no errors, so try to upload the file
	if(move_uploaded_file($_FILES["image"]["tmp_name"], $target_file)){
		// it means photo was uploaded
	}else{
		$result_message.="<div class='alert alert-danger'>";
			$result_message.="<div>Unable to upload photo.</div>";
			$result_message.="<div>Update the record to upload photo.</div>";
		$result_message.="</div>";
	}
}

// if $file_upload_error_messages is NOT empty
else{
	// it means there are some errors, so show them to user
	$result_message.="<div class='alert alert-danger'>";
		$result_message.="{$file_upload_error_messages}";
		$result_message.="<div>Update the record to upload photo.</div>";
	$result_message.="</div>";
}

11.8 Show uploaded image file

Open “objects” folder and open “product.php” file. Find readOne() method. Add the “image” field in the method. The new method should look like the following.

function readOne(){

	$query = "SELECT name, price, description, category_id, image
		FROM " . $this->table_name . "
		WHERE id = ?
		LIMIT 0,1";

	$stmt = $this->conn->prepare( $query );
	$stmt->bindParam(1, $this->id);
	$stmt->execute();

	$row = $stmt->fetch(PDO::FETCH_ASSOC);

	$this->name = $row['name'];
	$this->price = $row['price'];
	$this->description = $row['description'];
	$this->category_id = $row['category_id'];
	$this->image = $row['image'];
}

Open read_one.php file and find the closing “tr” tag of the “Description” field in the HTML table. Add the following code. This will show the uploaded image.

echo "<tr>";
	echo "<td>Image</td>";
	echo "<td>";
		echo $product->image ? "<img src='uploads/{$product->image}' style='width:300px;' />" : "No image found.";
	echo "</td>";
echo "</tr>";

12.0 Download LEVEL 1 Source Code

You can get the source code by following the whole, well-detailed tutorial above. But isn’t it more convenient if you can just download the complete source code we used, and play around it?

There’s a small fee in getting the complete source code, it is small compared to the:

✔ Value or skill upgrade it can bring you, orYES
✔ Income you can get from your website project or business.YES
✔ Precious time you save.YES
✔ Expert advice you can get from me, just in case you have any questions with the code.YES

For a limited time, I will give you the PHP OOP CRUD Tutorial source code for a low price. DOWNLOAD THE SOURCE CODE LEVEL you desire by clicking the BUY button below.

FEATURESLEVEL 1
Object Oriented Programming Source CodeYES
PDO extension usedYES
Create productYES
Read productYES
Update productYES
Delete productYES
Price display with dollar signYES
PaginationYES
Bootstrap UIYES
SQL file in “dev” folderYES
LEVEL 1: BUY AND DOWNLOAD NOW USING
* You can use your debit or credit card with PayPal.

13.0 Download LEVEL 2 Source Code

FEATURESLEVEL 2
All features of LEVEL 1 aboveYES
HTML5 (font-end) validation for create productYES
HTML5 (font-end) validation for update productYES
Category selection for create and update product.YES
Buttons with GlyphiconsYES
Search products by name or descriptionYES
HTML5 (font-end) validation for search productYES
Pagination in searchYES
Allow user to input page number (read and search list)YES
Export / download records to CSVYES
Price display with dollar sign, comma and decimal pointYES
Multiple deleteYES
File upload field when creating or updating recordYES
LEVEL 2: BUY AND DOWNLOAD NOW USING
* You can use your debit or credit card with PayPal.

14.0 Download LEVEL 3 Source Code

FEATURESLEVEL 3
All features of LEVEL 1 and 2 aboveYES
Bootstrap navigation barYES
Select category in navigationYES
Higlight category in navigationYES
Create categoryYES
Read categoryYES
Update categoryYES
Delete categoryYES
View products by categoryYES
Pagination for categoryYES
Search categoryYES
Pagination for category searchYES
Server side validation for create product & categoryYES
Server side validation for update product & categoryYES
Sorting by fieldsYES
Pagination for sorting by fieldsYES
jQuery UI enabledYES
Search product by date range – record date createdYES
Pagination for earch product by date rangeYES
jQuery UI calendar for picking dateYES
LEVEL 3: BUY AND DOWNLOAD NOW USING
* You can use your debit or credit card with PayPal.

15.0 Download ALL LEVELS in Separate Packages

DOWNLOAD ALL 3 PACKAGES ABOVEALL
Level 1 source code packageYES
Level 2 source code packageYES
Level 3 source code packageYES
ALL LEVEL: BUY AND DOWNLOAD NOW USING
* You can use your debit or credit card with PayPal.

Do you need more reasons to get it?

MORE REASONS TO DOWNLOAD THE CODEALL
Use new skills for your multiple projectsYES
Save huge amount of time learning Bootstrap and PHPYES
Code examples are direct to the pointYES
Well explained and commented source codeYES
Fast and friendly email supportYES
Free source code updatesYES

If you have any more questions, please feel free to contact me now. You can do it by sending a message on our official Facebook page, or via my email mike@codeofaninja.com

Thanks for supporting our website and projects here at codeofaninja.com!

16.0 What’s Next?

I hope you learned a lot from our from our PHP OOP CRUD Tutorial! Learning PHP Object Oriented Programming is fun and it can dramatically improve your career.

Up next: You have two choices.

A. Learn PHP and MySQL Shopping Cart Tutorial – Using SESSIONS To Store Cart Data

B. Learn PHP, MySQL and AJAX CRUD Tutorial – Step by Step Guide!.

17.0 Related Source Codes

The following related source code tutorials can be very useful to further improve your skills.

PHP CRUD Tutorials
1.0 PHP & MySQL CRUD Tutorial for Beginners
2.0 PHP, MySQL & OOP CRUD Tutorial
3.0 PHP, MySQL & AJAX CRUD Tutorial
4.0 PHP, MySQL & AngularJS CRUD Tutorial
5.0 PHP, MySQL & React CRUD Tutorial
PHP Shopping Cart Tutorials
1.0 Shopping Cart Tutorial using SESSIONS
2.0 Shopping Cart Tutorial using COOKIES
3.0 Shopping Cart Tutorial using MySQL
PHP Web Application Source Codes
PHP Shopping Cart System
PayPal Integration In PHP
PHP Login System

18.0 Some Notes

#1 Found An Issue?

If you found a problem with this code, we can solve it faster via Email or FB message, please send me a message via email mike@codeofaninja.com, or via our official Facebook page!

Please be more detailed about your issue. Best if you can provide an error message and your test or page URL. Thanks!

Please feel free to comment if you have any questions, suggestions, found something wrong or want to contribute to this code.

#2 Become a true Ninja!

We constantly add new tutorials and improve our existing tutorials and source codes. Be one of the first to know an update by subscribing to our FREE newsletter. Get a FREE EBOOK as well. CLICK HERE TO SUBSCRIBE FOR FREE!

#3 Thank You!

Please note that this post is in continuous development, meaning I’ll update it every now and then.

If you have a friend or know someone who needs this PHP OOP CRUD Tutorial, please share this page to them! I know you will help them a lot by doing it. Thanks!