PHP Object Oriented Programming পর্ব-১৩: PHP OOP Object Cloning

PHP OOP তে Object cloning কি?

PHP OOP Object Cloning Tutorial

একটি object কে clone করে সম্পূর্ণ নতুন একটা object তৈরী করার পদ্ধতিকে PHP OOP তে Object Cloning বলে। ব্যাপারটা আরেকটু সহজ ভাবে বুঝা যাক , PHP তে আপনি যখন সরাসরি কোনো object copy করবেন, তখন এটি Object এর value এর পরিবর্তে Reference দিয়ে copy করবে, অর্থাৎ, আপনি যদি Main Object এর যেকোনো value পরিবর্তন করেন তখন copy করা Object টি affected হবে। এছাড়াও আপনি copy করা Object এর মান পরিবর্তন করলেও Main Object এর মানও পরিবর্তন হয়ে যাবে। সুতরাং আপনি যদি Object এর copy টি এমন ভাবে তৈরী করতে চান যা Main Object এর সাথে কোনও Reference থাকবেনা। আর Main Object এর সাথে copy করা object এর সাথে কোনো রকম reference ছাড়া copy করার পদ্ধতিকে PHP OOP তে Object cloning বলে।

প্রথমে দেখা যাক cloning পদ্ধতি ব্যবহার না করে একটা object থেকে copy করে আরেকটা object তৈরী করলে কি সমস্যা হতে পারে ?

<?php
class test{
    public $name;
    private $mobile;
    function __construct($name, $mobile){
        $this->name = $name;
        $this->mobile = $mobile;
    }
}
$obj1 = new test("Farhaan" , "01700000000");
echo "Result Before Copy \n";
print_r($obj1);
echo "After Copy Both Object will show same result\n";
$obj2 = $obj1; //Copy of the object
$obj2->name = "Habibr";
print_r($obj1);
print_r($obj2);
?>

copy object without cloning implementation

ব্যাখ্যা: লক্ষ্য করুন , উপরের কোডটিতে $obj1 থেকে $obj2 কপি করে আমাদের কোনো সুবিধা হয় নাই, কারণ কপি object $obj2 দিয়ে class এর কোনো property অথবা Method এ কোনো পরিবর্তন করলে Main Object $obj1 ও পরিবর্তন হচ্ছে। একই ভাবে Main Object $obj1 দিয়ে class এর কোনো property অথবা Method এ কোনো পরিবর্তন করলে copy Object $obj2 ও পরিবর্তন হয়ে যাবে।

Zend Certified PHP Engineering (ZCPE) Course

এবার দেখা যাক cloning পদ্ধতি ব্যবহার করে একটা object থেকে copy করে আরেকটা object তৈরী করার সুবিধা :

PHP তে কোনো object কে clone করতে হলে, যেই object কে clone করা হবে সেই object এর সামনে clone keyword বসাতে হবে। চলুন নিচের উদাহরণটি দেখি :

<?php
class test{
    public $name;
    private $mobile;
    function __construct($name, $mobile){
        $this->name = $name;
        $this->mobile = $mobile;
    }
}
$obj1 = new test("Farhaan" , "01700000000");
$obj2 = clone $obj1; //Copy of the object
$obj2->name = "Habibr";
print_r($obj1);
print_r($obj2);
?>

PHP OOP Object Cloning

ব্যাখ্যা: $obj1 এবং $obj2 Object দুইটি সম্পূর্ণ আলাদা object হিসেবে ব্যবহার হচ্ছে।

Zend Certified PHP Engineering (ZCPE) Course

PHP OOP তে Object Cloning এ __clone() Magic Method এর কাজ কি?

PHP OOP তে Object Cloning করা কালীন class এর মধ্যে কোনো property পরিবর্তন , অথবা কোনো বিশেষ result চাইলে __clone() Magic Method টি ব্যবহৃত হয়। চলুন একটা উদাহরণ দিয়ে বুঝা যাক :

<?php
class test{
    public $name;
    private $mobile;
    function __construct($name, $mobile){
        $this->name = $name;
        $this->mobile = $mobile;
    }
    public function __clone(){
        echo "During Cloning I'm only Executing! And I can change anything\n";
        $this->mobile="01922009988";
    }
}
$obj1 = new test("Farhaan" , "01700000000");
$obj2 = clone $obj1; //Copy of the object
$obj2->name = "Habibr";
print_r($obj1);
print_r($obj2);
?>

