Mysql
 sql >> डेटाबेस >  >> RDS >> Mysql

PHP और MySQL डेटाबेस में ब्लॉग कैसे बनाये - DB डिज़ाइन

डेटाबेस

यह PHP और MySQL के साथ एक ब्लॉग कैसे बनाएं पर श्रृंखला का दूसरा भाग है। आप यहां पहला भाग प्राप्त कर सकते हैं

हम वहीं जारी रखेंगे जहां हमने पिछले ट्यूटोरियल में छोड़ा था। इस खंड में हम अपने डेटाबेस डिजाइन और उपयोगकर्ता प्रमाणीकरण (पंजीकरण और लॉगिन) पर काम करेंगे। पूर्ण-ब्लॉग-php नामक डेटाबेस बनाएं। इस डेटाबेस में, 2 टेबल बनाएं:पोस्ट और निम्न फ़ील्ड वाले उपयोगकर्ता।

पोस्ट:

+----+-----------+--------------+------------+
|     field      |     type     | specs      |
+----+-----------+--------------+------------+
|  id            | INT(11)      |            |
|  user_id       | INT(11)      |            |
|  title         | VARCHAR(255) |            |
|  slug          | VARCHAR(255) | UNIQUE     |
|  views         | INT(11)      |            |
|  image         | VARCHAR(255) |            |
|  body          | TEXT         |            |
|  published     | boolean      |            |
|  created_at    | TIMESTAMP    |            |
|  updated_at    | TIMESTAMP    |            |
+----------------+--------------+------------+

उपयोगकर्ता:

+----+-----------+------------------------+------------+
|     field      |     type               | specs      |
+----+-----------+------------------------+------------+
|  id            | INT(11)                |            |
|  username      | VARCHAR(255)           | UNIQUE     |
|  email         | VARCHAR(255)           | UNIQUE     |
|  role          | ENUM("Admin","Author") |            |
|  password      | VARCHAR(255)           |            |
|  created_at    | TIMESTAMP              |            |
|  updated_at    | TIMESTAMP              |            |
+----------------+--------------+---------+------------+

आप इन आदेशों का उपयोग करके ये तालिकाएँ बना सकते हैं।

उपयोगकर्ता:

