PHP Object Oriented Programming
PHP Object Oriented Programming পর্ব-১৩: PHP OOP Object Cloning
PHP OOP তে Object cloning কি?
একটি 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); ?>
ব্যাখ্যা: লক্ষ্য করুন , উপরের কোডটিতে $obj1 থেকে $obj2 কপি করে আমাদের কোনো সুবিধা হয় নাই, কারণ কপি object $obj2 দিয়ে class এর কোনো property অথবা Method এ কোনো পরিবর্তন করলে Main Object $obj1 ও পরিবর্তন হচ্ছে। একই ভাবে Main Object $obj1 দিয়ে class এর কোনো property অথবা Method এ কোনো পরিবর্তন করলে copy Object $obj2 ও পরিবর্তন হয়ে যাবে।
এবার দেখা যাক 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); ?>
ব্যাখ্যা: $obj1 এবং $obj2 Object দুইটি সম্পূর্ণ আলাদা object হিসেবে ব্যবহার হচ্ছে।
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); ?>
ব্যাখ্যা : লক্ষ্য করুন , 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>'; }