PHP OOP Object Cloning With __clone Magic Method

ব্যাখ্যা : লক্ষ্য করুন , Cloning টাইমে আমরা একটা message দেখায় , এবং Mobile Number টি চেঞ্জ করি।

PHP OOP তে Object Cloning ব্যবহার করে Data Insert, Backup এবং Restore সিস্টেম তৈরি

প্রথমে main_database নামক একটি ডাটাবেসে নিম্নোক্ত টেবিলটি তৈরি করুন:

CREATE TABLE `user_data` (
  `id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
  `name` varchar(100) NOT NULL,
  `email` varchar(100) NOT NULL,
  `phone` varchar(15) NOT NULL,
  `address` text NOT NULL,
  `created_at` timestamp NOT NULL DEFAULT current_timestamp()
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

এবার backup_database নামক একটি ডাটাবেসে নিম্নোক্ত টেবিলটি তৈরি করুন:

CREATE TABLE `backup_user_data` (
  `id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
  `data` varchar(255) NOT NULL,
  `backup_date` timestamp NOT NULL DEFAULT current_timestamp()
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

এবার form.html নামক ফাইলে নিম্নোক্ত কোড গুলো যুক্ত করুন :

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Database Backup System</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/css/bootstrap.min.css">

</head>
<body>
    <div class="container mt-5">
        <h2>Database Backup System</h2>
        <div class="row mt-3">
            <div class="col-md-6">
                <form id="insertForm">
                    <div class="form-group">
                        <label for="name">Name:</label>
                        <input type="text" class="form-control" id="name" name="name" required>
                    </div>
                    <div class="form-group">
                        <label for="email">Email:</label>
                        <input type="email" class="form-control" id="email" name="email" required>
                    </div>
                    <div class="form-group">
                        <label for="phone">Phone:</label>
                        <input type="text" class="form-control" id="phone" name="phone" required>
                    </div>
                    <div class="form-group">
                        <label for="name">Address:</label>
                        <textarea class="form-control" id="address" name="address" required></textarea>
                    </div>
                    <button type="submit" class="btn btn-primary">Insert Data</button>
                </form>
            </div>
            <div class="col-md-6">
                <button type="button" class="btn btn-info" id="viewBackupsBtn">View Backups</button>
                <div id="backupList" style="display: none;"></div>
            </div>
        </div>
        <div class="row mt-3">
            <div class="col-md-12">
                <div id="result"></div>
            </div>
        </div>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js"></script>
    <script>
        $(document).ready(function(){
            $("#insertForm").submit(function(e){
                e.preventDefault();

                $.ajax({
                    url: "insert_data.php",
                    type: "POST",
                    data: $(this).serialize(),
                    success: function(response){
                        $("#result").html(response);
                    },
                    error: function(){
                        alert("Error in insert process");
                    }
                });
            });

            $("#viewBackupsBtn").click(function(){
                $.ajax({
                    url: "view_backups.php",
                    type: "GET",
                    success: function(response){
                        $("#backupList").html(response);
                        $("#backupList").toggle();
                    },
                    error: function (){
                        alert("Error in viewing backups");
                    }
                });
            });
        });
    </script>
</body>
</html>

এবার DatabaseManager.php নামক class ফাইলে নিম্নোক্ত কোড গুলো যুক্ত করুন :

<?php 
class DatabaseManager 
{
    private $id;
    private $name;
    private $email;
    private $phone;
    private $address;
    private $backupDate;

    public function __construct($id, $name, $email, $phone, $address)
    {
        $this->id=$id;
        $this->name=$name;
        $this->email=$email;
        $this->phone=$phone;
        $this->address=$address;
        $this->backupDate = date('Y-m-d H:i:s');
    }

    public function displayDataInfo()
    {
        echo "Id: {$this->id}<br>";
        echo "Name: {$this->name}<br>";
        echo "Email: {$this->email}<br>";
        echo "Phone: {$this->phone}<br>";
        echo "Address: {$this->address}<br>";
        echo "Backup Date: {$this->backupDate}<br>";
    }

    public function toArray()
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'email' => $this->email,
            'phone' => $this->phone,
            'address' => $this->address,
            'backup_date' => $this->backupDate,

        ];
    }

    public function __clone()
    {
        $this->backupDate=date('Y-m-d H:i:s');
    }

    public function getBackupDate()
    {
        return $this->backupDate;
    }

    public static function Insert($conn, $table, array $data)
    {
        extract($data);
        $stmt=$conn->prepare("INSERT INTO $table (name, email, phone, address) VALUES (:name, :email, :phone, :address)");
        $stmt->bindParam(':name', $name);
        $stmt->bindParam(':email', $email);
        $stmt->bindParam(':phone', $phone);
        $stmt->bindParam(':address', $address);

        if($stmt->execute())
        {
            return new DatabaseManager($conn->lastInsertId(), $name, $email, $phone, $address);
        }
        return false;
    }

    public static function getAll($conn, $table)
    {
        $stmt = $conn->query("SELECT * FROM $table");
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }

    public static function getById($conn, $table, $id)
    {
        $stmt = $conn->prepare("SELECT * FROM $table WHERE id = :id ORDER BY id DESC LIMIT 1");
        $stmt->bindParam(':id', $id, PDO::PARAM_INT);
        $stmt->execute();

        return $stmt->fetch(PDO::FETCH_ASSOC);
        
    }



}