CREATE TABLE `users` (
  `id` int(11) AUTO_INCREMENT PRIMARY KEY NOT NULL,
  `username` varchar(255) NOT NULL,
  `email` varchar(255) NOT NULL,
  `role` enum('Author','Admin') DEFAULT NULL,
  `password` varchar(255) NOT NULL,
  `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
  `updated_at` timestamp NULL DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

पोस्ट:

CREATE TABLE `posts` (
 `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
 `user_id` int(11) DEFAULT NULL,
 `title` varchar(255) NOT NULL,
 `slug` varchar(255) NOT NULL UNIQUE,
 `views` int(11) NOT NULL DEFAULT '0',
 `image` varchar(255) NOT NULL,
 `body` text NOT NULL,
 `published` tinyint(1) NOT NULL,
 `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
 `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=latin1

आप इन स्क्रिप्ट को SQL कमांड प्रॉम्प्ट या PHPMyAdmin का उपयोग करके चला सकते हैं। PHPMyAdmin पर, उस डेटाबेस पर क्लिक करें/चुनें जिसे आप इन तालिकाओं के तहत बनाना चाहते हैं (इस मामले में पूर्ण-ब्लॉग-php), फिर पृष्ठ के शीर्ष पर कहीं भी नेवबार पर SQL टैब पर क्लिक करें। यदि आपको नीचे दी गई जगह में कोई SQL स्क्रिप्ट दिखाई देती है, तो उसे हटा दें और ऊपर दी गई स्क्रिप्ट को दिए गए स्थान में पेस्ट करें और टेबल बनाने के लिए 'गो' पर क्लिक करें।

यदि आपने इसके बजाय इन तालिकाओं को मैन्युअल रूप से बनाना चुना है, तो पोस्ट टेबल पर स्लग फ़ील्ड को अद्वितीय बनाना याद रखें, और पोस्ट टेबल के user_id फ़ील्ड को विदेशी कुंजी के रूप में सेट करना याद रखें जो उपयोगकर्ता तालिका पर आईडी को संदर्भित करती है। ON DELETE और ON UPDATE विकल्पों के लिए NO ACTION को मान के रूप में सेट करें ताकि जब कोई उपयोगकर्ता हटा दिया जाए या अपडेट किया जाए, तो उनकी पोस्ट पोस्ट टेबल पर बनी रहे और हटाई न जाए।

अब कुछ यूजर्स को यूजर टेबल में और कुछ पोस्ट को पोस्ट टेबल में डालें। सम्मिलित करने के लिए इन SQL क्वेरीज़ को चलाकर आप ऐसा कर सकते हैं:

उपयोगकर्ता:

INSERT INTO `users` (`id`, `username`, `email`, `role`, `password`, `created_at`, `updated_at`) VALUES
(1, 'Awa', '[email protected]', 'Admin', 'mypassword', '2018-01-08 12:52:58', '2018-01-08 12:52:58')

पोस्ट: 

INSERT INTO `posts` (`id`, `user_id`, `title`, `slug`, `views`, `image`, `body`, `published`, `created_at`, `updated_at`) VALUES
(1, 1, '5 Habits that can improve your life', '5-habits-that-can-improve-your-life', 0, 'banner.jpg', 'Read every day', 1, '2018-02-03 07:58:02', '2018-02-01 19:14:31'),
(2, 1, 'Second post on LifeBlog', 'second-post-on-lifeblog', 0, 'banner.jpg', 'This is the body of the second post on this site', 0, '2018-02-02 11:40:14', '2018-02-01 13:04:36')

आइए डेटाबेस से जुड़ें, इन पोस्टों को क्वेरी करें और वेबपेज पर प्रदर्शित करें।

config.php में, हमारे एप्लिकेशन को डेटाबेस से जोड़ने के लिए कोड जोड़ें। कोड जोड़ने के बाद, हमारी config.php फ़ाइल इस तरह दिखेगी:

<?php 
	session_start();
	// connect to database
	$conn = mysqli_connect("localhost", "root", "", "complete-blog-php");

	if (!$conn) {
		die("Error connecting to database: " . mysqli_connect_error());
	}
    // define global constants
	define ('ROOT_PATH', realpath(dirname(__FILE__)));
	define('BASE_URL', 'http://localhost/complete-blog-php/');
?>

यह एक डेटाबेस कनेक्टिविटी ऑब्जेक्ट $conn देता है जिसका उपयोग हम डेटाबेस को क्वेरी करने के लिए अपने संपूर्ण एप्लिकेशन में कर सकते हैं।

इस एप्लिकेशन को इस तरह से संरचित किया गया है कि PHP कोड HTML से यथासंभव अलग हो। डेटाबेस को क्वेरी करने और डेटा पर कुछ तर्क करने जैसे संचालन PHP फ़ंक्शंस में किए जाते हैं और परिणाम प्रदर्शित करने के लिए HTML को भेजे जाते हैं। इसलिए डेटाबेस से सभी पोस्ट प्राप्त करने के लिए, हम इसे एक फ़ंक्शन में करेंगे और परिणामों को एक सहयोगी सरणी के रूप में वापस कर देंगे, जिसके माध्यम से लूप किया जाएगा और पृष्ठ पर प्रदर्शित किया जाएगा।

इसलिए, शामिल फ़ोल्डर में public_functions.php नाम की एक फ़ाइल बनाएं। यह फ़ाइल सार्वजनिक क्षेत्र के लिए हमारे सभी PHP कार्यों को रखने वाली है। इस फ़ाइल में किसी भी फ़ंक्शन का उपयोग करने वाले सभी पृष्ठों में यह फ़ाइल पृष्ठ के शीर्ष भाग में शामिल होनी चाहिए।

आइए अपने नए बनाए गए public_functions.php में अपना पहला फंक्शन बनाएं। हम फ़ंक्शन का नाम getPublishedPosts() रखेंगे और यह डेटाबेस में पोस्ट तालिका से सभी पोस्ट पुनर्प्राप्त करेगा और उन्हें एक सहयोगी सरणी के रूप में लौटाएगा:

public_functions.php:

<?php 
/* * * * * * * * * * * * * * *
* Returns all published posts
* * * * * * * * * * * * * * */
function getPublishedPosts() {
	// use global $conn object in function
	global $conn;
	$sql = "SELECT * FROM posts WHERE published=true";
	$result = mysqli_query($conn, $sql);

	// fetch all posts as an associative array called $posts
	$posts = mysqli_fetch_all($result, MYSQLI_ASSOC);

	return $posts;
}

// more functions to come here ...
?>

index.php फ़ाइल के शीर्ष भाग में, कॉन्फ़िगरेशन वाली पंक्ति के ठीक नीचे। php , डेटाबेस को क्वेरी करने के लिए इस कोड को जोड़ें:

<!-- config.php should be here as the first include  -->

<?php require_once( ROOT_PATH . '/includes/public_functions.php') ?>

<!-- Retrieve all posts from database  -->
<?php $posts = getPublishedPosts(); ?>

हमने कोड की दो पंक्तियाँ जोड़ीं। पहले में हमारी index.php फ़ाइल में public_functions.php (जिसमें फ़ंक्शन होते हैं) फ़ाइल शामिल है। कोड की दूसरी पंक्ति getPublishedPosts() फ़ंक्शन को कॉल करती है जो डेटाबेस से पूछताछ करती है और डेटाबेस से पुनर्प्राप्त पोस्ट को $posts नामक एक चर में लौटाती है। अब आइए इन पोस्ट को index.php पेज पर देखें और प्रदर्शित करें।

हमारी प्रसिद्ध index.php फ़ाइल फिर से खोलें। सामग्री अनुभाग में कहीं बीच में, आपको एक


टैग और एक टिप्पणी मिलेगी जो इंगित करेगी कि और सामग्री कहां आनी है। स्पेस में,
टैग के ठीक नीचे, यह कोड जोड़ें:

<hr>
<!-- more content still to come here ... -->

<!-- Add this ... -->
<?php foreach ($posts as $post): ?>
	<div class="post" style="margin-left: 0px;">
		<img src="<?php echo BASE_URL . '/static/images/' . $post['image']; ?>" class="post_image" alt="">
		<a href="single_post.php?post-slug=<?php echo $post['slug']; ?>">
			<div class="post_info">
				<h3><?php echo $post['title'] ?></h3>
				<div class="info">
					<span><?php echo date("F j, Y ", strtotime($post["created_at"])); ?></span>
					<span class="read_more">Read more...</span>
				</div>
			</div>
		</a>
	</div>
<?php endforeach ?>

ठीक है, कृपया अभी तक पृष्ठ को पुनः लोड न करें। आइए इस पोस्ट लिस्टिंग में स्टाइल जोड़ें। public_styling.css खोलें और इसमें यह कोड जोड़ें:

/* CONTENT */
.content {
	margin: 5px auto;
	border-radius: 5px;
	min-height: 400px;
}
.content:after {
	content: "";
	display: block;
	clear: both;
}
.content .content-title {
	margin: 10px 0px;
	color: #374447;
	font-family: 'Averia Serif Libre', cursive;
}
.content .post {
	width: 335px;
	margin: 9px;
	min-height: 320px;
	float: left;
	border-radius: 2px;
	border: 1px solid #b3b3b3;
	position: relative;
}
.content .post .category {
	margin-top: 0px;
	padding: 3px 8px;
	color: #374447;
	background: white;
	display: inline-block;
	border-radius: 2px;
	border: 1px solid #374447;
	box-shadow: 3px 2px 2px;
	position: absolute;
	left: 5px; top: 5px;
	z-index: 3;
}
.content .post .category:hover {
	box-shadow: 3px 2px 2px;
	color: white;
	background: #374447;
	transition: .4s;
	opacity: 1;
}
.content .post .post_image {
	height: 260px;
	width: 100%;
	background-size: 100%;
}
.content .post .post_image {
	width: 100%;
	height: 260px;
}
.content .post .post_info {
	height: 100%;
	padding: 0px 5px;
	font-weight: 200;
    font-family: 'Noto Serif', serif;
}
.content .post .post_info {
	color: #222;
}
.content .post .post_info span {
	color: #A6A6A6;
	font-style: italic;
}
.content .post .post_info span.read_more {
	position: absolute;
	right: 5px; bottom: 5px;
}

अब आप पृष्ठ को पुनः लोड कर सकते हैं।

यदि सब कुछ ठीक रहा, तो आपको "हाल के लेख" शीर्षक के नीचे थंबनेल के रूप में स्टाइल की गई एक पोस्ट दिखाई देगी। याद रखें कि हमने डेटाबेस में दो रिकॉर्ड डाले थे लेकिन केवल एक ही प्रदर्शित किया जा रहा है। ऐसा इसलिए है क्योंकि रिकॉर्ड में से एक का प्रकाशित फ़ील्ड झूठा (अर्थात, 0) पर सेट था, और चूंकि केवल प्रकाशित लेख प्रदर्शित होते हैं, हम केवल एक को प्रकाशित करते हैं।

लेकिन अभी तक की हमारी पोस्ट किसी भी विषय के अंतर्गत वर्गीकृत नहीं हैं। आइए एक विषय तालिका बनाएं और पोस्ट और विषय तालिका के बीच कई-से-अनेक संबंध बनाएं। ऐसा करने के लिए, हम दो नई तालिकाएँ बनाएंगे:विषयों को संग्रहीत करने के लिए विषय, और पोस्ट और विषयों के बीच संबंध को संभालने के लिए पोस्ट_टॉपिक तालिका।

विषय:

+----+-----------+------------------------+------------+
|     field      |     type               | specs      |
+----+-----------+------------------------+------------+
|  id            | INT(11)                |            |
|  name          | VARCHAR(255)           |            |
|  slug          | VARCHAR(255)           | UNIQUE     |
+----------------+--------------+---------+------------+

post_topic:

+----+-----------+------------------------+------------+
|     field      |     type               | specs      |
+----+-----------+------------------------+------------+
|  id            | INT(11)                |            |
|  post_id       | INT(11)                |  UNIQUE    |
|  topic_id      | INT(11)                |            |
+----------------+--------------+---------+------------+

हम वास्तव में जिस चीज में रुचि रखते हैं वह है post_topic तालिका। यह वह तालिका है जो पदों और विषयों के बीच संबंध को संभालती है। जब किसी विशेष विषय के तहत कोई पोस्ट बनाया जाता है, तो उस पोस्ट की आईडी (post_id), साथ ही उस विषय की आईडी (topic_id) जिसके तहत वह पोस्ट बनाई जाती है, को पोस्ट_टॉपिक टेबल में डाला जाता है।

आइए इस संबंध को स्थापित करें ताकि जब कोई पोस्ट हटा दी जाए, तो पोस्ट_टॉपिक तालिका में उनकी प्रविष्टि भी स्वचालित रूप से हटा दी जाएगी; जब पोस्ट मौजूद नहीं है तो आप किसी पोस्ट के संबंध के बारे में जानकारी नहीं रखना चाहते हैं?

पोस्ट_टॉपिक टेबल पर क्लिक करें/चुनें, फिर PHPMyAdmin नेवबार के स्ट्रक्चर टैब पर क्लिक करें। इसके बाद, स्ट्रक्चर टैब के ठीक नीचे रिलेशन व्यू पर क्लिक करें (यह PHPMyAdmin के आपके संस्करण के आधार पर कहीं और पाया जा सकता है)। फिर नीचे दिए गए फॉर्म को इस प्रकार भरें:

युक्ति:+ बाधा जोड़ें लिंक का उपयोग एक नई बाधा जोड़ने के लिए किया जाता है।

ON DELETE और ON UPDATE सभी क्रमशः CASCADE और NO ACTION पर सेट हैं ताकि जब कोई पोस्ट या विषय हटा दिया जाए, तो post_topic तालिका में उसकी संबंध जानकारी भी स्वचालित रूप से हटा दी जाती है। (छवि में मैंने NO ACTION के बजाय ON UPDATE को CASCADE पर सेट करने की गलती की, इसके लिए क्षमा करें)।

सहेजें पर क्लिक करें और बस इतना ही। टेबल अब संबंधित हैं। लेकिन पोस्ट और टॉपिक के बीच संबंध स्थापित करने के लिए, हमें टॉपिक्स टेबल को टॉपिक और अंत में पोस्ट_टॉपिक टेबल से भरना होगा जो वास्तविक संबंध जानकारी है।

अब दो तालिकाओं में कुछ प्रविष्टियाँ सम्मिलित करते हैं:

विषय:

INSERT INTO `topics` (`id`, `name`, `slug`) VALUES
(1, 'Inspiration', 'inspiration'),
(2, 'Motivation', 'motivation'),
(3, 'Diary', 'diary')

post_topic:

INSERT INTO `post_topic` (`id`, `post_id`, `topic_id`) VALUES
(1, 1, 1),
(2, 2, 2)

पोस्ट_टॉपिक टेबल पर परिभाषित संबंध कहता है कि विषय तालिका में आईडी 1 वाला विषय पोस्ट टेबल पर आईडी 1 वाली पोस्ट से संबंधित है। आईडी 2 वाले विषय और आईडी 2 वाले पोस्ट के लिए भी यही सच है।

index.php पेज पर प्रत्येक पोस्ट लिस्टिंग पर, हम उस विषय को प्रदर्शित करने जा रहे हैं जिसके तहत पोस्ट बनाया गया है।

ऐसा करने के लिए, हमें डेटाबेस से प्रत्येक पोस्ट के विषय को क्वेरी करने और पोस्ट को उसके विषय के साथ वापस करने के लिए अपने getPublishedPosts () को संशोधित करना होगा जिसे हमने public_functions.php के अंदर बनाया था।

public_functions.php फ़ाइल को इस तरह दिखने के लिए संशोधित करें:

<?php 
/* * * * * * * * * * * * * * *
* Returns all published posts
* * * * * * * * * * * * * * */
function getPublishedPosts() {
	// use global $conn object in function
	global $conn;
	$sql = "SELECT * FROM posts WHERE published=true";
	$result = mysqli_query($conn, $sql);
	// fetch all posts as an associative array called $posts
	$posts = mysqli_fetch_all($result, MYSQLI_ASSOC);

	$final_posts = array();
	foreach ($posts as $post) {
		$post['topic'] = getPostTopic($post['id']); 
		array_push($final_posts, $post);
	}
	return $final_posts;
}
/* * * * * * * * * * * * * * *
* Receives a post id and
* Returns topic of the post
* * * * * * * * * * * * * * */
function getPostTopic($post_id){
	global $conn;
	$sql = "SELECT * FROM topics WHERE id=
			(SELECT topic_id FROM post_topic WHERE post_id=$post_id) LIMIT 1";
	$result = mysqli_query($conn, $sql);
	$topic = mysqli_fetch_assoc($result);
	return $topic;
}
?>

अब index.php फाइल पर जाएं। फ़ोरैच लूप के अंदर, इमेज टैग के ठीक नीचे, विषय प्रदर्शित करने के लिए if स्टेटमेंट जोड़ें। संशोधित करने के बाद आपका फ़ोरैच लूप इस तरह दिखना चाहिए:

<?php foreach ($posts as $post): ?>
	<div class="post" style="margin-left: 0px;">
		<img src="<?php echo BASE_URL . '/static/images/' . $post['image']; ?>" class="post_image" alt="">
        <!-- Added this if statement... -->
		<?php if (isset($post['topic']['name'])): ?>
			<a 
				href="<?php echo BASE_URL . 'filtered_posts.php?topic=' . $post['topic']['id'] ?>"
				class="btn category">
				<?php echo $post['topic']['name'] ?>
			</a>
		<?php endif ?>

		<a href="single_post.php?post-slug=<?php echo $post['slug']; ?>">
			<div class="post_info">
				<h3><?php echo $post['title'] ?></h3>
				<div class="info">
					<span><?php echo date("F j, Y ", strtotime($post["created_at"])); ?></span>
					<span class="read_more">Read more...</span>
				</div>
			</div>
		</a>
	</div>
<?php endforeach ?>

अब पृष्ठ को पुनः लोड करें और आप पोस्ट में प्रदर्शित विषय देखेंगे।

इस फ़ोरैच लूप के अंदर, आप देखते हैं कि दो लिंक हैं जिन पर क्लिक करने पर, आपको दो पेज पर ले जाया जाएगा:filtered_posts.php और single_post.php।

filtered_posts.php एक ऐसा पृष्ठ है जो उपयोगकर्ता द्वारा उस विषय पर क्लिक करने पर किसी विशेष विषय के अंतर्गत सभी पोस्ट सूचीबद्ध करता है।

Single_post.php एक ऐसा पेज है जो उपयोगकर्ता द्वारा पोस्ट थंबनेल पर क्लिक करने पर टिप्पणियों के साथ पूरी पोस्ट को विस्तार से प्रदर्शित करता है।

इन दो फाइलों को हमारी public_functions.php फ़ाइल से कुछ कार्यों की आवश्यकता है। filtered_posts.php को getPublishedPostsByTopic() और getTopicNameById() नामक दो फ़ंक्शन की आवश्यकता होती है, जबकि सिंगल_पोस्ट्स.php को getPost() और getAllTopics() की आवश्यकता होती है।

आइए filtered_posts.php फाइल से शुरू करते हैं। public_functions.php खोलें और इन दो कार्यों को कार्यों की सूची में जोड़ें:

/* * * * * * * * * * * * * * * *
* Returns all posts under a topic
* * * * * * * * * * * * * * * * */
function getPublishedPostsByTopic($topic_id) {
	global $conn;
	$sql = "SELECT * FROM posts ps 
			WHERE ps.id IN 
			(SELECT pt.post_id FROM post_topic pt 
				WHERE pt.topic_id=$topic_id GROUP BY pt.post_id 
				HAVING COUNT(1) = 1)";
	$result = mysqli_query($conn, $sql);
	// fetch all posts as an associative array called $posts
	$posts = mysqli_fetch_all($result, MYSQLI_ASSOC);

	$final_posts = array();
	foreach ($posts as $post) {
		$post['topic'] = getPostTopic($post['id']); 
		array_push($final_posts, $post);
	}
	return $final_posts;
}
/* * * * * * * * * * * * * * * *
* Returns topic name by topic id
* * * * * * * * * * * * * * * * */
function getTopicNameById($id)
{
	global $conn;
	$sql = "SELECT name FROM topics WHERE id=$id";
	$result = mysqli_query($conn, $sql);
	$topic = mysqli_fetch_assoc($result);
	return $topic['name'];
}

आइए सबसे पहले हमारे एप्लिकेशन के रूट फोल्डर (यानी, Complete-blog-php/filtered_posts.php) में filtered_posts.php फाइल बनाएं। मैं अभी आगे बढ़ूंगा और इस पेज का पूरा कोड फाइल के अंदर पेस्ट करूंगा:

filtered_posts.php:

<?php include('config.php'); ?>
<?php include('includes/public_functions.php'); ?>
<?php include('includes/head_section.php'); ?>
<?php 
	// Get posts under a particular topic
	if (isset($_GET['topic'])) {
		$topic_id = $_GET['topic'];
		$posts = getPublishedPostsByTopic($topic_id);
	}
?>
	<title>LifeBlog | Home </title>
</head>
<body>
<div class="container">
<!-- Navbar -->
	<?php include( ROOT_PATH . '/includes/navbar.php'); ?>
<!-- // Navbar -->
<!-- content -->
<div class="content">
	<h2 class="content-title">
		Articles on <u><?php echo getTopicNameById($topic_id); ?></u>
	</h2>
	<hr>
	<?php foreach ($posts as $post): ?>
		<div class="post" style="margin-left: 0px;">
			<img src="<?php echo BASE_URL . '/static/images/' . $post['image']; ?>" class="post_image" alt="">
			<a href="single_post.php?post-slug=<?php echo $post['slug']; ?>">
				<div class="post_info">
					<h3><?php echo $post['title'] ?></h3>
					<div class="info">
						<span><?php echo date("F j, Y ", strtotime($post["created_at"])); ?></span>
						<span class="read_more">Read more...</span>
					</div>
				</div>
			</a>
		</div>
	<?php endforeach ?>
</div>
<!-- // content -->
</div>
<!-- // container -->

<!-- Footer -->
	<?php include( ROOT_PATH . '/includes/footer.php'); ?>
<!-- // Footer -->

अब पेज को रिफ्रेश करें, विषय पर क्लिक करें और यदि यह आपको उस विषय के तहत पोस्ट प्रदर्शित करने वाले पेज पर ले जाता है, तो आप सही काम कर रहे हैं।

चलिए यही काम सिंगल_पोस्ट.php के साथ करते हैं। public_functions.php खोलें और इन 2 कार्यों को इसमें जोड़ें:

/* * * * * * * * * * * * * * *
* Returns a single post
* * * * * * * * * * * * * * */
function getPost($slug){
	global $conn;
	// Get single post slug
	$post_slug = $_GET['post-slug'];
	$sql = "SELECT * FROM posts WHERE slug='$post_slug' AND published=true";
	$result = mysqli_query($conn, $sql);

	// fetch query results as associative array.
	$post = mysqli_fetch_assoc($result);
	if ($post) {
		// get the topic to which this post belongs
		$post['topic'] = getPostTopic($post['id']);
	}
	return $post;
}
/* * * * * * * * * * * *
*  Returns all topics
* * * * * * * * * * * * */
function getAllTopics()
{
	global $conn;
	$sql = "SELECT * FROM topics";
	$result = mysqli_query($conn, $sql);
	$topics = mysqli_fetch_all($result, MYSQLI_ASSOC);
	return $topics;
}

अब फ़ाइल बनाएं full-blog-php/single_post.php और उसमें यह कोड पेस्ट करें:

<?php  include('config.php'); ?>
<?php  include('includes/public_functions.php'); ?>
<?php 
	if (isset($_GET['post-slug'])) {
		$post = getPost($_GET['post-slug']);
	}
	$topics = getAllTopics();
?>
<?php include('includes/head_section.php'); ?>
<title> <?php echo $post['title'] ?> | LifeBlog</title>
</head>
<body>
<div class="container">
	<!-- Navbar -->
		<?php include( ROOT_PATH . '/includes/navbar.php'); ?>
	<!-- // Navbar -->
	
	<div class="content" >
		<!-- Page wrapper -->
		<div class="post-wrapper">
			<!-- full post div -->
			<div class="full-post-div">
			<?php if ($post['published'] == false): ?>
				<h2 class="post-title">Sorry... This post has not been published</h2>
			<?php else: ?>
				<h2 class="post-title"><?php echo $post['title']; ?></h2>
				<div class="post-body-div">
					<?php echo html_entity_decode($post['body']); ?>
				</div>
			<?php endif ?>
			</div>
			<!-- // full post div -->
			
			<!-- comments section -->
			<!--  coming soon ...  -->
		</div>
		<!-- // Page wrapper -->

		<!-- post sidebar -->
		<div class="post-sidebar">
			<div class="card">
				<div class="card-header">
					<h2>Topics</h2>
				</div>
				<div class="card-content">
					<?php foreach ($topics as $topic): ?>
						<a 
							href="<?php echo BASE_URL . 'filtered_posts.php?topic=' . $topic['id'] ?>">
							<?php echo $topic['name']; ?>
						</a> 
					<?php endforeach ?>
				</div>
			</div>
		</div>
		<!-- // post sidebar -->
	</div>
</div>
<!-- // content -->

<?php include( ROOT_PATH . '/includes/footer.php'); ?>

आइए अब इस पर स्टाइल लागू करें। public_styling.css खोलें और इसमें यह स्टाइलिंग कोड जोड़ें:

/* * * * * * * * *
* SINGLE PAGE 
* * * * * * * * */
.content .post-wrapper {
	width: 70%;
	float: left;
	min-height: 250px;
}
.full-post-div {
	min-height: 300px;
	padding: 20px;
	border: 1px solid #e4e1e1;
	border-radius: 2px;
}
.full-post-div h2.post-title {
	margin: 10px auto 20px;
	text-align: center;
}
.post-body-div {
	font-family: 'Noto Serif', serif;
	font-size: 1.2em;
}
.post-body-div p {
	margin:20px 0px;
}
.post-sidebar {
	width: 24%;
	float: left;
	margin-left: 5px;
	min-height: 400px;
}
.content .post-comments {
	margin-top: 25px;
	border-radius: 2px;
	border-top: 1px solid #e4e1e1;
	padding: 10px;
}
.post-sidebar .card {
	width: 95%;
	margin: 10px auto;
	border: 1px solid #e4e1e1;
	border-radius: 10px 10px 0px 0px;
}
.post-sidebar .card .card-header {
	padding: 10px;
	text-align: center;
	border-radius: 3px 3px 0px 0px;
	background: #3E606F;
}
.post-sidebar .card .card-header h2 {
	color: white;
}
.post-sidebar .card .card-content a {
	display: block;
	box-sizing: border-box;
	padding: 8px 10px;
	border-bottom: 1px solid #e4e1e1;
	color: #444;
}
.post-sidebar .card .card-content a:hover {
	padding-left: 20px;
	background: #F9F9F9;
	transition: 0.1s;
}

अभी अच्छा लग रहा है?

एक आखिरी काम करना है और हम सार्वजनिक क्षेत्र के साथ काफी कुछ कर लेंगे:हम उपयोगकर्ता पंजीकरण और लॉगिन लागू करेंगे।

उपयोगकर्ता पंजीकरण और लॉगिन

क्योंकि मैंने पहले ही उपयोगकर्ता पंजीकरण और लॉगिन पर एक ट्यूटोरियल बना लिया है, मैं इस भाग के साथ काफी हद तक स्पष्ट हो जाऊंगा और ज्यादा व्याख्या नहीं करूंगा।

अपने रूट फोल्डर में दो फाइलें बनाएं जिनका नाम register.php और login.php है। उनमें से प्रत्येक को खोलें और उनमें यह कोड डालें:

register.php:

<?php  include('config.php'); ?>
<!-- Source code for handling registration and login -->
<?php  include('includes/registration_login.php'); ?>

<?php include('includes/head_section.php'); ?>

<title>LifeBlog | Sign up </title>
</head>
<body>
<div class="container">
	<!-- Navbar -->
		<?php include( ROOT_PATH . '/includes/navbar.php'); ?>
	<!-- // Navbar -->

	<div style="width: 40%; margin: 20px auto;">
		<form method="post" action="register.php" >
			<h2>Register on LifeBlog</h2>
			<?php include(ROOT_PATH . '/includes/errors.php') ?>
			<input  type="text" name="username" value="<?php echo $username; ?>"  placeholder="Username">
			<input type="email" name="email" value="<?php echo $email ?>" placeholder="Email">
			<input type="password" name="password_1" placeholder="Password">
			<input type="password" name="password_2" placeholder="Password confirmation">
			<button type="submit" class="btn" name="reg_user">Register</button>
			<p>
				Already a member? <a href="login.php">Sign in</a>
			</p>
		</form>
	</div>
</div>
<!-- // container -->
<!-- Footer -->
	<?php include( ROOT_PATH . '/includes/footer.php'); ?>
<!-- // Footer -->

login.php:  

<?php  include('config.php'); ?>
<?php  include('includes/registration_login.php'); ?>
<?php  include('includes/head_section.php'); ?>
	<title>LifeBlog | Sign in </title>
</head>
<body>
<div class="container">
	<!-- Navbar -->
	<?php include( ROOT_PATH . '/includes/navbar.php'); ?>
	<!-- // Navbar -->

	<div style="width: 40%; margin: 20px auto;">
		<form method="post" action="login.php" >
			<h2>Login</h2>
			<?php include(ROOT_PATH . '/includes/errors.php') ?>
			<input type="text" name="username" value="<?php echo $username; ?>" value="" placeholder="Username">
			<input type="password" name="password" placeholder="Password">
			<button type="submit" class="btn" name="login_btn">Login</button>
			<p>
				Not yet a member? <a href="register.php">Sign up</a>
			</p>
		</form>
	</div>
</div>
<!-- // container -->

<!-- Footer -->
	<?php include( ROOT_PATH . '/includes/footer.php'); ?>
<!-- // Footer -->

दोनों फाइलों के शीर्ष खंडों में, हमने पंजीकरण और लॉगिन के तर्क को संभालने के लिए पंजीकरण_लॉगिन.php नाम की एक फ़ाइल शामिल की। यह वह फ़ाइल है जिसमें लॉगिन और रजिस्टर फॉर्म की जानकारी सबमिट की जाएगी और डेटाबेस के साथ संचार किया जाएगा। आइए इसे अपने शामिल फ़ोल्डर में बनाएं और इस कोड को इसके अंदर थूक दें:

पूर्ण-ब्लॉग-php/includes/registration_login.php:

<?php 
	// variable declaration
	$username = "";
	$email    = "";
	$errors = array(); 

	// REGISTER USER
	if (isset($_POST['reg_user'])) {
		// receive all input values from the form
		$username = esc($_POST['username']);
		$email = esc($_POST['email']);
		$password_1 = esc($_POST['password_1']);
		$password_2 = esc($_POST['password_2']);

		// form validation: ensure that the form is correctly filled
		if (empty($username)) {  array_push($errors, "Uhmm...We gonna need your username"); }
		if (empty($email)) { array_push($errors, "Oops.. Email is missing"); }
		if (empty($password_1)) { array_push($errors, "uh-oh you forgot the password"); }
		if ($password_1 != $password_2) { array_push($errors, "The two passwords do not match");}

		// Ensure that no user is registered twice. 
		// the email and usernames should be unique
		$user_check_query = "SELECT * FROM users WHERE username='$username' 
								OR email='$email' LIMIT 1";

		$result = mysqli_query($conn, $user_check_query);
		$user = mysqli_fetch_assoc($result);

		if ($user) { // if user exists
			if ($user['username'] === $username) {
			  array_push($errors, "Username already exists");
			}
			if ($user['email'] === $email) {
			  array_push($errors, "Email already exists");
			}
		}
		// register user if there are no errors in the form
		if (count($errors) == 0) {
			$password = md5($password_1);//encrypt the password before saving in the database
			$query = "INSERT INTO users (username, email, password, created_at, updated_at) 
					  VALUES('$username', '$email', '$password', now(), now())";
			mysqli_query($conn, $query);

			// get id of created user
			$reg_user_id = mysqli_insert_id($conn); 

			// put logged in user into session array
			$_SESSION['user'] = getUserById($reg_user_id);

			// if user is admin, redirect to admin area
			if ( in_array($_SESSION['user']['role'], ["Admin", "Author"])) {
				$_SESSION['message'] = "You are now logged in";
				// redirect to admin area
				header('location: ' . BASE_URL . 'admin/dashboard.php');
				exit(0);
			} else {
				$_SESSION['message'] = "You are now logged in";
				// redirect to public area
				header('location: index.php');				
				exit(0);
			}
		}
	}

	// LOG USER IN
	if (isset($_POST['login_btn'])) {
		$username = esc($_POST['username']);
		$password = esc($_POST['password']);

		if (empty($username)) { array_push($errors, "Username required"); }
		if (empty($password)) { array_push($errors, "Password required"); }
		if (empty($errors)) {
			$password = md5($password); // encrypt password
			$sql = "SELECT * FROM users WHERE username='$username' and password='$password' LIMIT 1";

			$result = mysqli_query($conn, $sql);
			if (mysqli_num_rows($result) > 0) {
				// get id of created user
				$reg_user_id = mysqli_fetch_assoc($result)['id']; 

				// put logged in user into session array
				$_SESSION['user'] = getUserById($reg_user_id); 

				// if user is admin, redirect to admin area
				if ( in_array($_SESSION['user']['role'], ["Admin", "Author"])) {
					$_SESSION['message'] = "You are now logged in";
					// redirect to admin area
					header('location: ' . BASE_URL . '/admin/dashboard.php');
					exit(0);
				} else {
					$_SESSION['message'] = "You are now logged in";
					// redirect to public area
					header('location: index.php');				
					exit(0);
				}
			} else {
				array_push($errors, 'Wrong credentials');
			}
		}
	}
	// escape value from form
	function esc(String $value)
	{	
		// bring the global db connect object into function
		global $conn;

		$val = trim($value); // remove empty space sorrounding string
		$val = mysqli_real_escape_string($conn, $value);

		return $val;
	}
	// Get user info from user id
	function getUserById($id)
	{
		global $conn;
		$sql = "SELECT * FROM users WHERE id=$id LIMIT 1";

		$result = mysqli_query($conn, $sql);
		$user = mysqli_fetch_assoc($result);

		// returns user in an array format: 
		// ['id'=>1 'username' => 'Awa', 'email'=>'[email protected]', 'password'=> 'mypass']
		return $user; 
	}
?>

http://localhost/complete-blog-php/register.php पर जाएं और आपको यह कहते हुए एक त्रुटि दिखाई देगी कि error.php फ़ाइल नहीं मिली।

error.php फ़ाइल फ़ॉर्म सत्यापन त्रुटियों को प्रदर्शित करने के लिए कोड वाली फ़ाइल है। कंप्लीट-ब्लॉग-php/includes के अंदर error.php बनाएं और इस कोड को इसमें पेस्ट करें:

<?php if (count($errors) > 0) : ?>
  <div class="message error validation_errors" >
  	<?php foreach ($errors as $error) : ?>
  	  <p><?php echo $error ?></p>
  	<?php endforeach ?>
  </div>
<?php endif ?>

एक बार फिर public_styling.css खोलें, आइए इस error.php फ़ाइल और कुछ अन्य तत्वों के लिए स्टाइलिंग कोड का यह अंतिम भाग जोड़ें:

/* NOTIFICATION MESSAGES */
.message {
	width: 100%; 
	margin: 0px auto; 
	padding: 10px 0px; 
	color: #3c763d; 
	background: #dff0d8; 
	border: 1px solid #3c763d;
	border-radius: 5px; 
	text-align: center;
}
.error {
	color: #a94442; 
	background: #f2dede; 
	border: 1px solid #a94442; 
	margin-bottom: 20px;
}
.validation_errors p {
	text-align: left;
	margin-left: 10px;
}
.logged_in_info {
	text-align: right; 
	padding: 10px;
}

और अब त्रुटि संदेश चला गया है। बिना फॉर्म भरे रजिस्टर बटन पर क्लिक करें और आप सुंदर त्रुटि संदेश प्रस्तुत करते हुए देखते हैं।

रजिस्टर.php पेज पर फॉर्म भरकर और रजिस्टर बटन पर क्लिक करके एक नया उपयोगकर्ता बनाते हैं। आप उपयोगकर्ता नाम, ईमेल और पासवर्ड के लिए जो भी मान्य जानकारी प्रदान कर सकते हैं; बस सुनिश्चित करें कि आप उन्हें याद रखें क्योंकि हम उनका उपयोग बहुत जल्द लॉगिन पेज पर लॉग इन करने के लिए करेंगे।

जब कोई उपयोगकर्ता लॉग इन करता है, तो उसे निश्चित रूप से लॉग आउट करने में सक्षम होने की आवश्यकता होगी। एप्लिकेशन के रूट फोल्डर में logout.php नाम की फाइल बनाएं।

पूर्ण-ब्लॉग-php/logout.php: 

<?php 
	session_start();
	session_unset($_SESSION['user']);
	session_destroy();
	header('location: index.php');
?>

इसके अलावा, जब कोई उपयोगकर्ता लॉग इन करता है, तो हम उनका नाम और एक लिंक या बटन प्रदर्शित करना चाहते हैं, ताकि वे लॉग आउट करने के लिए क्लिक कर सकें। सार्वजनिक क्षेत्र के लिए, हम इसे हमारे द्वारा शामिल बैनर.php फ़ाइल में करेंगे। बैनर.php फ़ाइल खोलें और इस तरह दिखने के लिए कोड को संशोधित करें:

complete-blog-php/includes/banner.php:

<?php if (isset($_SESSION['user']['username'])) { ?>
	<div class="logged_in_info">
		<span>welcome <?php echo $_SESSION['user']['username'] ?></span>
		|
		<span><a href="logout.php">logout</a></span>
	</div>
<?php }else{ ?>
	<div class="banner">
		<div class="welcome_msg">
			<h1>Today's Inspiration</h1>
			<p> 
			    One day your life <br> 
			    will flash before your eyes. <br> 
			    Make sure it's worth watching. <br>
				<span>~ Gerard Way</span>
			</p>
			<a href="register.php" class="btn">Join us!</a>
		</div>

		<div class="login_div">
			<form action="<?php echo BASE_URL . 'index.php'; ?>" method="post" >
				<h2>Login</h2>
				<div style="width: 60%; margin: 0px auto;">
					<?php include(ROOT_PATH . '/includes/errors.php') ?>
				</div>
				<input type="text" name="username" value="<?php echo $username; ?>" placeholder="Username">
				<input type="password" name="password"  placeholder="Password"> 
				<button class="btn" type="submit" name="login_btn">Sign in</button>
			</form>
		</div>
	</div>
<?php } ?>

It checks the session to see if a user is available (logged in). If logged in, the username is displayed with the logout link. When there is a logged in user, the banner does not get displayed since it is some sort of a welcome screen to guest users.

You notice that the banner has a login form and this banner is included inside index.php file. Therefore we need to include the code that handles registration and login inside our index.php file also. Open index.php and add this line directly under the include for public_functions.php:

top section of complete-blog-php/index.php:

<?php require_once( ROOT_PATH . '/includes/registration_login.php') ?>

And that's it with user registration and login. In the next section, we begin work on the admin area.

Thank you so much for sticking around up to this point. I hope you found it helpful. If you have any worries, please leave it in the comments below. Your feedback is always very helpful and if you have any bugs in your code, I will try my best to help you out.

I will be very much encouraged to create more of these tutorials with improved quality if you share, subscribe to my site and recommend my site to your friends.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. PHP और MySQL डेटाबेस का उपयोग करके पूर्ण उपयोगकर्ता पंजीकरण प्रणाली

  2. MySQL ने कहा:दस्तावेज़ीकरण # 1045 - उपयोगकर्ता 'रूट' @ 'लोकलहोस्ट' के लिए प्रवेश निषेध (पासवर्ड का उपयोग करके:नहीं)

  3. MySQL तालिका से अद्वितीय बाधा छोड़ना

  4. MyIsam इंजन लेनदेन समर्थन

  5. MySQL प्रश्नों में, कहां के बजाय शामिल हों का उपयोग क्यों करें?