এবার dbConfig.php নামক ফাইলে নিম্নোক্ত কোড গুলো যুক্ত করুন :

<?php 
return
    [
        'mainDbHost' => 'localhost',
        'mainDbName' => 'main_database',
        'mainDbUser' => 'root',
        'mainDbpassword' => '',
        'backupDbHost' => 'localhost',
        'backupDbName' => 'backup_database',
        'backupDbUser' => 'root',
        'backupDbpassword' => '',
    ];

এবার db.php নামক ফাইলে নিম্নোক্ত কোড গুলো যুক্ত করুন :

<?php 
function connectToDb($host, $dbname, $user, $password)
{
    try{
        $pdo = new PDO("mysql:host=$host;dbname=$dbname", $user, $password);
        $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        return $pdo;
    }catch (PDOException $e){
        die ("Connection failed: " .  $e->getMessage());
    }
}

এবার insert_data.php নামক ফাইলে নিম্নোক্ত কোড গুলো যুক্ত করুন :

<?php 
include 'db.php';
$db=include 'dbConfig.php';
include 'DatabaseManager.php';
try{
    $insertPdo=connectToDb($db['mainDbHost'],$db['mainDbName'],$db['mainDbUser'],$db['mainDbpassword']);

    $name = isset($_POST['name']) ? htmlspecialchars($_POST['name']) : '';
    $email = isset($_POST['email']) ? htmlspecialchars($_POST['email']) : '';
    $phone = isset($_POST['phone']) ? htmlspecialchars($_POST['phone']) : '';
    $address = isset($_POST['address']) ? htmlspecialchars($_POST['address']) : '';

    $formData=[
        'name' => $name,
        'email' => $email,
        'phone' => $phone,
        'address' => $address
    ];

    $result = DatabaseManager::Insert($insertPdo, "user_data", $formData);
    
    if($result !==false)
    {
        echo '<div class="alert alert-success" role="alert">Data successfully inserted. </div>';
        echo '<strong>Original Data: </strong><br>';
        $result->displayDataInfo();

        $jsonData = json_encode($result->toArray());

        $clonedData = clone $result;

        $backup_date = $clonedData->getBackupDate();

        $backupPdo = connectToDb($db['backupDbHost'],$db['backupDbName'],$db['backupDbUser'],$db['backupDbpassword']);
        $backupStmt = $backupPdo->prepare("INSERT INTO backup_user_data (data, backup_date) VALUES (:data, :backup_date)");
        $backupStmt->bindParam(':data', $jsonData);
        $backupStmt->bindParam(':backup_date',$backup_date);
        $backupStmt->execute();

        echo "<br><strong>Cloned Data</strong><br>";
        
        $clonedData->displayDataInfo();
    }else{
        echo '<div class="alert alert-danger" role="alert">Error in inserting data.</div>';
    }
}catch(PDOException $e){
    echo '<div class="alert alert-danger" role="alert">Error:'.$e->getMessage().'</div>';
}

এবার view_backups.php নামক ফাইলে নিম্নোক্ত কোড গুলো যুক্ত করুন :

<?php 
include 'db.php';
$db= include 'dbConfig.php';
include 'DatabaseManager.php';

try{
    $backupPdo = connectToDb($db['backupDbHost'],$db['backupDbName'],$db['backupDbUser'],$db['backupDbpassword']);
    $backups=DatabaseManager::getAll($backupPdo, 'backup_user_data');

    echo '<strong>List of Backups: </strong><br>';

    if(empty($backups))
    {
        echo 'No backups available.';
    }else{
        foreach($backups as $backup){
            echo '<a href="#" class="restoreBackup" data-id="'.$backup['id'].'">' . $backup['backup_date'] . '</a><br>';
        }
    }
}catch(PDOException $e){
    echo 'Error: '.$e->getMessage();
}
?>
<script>
    $(document).ready(function(){
        $(".restoreBackup").click(function(){
            var backupId = $(this).data("id");
            $.ajax({
                url:"restore_backup.php",
                type: "POST",
                data: {backupId: backupId},
                success: function(response){
                    $("#result").html(response)
                },
                error: function(){
                    alert("Error in restoring backup");
                }
            });
        });
    });
</script>

এবার restore_backup.php নামক ফাইলে নিম্নোক্ত কোড গুলো যুক্ত করুন :

<?php 
include 'db.php';
$db= include 'dbConfig.php';
include 'DatabaseManager.php';
$backuId=isset($_POST['backupId'])? $_POST['backupId'] : null;

try{
    if($backuId !==null){
    $backupPdo = connectToDb($db['backupDbHost'],$db['backupDbName'],$db['backupDbUser'],$db['backupDbpassword']);
    $backupData=DatabaseManager::getById($backupPdo, 'backup_user_data',$backuId);

        if($backupData)
        {
            $insertPdo=connectToDb($db['mainDbHost'],$db['mainDbName'],$db['mainDbUser'],$db['mainDbpassword']);
            
            $decodedData = json_decode($backupData['data'], true);

            $result = DatabaseManager::Insert($insertPdo, "user_data", $decodedData);

            if($result !==false){
                echo '<div class="alert alert-success" role = "alert"> Data successfully restored from backup.</div>';
            }else{
                echo '<div class = "alert alert-danger" role="alert"> Error in restoring data. </div>';
            }
        }else{
            echo '<div class="alert alert-warning" role="alert"> No backup data available to restore.</div>';
        }
    }else{
        echo '<div class="alert alert-warning" role="alert"> Error: '. $e->getMessage(). '</div>';
    }
}catch(PDOException $e){
    echo '<div class="alert alert-danger" role="alert">Error: '. $e->getMessage().'</div>';
}

Output:

Data Backup and Restore with PHP Object Cloning

আমি মাসুদ আলম, বাংলাদেশের ৩৬ তম Zend Certified Engineer । ২০০৯ সালে কম্পিউটার সাইন্স থেকে বেচেলর ডিগ্রী অর্জন করি। দীর্ঘ ১৫ বছর আমি Winux Soft, SSL Wireless, IBCS-PRIMAX, Max Group, Canadian International Development Agency (CIDA), Care Bangladesh, World Vision, Hellen Keller, Amarbebsha Ltd সহ বিভিন্ন দেশি বিদেশী কোম্পানিতে ডেটা সাইন্স, মেশিন লার্নিং, বিগ ডেটা, ওয়েব ডেভেলপমেন্ট এবং সফটওয়্যার ডেভেলপমেন্ট এর উপর বিভিন্ন লিডিং পজিশন এ চাকরি এবং প্রজেক্ট লিড করি। এছাড়াও বাংলাদেশের ১৮৫ জন জেন্ড সার্টিফাইড ইঞ্জিনিয়ার এর মধ্যে ১২০ এরও অধিক ছাত্র আমার হাতে জেন্ড সার্টিফাইড ইঞ্জিনিয়ার হয়েছেন। বর্তমানে w3programmers ট্রেনিং ইনস্টিটিউট এ PHP এর উপর Professional এবং Advance Zend Certified PHP -8.2 Engineering, Laravel Mastering Course with ReactJS, Python Beginning To Advance with Blockchain, Machine Learning and Data Science, Professional WordPress Plugin Development Beginning to Advance কোর্স করাই। আর অবসর সময়ে w3programmers.com এ ওয়েব টেকনোলজি নিয়ে লেখালেখি করি।

Leave a Reply