Advertisement
  1. Code
  2. PHP

एक PHP5 फ्रेमवर्क बनाएँ - भाग 2

Scroll to top
Read Time: 23 min

() translation by (you can also view the original English article)

हमारे फ्रेमवर्क के लिए बेसिक स्ट्रक्चर के साथ, यह समय फंक्शनलिटी जोड़ना शुरू करने का है। इस ट्यूटोरियल में हम एक टेम्पलेट मैनेजर और डेटाबेस हैंडलर बनाएंगे, जिससे हमें लगभग किसी भी प्रोजेक्ट में उपयोग के लिए एक शक्तिशाली फ्रेमवर्क के करीब एक कदम मिल जाएगा। यदि आपने पहले से नहीं किया हैं, तो पहले इस सीरीज के भाग 1 की समीक्षा करना सुनिश्चित करें!




MVC: स्ट्रक्चर को ट्विक करें

इस ट्यूटोरियल के पहले भाग में, हमने अपने ऍप्लिकेशन्स के लिए बिज़नेस लॉजिक को स्टोर करने के लिए controllers नामक एक फ़ोल्डर बनाया है। जैसा कि daok ने एक कमेंट में बताया, यह सभी बिज़नेस लॉजिक के लिए सबसे अच्छी जगह नहीं है, और इस लॉजिक को स्टोर करने के लिए model का उपयोग किया जाना चाहिए। पहले, मैंने हमेशा अपने अधिकांश ऍप्लिकेशन्स में मॉडल के रूप में डेटाबेस का उपयोग किया है, हालांकि, इसे थोड़ा और अलग करने से हमारा फ्रेमवर्क और भी शक्तिशाली और एक्सटेंड करना आसान हो जाएगा।

तो, MVC क्या है? MVC एक डिजाइन पैटर्न है (जैसा कि सिंगलटन और रजिस्ट्री पैटर्न था जिसे हमने भाग 1 में देखा था), और यह मॉडल व्यू कंट्रोलर के लिए है, और इस पैटर्न का उद्देश्य बिज़नेस लॉजिक, यूजर इंटरफ़ेस एक्शन्स और यूजर इंटरफ़ेस को अलग करना है एक दूसरे से। यद्यपि हम अभी तक हमारे मॉडल और कंट्रोलर्स के साथ कुछ भी नहीं करने जा रहे हैं, आइए "models" फ़ोल्डर को शामिल करने के लिए हमारे फ्रेमवर्क फ़ोल्डर स्ट्रक्चर को अपडेट करें। मॉडल में मुख्य बिज़नेस लॉजिक होगा, और कंट्रोलर यूजर इंटरैक्शन से निपटेंगे (उदाहरण के लिए डेटा सबमिट करना, जैसे कोई कमेंट)। NB: हमारे __autoload फ़ंक्शन को बदलने की आवश्यकता नहीं है।

डेटाबेस हैंडलर

PHP का उपयोग करने वाली अधिकांश वेबसाइटें और वेब एप्लिकेशन भी डेटाबेस इंजन का उपयोग करते हैं, जैसे MySQL। यदि हम अपने सभी डेटाबेस से संबंधित फंक्शन्स को एक ही स्थान पर रखते हैं, तो हम (सैद्धांतिक रूप में) डेटाबेस इंजन को आसानी से बदल सकते हैं। हम कुछ ख़ास ऑपरेशन को आसान बना सकते हैं, जैसे रिकॉर्ड डालना, रिकॉर्ड अपडेट करना या डेटाबेस से रिकॉर्ड्स हटाना। यह कई डेटाबेस कनेक्शन से निपटने के दौरान भी आसान बना सकता है।

तो...हमारे डेटाबेस हैंडलर को क्या करना चाहिए:

  • डेटाबेस में कनेक्शन मैनेज करें
  • डेटाबेस से कुछ लेवल का अब्स्ट्रक्शन प्रदान करने का प्रयास करें
  • क्वेरी को Cache करें ताकि हम बाद में उनका उपयोग कर सकें
  • सामान्य डेटाबेस ऑपरेशन को आसान बनाएं

आइए हमारे डेटाबेस हैंडलर के लिए कोड देखें, फिर हम इसके बाद चर्चा करेंगे।

1
<?php
2
3
/**

4
 * Database management and access class

5
 * This is a very basic level of abstraction

6
 */
7
class database {
8
  
9
	/**

10
	 * Allows multiple database connections

11
	 * probably not used very often by many applications, but still useful

12
	 */
13
	private $connections = array();
14
	
15
	/**

16
	 * Tells the DB object which connection to use

17
	 * setActiveConnection($id) allows us to change this

18
	 */
19
	private $activeConnection = 0;
20
	
21
	/**

22
	 * Queries which have been executed and then "saved for later"

23
	 */
24
	private $queryCache = array();
25
	
26
	/**

27
	 * Data which has been prepared and then "saved for later"

28
	 */
29
	private $dataCache = array();
30
	
31
	/**

32
	 * Record of the last query

33
	 */
34
	private $last;
35
	
36
	
37
	/**

38
	 * Hello

39
	 */
40
    public function __construct()
41
    {
42
    	
43
    }
44
    
45
    /**

46
     * Create a new database connection

47
     * @param String database hostname

48
     * @param String database username

49
     * @param String database password

50
     * @param String database we are using

51
     * @return int the id of the new connection

52
     */
53
    public function newConnection( $host, $user, $password, $database )
54
    {
55
    	$this->connections[] = new mysqli( $host, $user, $password, $database );
56
    	$connection_id = count( $this->connections )-1;
57
    	if( mysqli_connect_errno() )
58
    	{
59
    		trigger_error('Error connecting to host. '.$this->connections[$connection_id]->error, E_USER_ERROR);
60
		} 	
61
    	
62
    	return $connection_id;
63
    }
64
    
65
    /**

66
     * Close the active connection

67
     * @return void

68
     */
69
    public function closeConnection()
70
    {
71
    	$this->connections[$this->activeConnection]->close();
72
    }
73
    
74
    /**

75
     * Change which database connection is actively used for the next operation

76
     * @param int the new connection id

77
     * @return void

78
     */
79
    public function setActiveConnection( int $new )
80
    {
81
    	$this->activeConnection = $new;
82
    }
83
    
84
    /**

85
     * Store a query in the query cache for processing later

86
     * @param String the query string

87
     * @return the pointed to the query in the cache

88
     */
89
    public function cacheQuery( $queryStr )
90
    {
91
    	if( !$result = $this->connections[$this->activeConnection]->query( $queryStr ) )
92
    	{
93
		    trigger_error('Error executing and caching query: '.$this->connections[$this->activeConnection]->error, E_USER_ERROR);
94
		    return -1;
95
		}
96
		else
97
		{
98
			$this->queryCache[] = $result;
99
			return count($this->queryCache)-1;
100
		}
101
    }
102
    
103
    /**

104
     * Get the number of rows from the cache

105
     * @param int the query cache pointer

106
     * @return int the number of rows

107
     */
108
    public function numRowsFromCache( $cache_id )
109
    {
110
    	return $this->queryCache[$cache_id]->num_rows;	
111
    }
112
    
113
    /**

114
     * Get the rows from a cached query

115
     * @param int the query cache pointer

116
     * @return array the row

117
     */
118
    public function resultsFromCache( $cache_id )
119
    {
120
    	return $this->queryCache[$cache_id]->fetch_array(MYSQLI_ASSOC);
121
    }
122
    
123
    /**

124
     * Store some data in a cache for later

125
     * @param array the data

126
     * @return int the pointed to the array in the data cache

127
     */
128
    public function cacheData( $data )
129
    {
130
    	$this->dataCache[] = $data;
131
    	return count( $this->dataCache )-1;
132
    }
133
    
134
    /**

135
     * Get data from the data cache

136
     * @param int data cache pointed

137
     * @return array the data

138
     */
139
    public function dataFromCache( $cache_id )
140
    {
141
    	return $this->dataCache[$cache_id];
142
    }
143
    
144
    /**

145
     * Delete records from the database

146
     * @param String the table to remove rows from

147
     * @param String the condition for which rows are to be removed

148
     * @param int the number of rows to be removed

149
     * @return void

150
     */
151
    public function deleteRecords( $table, $condition, $limit )
152
    {
153
    	$limit = ( $limit == '' ) ? '' : ' LIMIT ' . $limit;
154
    	$delete = "DELETE FROM {$table} WHERE {$condition} {$limit}";
155
    	$this->executeQuery( $delete );
156
    }
157
    
158
    /**

159
     * Update records in the database

160
     * @param String the table

161
     * @param array of changes field => value

162
     * @param String the condition

163
     * @return bool

164
     */
165
    public function updateRecords( $table, $changes, $condition )
166
    {
167
    	$update = "UPDATE " . $table . " SET ";
168
    	foreach( $changes as $field => $value )
169
    	{
170
    		$update .= "`" . $field . "`='{$value}',";
171
    	}
172
    	   	
173
    	// remove our trailing ,

174
    	$update = substr($update, 0, -1);
175
    	if( $condition != '' )
176
    	{
177
    		$update .= "WHERE " . $condition;
178
    	}
179
    	
180
    	$this->executeQuery( $update );
181
    	
182
    	return true;
183
    	
184
    }
185
    
186
    /**

187
     * Insert records into the database

188
     * @param String the database table

189
     * @param array data to insert field => value

190
     * @return bool

191
     */
192
    public function insertRecords( $table, $data )
193
    {
194
    	// setup some variables for fields and values

195
    	$fields  = "";
196
		$values = "";
197
		
198
		// populate them

199
		foreach ($data as $f => $v)
200
		{
201
			
202
			$fields  .= "`$f`,";
203
			$values .= ( is_numeric( $v ) && ( intval( $v ) == $v ) ) ? $v."," : "'$v',";
204
		
205
		}
206
		
207
		// remove our trailing ,

208
    	$fields = substr($fields, 0, -1);
209
    	// remove our trailing ,

210
    	$values = substr($values, 0, -1);
211
    	
212
		$insert = "INSERT INTO $table ({$fields}) VALUES({$values})";
213
		$this->executeQuery( $insert );
214
		return true;
215
    }
216
    
217
    /**

218
     * Execute a query string

219
     * @param String the query

220
     * @return void

221
     */
222
    public function executeQuery( $queryStr )
223
    {
224
    	if( !$result = $this->connections[$this->activeConnection]->query( $queryStr ) )
225
    	{
226
		    trigger_error('Error executing query: '.$this->connections[$this->activeConnection]->error, E_USER_ERROR);
227
		}
228
		else
229
		{
230
			$this->last = $result;
231
		}
232
		
233
    }
234
    
235
    /**

236
     * Get the rows from the most recently executed query, excluding cached queries

237
     * @return array 

238
     */
239
    public function getRows()
240
    {
241
    	return $this->last->fetch_array(MYSQLI_ASSOC);
242
    }
243
    
244
    /**

245
     * Gets the number of affected rows from the previous query

246
     * @return int the number of affected rows

247
     */
248
    public function affectedRows()
249
    {
250
    	return $this->$this->connections[$this->activeConnection]->affected_rows;
251
    }
252
    
253
    /**

254
     * Sanitize data

255
     * @param String the data to be sanitized

256
     * @return String the sanitized data

257
     */
258
    public function sanitizeData( $data )
259
    {
260
    	return $this->connections[$this->activeConnection]->real_escape_string( $data );
261
    }
262
    
263
    /**

264
     * Deconstruct the object

265
     * close all of the database connections

266
     */
267
    public function __deconstruct()
268
    {
269
    	foreach( $this->connections as $connection )
270
    	{
271
    		$connection->close();
272
    	}
273
    }
274
}
275
?>

इसे अधिक विस्तार से चर्चा करने से पहले, मुझे यह पॉइंट आउट करना चाहिए कि यह डेटाबेस हैंडलर बहुत बेसिक है। हम सीधे क्वेरी को एक्सेक्यूट नहीं करके पूर्ण अब्स्ट्रक्शन प्रदान कर सकते हैं, लेकिन इसके बजाय पैरामीटर पर आधारित क्वेरी फ़ंक्शन पर क्वेरी का निर्माण करना और फिर इसे एक्सेक्यूट करना।

हमारे डिलीट, इन्सर्ट और अपडेट मेथड्स कुछ सामान्य टास्कस को परफॉर्म करना आसान बनाता है (जैसा कि मैंने ऊपर उल्लेखित किया है, हम इसे और अधिक करने के लिए एक्सटेंड कर सकते हैं), केवल टेबल नाम, फ़ील्ड का एक array और करेस्पोंडिंग वैल्यू जैसी जानकारी प्रदान करके, वैल्यूज और कंडीशंस को सीमित करें। क्वेरी को "cached" भी किया जा सकता है ताकि हम बाद में उनके साथ चीजें कर सकें। मुझे यह सुविधा मिलती है (साथ ही डेटा के "cache" array की क्षमता) टेम्पलेट मैनेजर के साथ मिलकर बहुत आसान होती है, क्योंकि हम डेटा की row के माध्यम से आसानी से पुन: प्रयास कर सकते हैं और इसे अपने टेम्पलेट्स में थोड़ा झगड़ा कर सकते हैं, जैसा कि आप करेंगे देखें जब हम टेम्पलेट मैनेजर को देखते हैं।

1
// insert record

2
$registry->getObject('db')->insertRecords( 'testTable', array('name'=>'Michael' ) );
3
// update a record

4
$registry->getObject('db')->updateRecords( 'testTable', array('name'=>'MichaelP' ), 'ID=2' );
5
// delete a record (well, upto 5 in this case)

6
$registry->getObject('db')->deleteRecords( 'testTable', "name='MichaelP'", 5 );

हम अपेक्षाकृत आसानी से कई डेटाबेस कनेक्शन के साथ भी काम कर सकते हैं, तब तक हम उचित कनेक्शन के बीच स्विच करते हैं, जब तक हमें आवश्यकता होती है (हालांकि इस क्वेरी के दौरान काम नहीं करेगा और बिना किसी काम के हमारे टेम्पलेट मैनेजर के माध्यम से उन्हें रिट्रीव करेगा), उदाहरण के लिए, नीचे कोड स्निपेट हमें दो डेटाबेस से रिकॉर्ड हटाने की अनुमति देगा।

1
// our second database connection (let's assume we already have a connection to our main DB)

2
$newConnection = $registry->getObject('db')->newConnection('localhost', 'root', 'password', 'secondDB');
3
// delete from the primary db connection

4
$registry->getObject('db')->deleteRecords( 'testTable', "name='MichaelP'", 5 );
5
// change our active db connection, to allow future queries to be on the second connection

6
$registry->getObject('db')->setActiveConnection( $newConnection );
7
// delete from the secondary db connection

8
$registry->getObject('db')->deleteRecords( 'testTable', "name='MichaelP'", 5 );
9
// revert the active connection so future queries are on the primary db connection

10
$registry->getObject('db')->setActiveConnection( 0 );

हम इस क्लास को कैसे एक्सटेंड करना चाहते हैं?

  • फुल अब्स्ट्रक्शन
  • इनहेरिटेंस का उपयोग करें, एक इंटरफ़ेस बनाएं और डेटाबेस क्लास से इसका इन्हेरिट हो, हर डेटाबेस इंजन
  • के लिए अलगक्वेरी को cache करते समय क्वेरी के साथ कनेक्शन id को स्टोर करें
  • डेटा को सनिटीज़ (sanitize) करने के लिए इच्छित डेटा के प्रकार के आधार पर डेटा सनिटीज़िंग (sanitizing) में सुधार करें

टेम्पलेट मैनेजर

टेम्पलेट मैनेजर सभी आउटपुट को संभालेगा, इसे विभिन्न अलग-अलग टेम्पलेट फाइलों के साथ काम करने में सक्षम होना चाहिए, प्लेसहोल्डर को रीप्लेस करें (मैं उन्हें टैग कहता हूं) डेटा के साथ और डेटाबेस से डेटा की कई rows के साथ टेम्पलेट के हिस्सों के माध्यम से इटरेट करता हूं।

चीजों को आसान बनाने के लिए, हम पेज से संबंधित कंटेंट को शामिल करने के लिए page क्लास का उपयोग करेंगे, इससे हमारे लिए इसे एक्सटेंड करना और बाद में फीचर्स को जोड़ना आसान हो जाता है। टेम्पलेट मैनेजर इस ऑब्जेक्ट को मैनेज करेगा।

1
<?php
2
3
// prevent this file being called directly

4
if ( ! defined( 'PCAFW' ) ) 
5
{
6
	echo 'This file can only be called via the main index.php file, and not directly';
7
	exit();
8
}
9
10
/**

11
 * Template manager class

12
 */
13
class template {
14
15
	private $page;
16
	
17
	/**

18
	 * Hello!

19
	 */
20
    public function __construct() 
21
    {
22
	    include( APP_PATH . '/PCARegistry/objects/page.class.php');
23
	    $this->page = new Page();
24
25
    }
26
    
27
    /**

28
     * Add a template bit onto our page

29
     * @param String $tag the tag where we insert the template e.g. {hello}

30
     * @param String $bit the template bit (path to file, or just the filename)

31
     * @return void

32
     */
33
    public function addTemplateBit( $tag, $bit )
34
    {
35
		if( strpos( $bit, 'skins/' ) === false )
36
		{
37
		    $bit = 'skins/' . PCARegistry::getSetting('skin') . '/templates/' . $bit;
38
		}
39
		$this->page->addTemplateBit( $tag, $bit );
40
    }
41
    
42
    /**

43
     * Put the template bits into our page content

44
     * Updates the pages content

45
     * @return void

46
     */
47
    private function replaceBits()
48
    {
49
	    $bits = $this->page->getBits();
50
	    foreach( $bits as $tag => $template )
51
	    {
52
		    $templateContent = file_get_contents( $bit );
53
		    $newContent = str_replace( '{' . $tag . '}', $templateContent, $this->page->getContent() );
54
		    $this->page->setContent( $newContent );
55
	    }
56
    }
57
    
58
    /**

59
     * Replace tags in our page with content

60
     * @return void

61
     */
62
    private function replaceTags()
63
    {
64
	    // get the tags

65
	    $tags = $this->page->getTags();
66
	    // go through them all

67
	    foreach( $tags as $tag => $data )
68
	    {
69
		    if( is_array( $data ) )
70
		    {
71
			  
72
			    if( $data[0] == 'SQL' )
73
			    {
74
				    // it is a cached query...replace DB tags

75
				    $this->replaceDBTags( $tag, $data[1] );
76
			    }
77
			    elseif( $data[0] == 'DATA' )
78
			    {
79
				     // it is some cached data...replace data tags

80
				    $this->replaceDataTags( $tag, $data[1] );
81
			    }
82
	    	}
83
	    	else
84
	    	{	
85
		    	// replace the content	    	

86
		    	$newContent = str_replace( '{' . $tag . '}', $data, $this->page->getContent() );
87
		    	// update the pages content

88
		    	$this->page->setContent( $newContent );
89
	    	}
90
	    }
91
    }
92
    
93
    /**

94
     * Replace content on the page with data from the DB

95
     * @param String $tag the tag defining the area of content

96
     * @param int $cacheId the queries ID in the query cache

97
     * @return void

98
     */
99
    private function replaceDBTags( $tag, $cacheId )
100
    {
101
	    $block = '';
102
		$blockOld = $this->page->getBlock( $tag );
103
		
104
		// foreach record relating to the query...

105
		while ($tags = PCARegistry::getObject('db')->resultsFromCache( $cacheId ) )
106
		{
107
			$blockNew = $blockOld;
108
			// create a new block of content with the results replaced into it

109
			foreach ($tags as $ntag => $data) 
110
	       	{
111
	        	$blockNew = str_replace("{" . $ntag . "}", $data, $blockNew); 
112
	        }
113
	        $block .= $blockNew;
114
		}
115
		$pageContent = $this->page->getContent();
116
		// remove the seperator in the template, cleaner HTML

117
		$newContent = str_replace( '<!-- START ' . $tag . ' -->' . $blockOld . '<!-- END ' . $tag . ' -->', $block, $pageContent );
118
		// update the page content

119
		$this->page->setContent( $newContent );
120
	}
121
    
122
	/**

123
     * Replace content on the page with data from the cache

124
     * @param String $tag the tag defining the area of content

125
     * @param int $cacheId the datas ID in the data cache

126
     * @return void

127
     */
128
    private function replaceDataTags( $tag, $cacheId )
129
    {
130
	    $block = $this->page->getBlock( $tag );
131
		$blockOld = $block;
132
		while ($tags = PCARegistry::getObject('db')->dataFromCache( $cacheId ) )
133
		{
134
			foreach ($tags as $tag => $data) 
135
	       	{
136
		       	$blockNew = $blockOld;
137
	        	$blockNew = str_replace("{" . $tag . "}", $data, $blockNew); 
138
	        }
139
	        $block .= $blockNew;
140
		}
141
		$pageContent = $this->page->getContent();
142
		$newContent = str_replace( $blockOld, $block, $pageContent );
143
		$this->page->setContent( $newContent );
144
    }
145
    
146
    /**

147
     * Get the page object

148
     * @return Object 

149
     */
150
    public function getPage()
151
    {
152
	    return $this->page;
153
    }
154
    
155
    /**

156
     * Set the content of the page based on a number of templates

157
     * pass template file locations as individual arguments

158
     * @return void

159
     */
160
    public function buildFromTemplates()
161
    {
162
	    $bits = func_get_args();
163
	    $content = "";
164
	    foreach( $bits as $bit )
165
	    {
166
		    
167
		    if( strpos( $bit, 'skins/' ) === false )
168
		    {
169
			    $bit = 'skins/' . PCARegistry::getSetting('skin') . '/templates/' . $bit;
170
		    }
171
		    if( file_exists( $bit ) == true )
172
		    {
173
			    $content .= file_get_contents( $bit );
174
		    }
175
		    
176
	    }
177
	    $this->page->setContent( $content );
178
    }
179
    
180
    /**

181
     * Convert an array of data (i.e. a db row?) to some tags

182
     * @param array the data 

183
     * @param string a prefix which is added to field name to create the tag name

184
     * @return void

185
     */
186
    public function dataToTags( $data, $prefix )
187
    {
188
	    foreach( $data as $key => $content )
189
	    {
190
		    $this->page->addTag( $key.$prefix, $content);
191
	    }
192
    }
193
    
194
    public function parseTitle()
195
    {
196
	    $newContent = str_replace('<title>', '<title>'. $page->getTitle(), $this->page->getContent() );
197
	    $this->page->setContent( $newContent );
198
    }
199
    
200
    /**

201
     * Parse the page object into some output

202
     * @return void

203
     */
204
    public function parseOutput()
205
    {
206
	    $this->replaceBits();
207
	    $this->replaceTags();
208
	    $this->parseTitle();
209
    }
210
    
211
    
212
    
213
}
214
?>

तो, यह क्लास वास्तव में क्या करती है?

हमारा पेज ऑब्जेक्ट बनाता है, और इसे टेम्पलेट फ़ाइलों से बेस करता है, पेज ऑब्जेक्ट में कंटेंट और जानकारी होती है जो पेज के HTML को बनाने के लिए आवश्यक होती है। इसके बाद हम अपने पेज के लिए प्रारंभिक कंटेंट प्राप्त करने के लिए FromTemplate ('templatefile.tpl.php', 'templatefile.tpl.php', 'templatefile2.tpl.php') बनाते हैं, यह मेथड किसी भी टेम्पलेट फ़ाइलों को इसके आर्गुमेंट के रूप में लेती है, और इसके लिए उपयोगी होती है हैडर, कंटेंट और फुटर टेम्पलेट्स।

पेज ऑब्जेक्ट को पेज में रीप्लेस करने के लिए डेटा के रिकॉर्ड को बनाए रखने में मदद करके पेज से जुड़े कंटेंट को मैनेज करता है, और अतिरिक्त टेम्पलेट बिट्स जिन्हें पेज में शामिल करने की आवश्यकता होती है (addTemplateBit ('userbar', 'usertoolsbar.tpl.php '))।

पेज कंटेंट पर विभिन्न रीप्लेस ऑपरेशन करके पेज पर डेटा और कंटेंट जोड़ता है, जिसमें cache किए गए क्वेरी से परिणाम रिट्रीव करना और उन्हें पेज पर जोड़ना शामिल है।

टेम्पलेट फ़ाइल को अपने आप को मार्क करने की आवश्यकता है जहां एक cache किए गए क्वेरी को रिट्रीव करने की आवश्यकता होती है और क्वेरी से डेटा बदल दिया जाता है। जब टेम्पलेट मैनेजर एक टैग को रीप्लेस करने के लिए एक टैग से मुकाबला करता है, तो यह उस पेज का हिस्सा हो जाता है जहां उसे पेज ऑब्जेक्ट पर getBlock('block') को कॉल करके पुन: प्रयास करने की आवश्यकता होती है। कंटेंट के इस हिस्से को फिर क्वेरी में प्रत्येक रिकॉर्ड के लिए कॉपी किया जाता है, और उसके भीतर टैग को क्वेरी के परिणामों के साथ रीप्लेस किया जाता है। हम इस ट्यूटोरियल में बाद में टेम्पलेट कैसा दिखता हैं, इस पर एक नज़र डालेंगे।

टेम्पलेट मैनेजर: पेज

पेज ऑब्जेक्ट टेम्पलेट मैनेजर द्वारा मैनेज किया जाता है, और इसमें पेज से संबंधित सभी details शामिल होते हैं। यह टेम्पलेट मैनेजर को मैनेज करने के लिए स्वतंत्र छोड़ देता है, जबकि इसे बाद की तारीख में इसकी फंक्शनलिटी को एक्सटेंड करना आसान बनाता है।

1
<?php
2
3
/**

4
 * This is our page object

5
 * It is a seperate object to allow some interesting extra functionality to be added

6
 * Some ideas: passwording pages, adding page specific css/js files, etc

7
 */
8
class page {
9
10
	// room to grow later?

11
	private $css = array();
12
	private $js = array();
13
	private $bodyTag = '';
14
	private $bodyTagInsert = '';
15
	
16
	// future functionality?

17
	private $authorised = true;
18
	private $password = '';
19
	
20
	// page elements

21
	private $title = '';
22
	private $tags = array();
23
	private $postParseTags = array();
24
	private $bits = array();
25
	private $content = "";
26
	
27
	/**

28
	 * Constructor...

29
	 */
30
    function __construct() { }
31
    
32
    public function getTitle()
33
    {
34
    	return $this->title;
35
    }
36
    
37
    public function setPassword( $password )
38
    {
39
    	$this->password = $password;
40
    } 
41
    
42
    public function setTitle( $title )
43
    {
44
	    $this->title = $title;
45
    }
46
    
47
    public function setContent( $content )
48
    {
49
	    $this->content = $content;
50
    }
51
    
52
    public function addTag( $key, $data )
53
    {
54
	    $this->tags[$key] = $data;
55
    }
56
    
57
    public function getTags()
58
    {
59
	    return $this->tags;
60
    }
61
    
62
    public function addPPTag( $key, $data )
63
    {
64
	    $this->postParseTags[$key] = $data;
65
    }
66
    
67
    /**

68
     * Get tags to be parsed after the first batch have been parsed

69
     * @return array

70
     */
71
    public function getPPTags()
72
    {
73
	    return $this->postParseTags;
74
    }
75
    
76
    /**

77
     * Add a template bit to the page, doesnt actually add the content just yet

78
     * @param String the tag where the template is added

79
     * @param String the template file name

80
     * @return void

81
     */
82
    public function addTemplateBit( $tag, $bit )
83
    {
84
	    $this->bits[ $tag ] = $bit;
85
    }
86
    
87
    /**

88
     * Get the template bits to be entered into the page

89
     * @return array the array of template tags and template file names

90
     */
91
    public function getBits()
92
    {
93
	    return $this->bits;
94
    }
95
    
96
    /**

97
     * Gets a chunk of page content

98
     * @param String the tag wrapping the block ( <!-- START tag --> block <!-- END tag --> )

99
     * @return String the block of content

100
     */
101
    public function getBlock( $tag )
102
    {
103
		preg_match ('#<!-- START '. $tag . ' -->(.+?)<!-- END '. $tag . ' -->#si', $this->content, $tor);
104
		
105
		$tor = str_replace ('<!-- START '. $tag . ' -->', "", $tor[0]);
106
		$tor = str_replace ('<!-- END '  . $tag . ' -->', "", $tor);
107
		
108
		return $tor;
109
    }
110
    
111
    public function getContent()
112
    {
113
	    return $this->content;
114
    }
115
  
116
}
117
?>

इस क्लास को कैसे एक्सटेंड किया जा सकता है और इसमें सुधार किया जा सकता है?

  • PostParseTags: अधिकांश पेज के पार्स होने के बाद आप टैग बदलना चाहेंगे, शायद डेटाबेस के कंटेंट में ऐसे टैग होते हैं जिन्हें पार्स करने की आवश्यकता होती है।
  • पासवर्ड वाले page: किसी पेज पर पासवर्ड असाइन करें, यह देखने के लिए जांचें कि यूजर के पास कुकी या सेशन में पासवर्ड है या नहीं, ताकि उन्हें पेज देखने की अनुमति मिल सके।
  • रिस्ट्रिक्टेड पेज बदलना (हालांकि हमें पहले हमारे ऑथेंटिकेशन कंपोनेंट्स की आवश्यकता है!)
  • पेज या एप्लिकेशन के
  • आधार पर जावास्क्रिप्ट और CSS फ़ाइलों को डायनामिक रूप से रिफरेन्स जोड़ना।

कोर ऑब्जेक्ट्स को लोड करें

अब हमारे पास कुछ ऑब्जेक्ट्स हैं जो हमारी रजिस्ट्री हमारे लिए स्टोर करने जा रहे हैं, हमें इन ऑब्जेक्ट्स के बारे में रजिस्ट्री को बताने की ज़रूरत है। मैंने PCARegistry ऑब्जेक्ट में एक मेथड बनाया है जिसे loadCoreObjects कहा जाता है यह (जैसा कि यह कहता है) कोर ऑब्जेक्ट्स को लोड करता है। इसका मतलब यह है कि इन ऑब्जेक्ट्स के साथ रजिस्ट्री को लोड करने के लिए बस इससे हमारी index.php फ़ाइल से कॉल कर सकते हैं।

1
public function storeCoreObjects()
2
{
3
	$this->storeObject('database', 'db' );
4
	$this->storeObject('template', 'template' );
5
}

रजिस्ट्री को लोड करने वाले अन्य कोर ऑब्जेक्ट्स को शामिल करने के लिए बाद में इस मेथड को बदला जा सकता है, निश्चित रूप से ऐसे ऑब्जेक्ट्स हो सकते हैं जिनसे हम अपनी रजिस्ट्री को मैनेज करना चाहते हैं, लेकिन केवल फ्रेमवर्क के लिए उपयोग किए जाने वाले एप्लिकेशन के आधार पर। इन ऑब्जेक्ट्स को इस मेथड के बाहर लोड किया जाएगा।

कुछ डाटा

ताकि हम अपने फ्रेमवर्क में जोड़े गए नए फीचर्स का प्रदर्शन कर सकें, हमें डेटाबेस हैंडलर का उपयोग करने के लिए डेटाबेस की आवश्यकता है, और कुछ टेम्पलेट मैनेजमेंट फ़ंक्शन (जहां हम डेटाबेस में rows के साथ कंटेंट के ब्लॉक को रीप्लेस करते हैं)।

डेमोंस्ट्रेशन साइट जो हम ट्यूटोरियल्स की इस सीरीज के अंत तक हमारे फ्रेमवर्क के साथ करेंगे, एक मेम्बर्स डायरेक्टरी वाली वेबसाइट है, इसलिए चलिए मेंबर प्रोफाइल के लिए एक बहुत ही बेसिक डेटाबेस टेबल बनाते हैं, जिसमें एक id, name और email एड्रेस होता है।

जाहिर है, हमें इस टेबल में डाटा की कुछ rows की आवश्यकता है!

एक क्विक टेम्पलेट

कुछ भी प्रदर्शित होने के लिए, हमें एक बेसिक टेम्पलेट की आवश्यकता है, जहां हम अपने मेंबर्स की टेबल से डाटा लिस्ट करेंगे।

1
<html>
2
<head>
3
	<title> Powered by PCA Framework</title>
4
</head>
5
<body>
6
<h1>Our Members</h1>
7
<p>Below is a list of our members:</p>
8
<ul>
9
<!-- START members -->
10
<li>{name} {email}</li>
11
<!-- END members -->
12
</ul>
13
</body>
14
</html>

START मेंबर और END मेंबर HTML कमैंट्स मेंबर ब्लॉक को डेनोट करती हैं (जो पेज पर getBlock() मेथड के माध्यम से प्राप्त की जाती है), यह वह जगह है जहां टेम्पलेट मैनेजर डेटाबेस में रिकॉर्ड्स के माध्यम से पुन: प्रयास करेगा और उन्हें प्रदर्शित करेगा।

उपयोग करते हुए फ्रेमवर्क

अब, हमें यह सब एक साथ लाने की जरूरत है, हमारी index.php फ़ाइल के साथ:

1
// require our registry

2
require_once('PCARegistry/pcaregistry.class.php');
3
$registry = PCARegistry::singleton();
4
5
// store those core objects

6
$registry->storeCoreObjects();
7
8
// create a database connection

9
$registry->getObject('db')->newConnection('localhost', 'root', '', 'pcaframework');
10
11
// set the default skin setting (we will store these in the database later...)

12
$registry->storeSetting('default', 'skin');
13
14
// populate our page object from a template file

15
$registry->getObject('template')->buildFromTemplates('main.tpl.php');
16
17
// cache a query of our members table

18
$cache = $registry->getObject('db')->cacheQuery('SELECT * FROM members');
19
20
// assign this to the members tag

21
$registry->getObject('template')->getPage()->addTag('members', array('SQL', $cache) );
22
23
// set the page title

24
$registry->getObject('template')->getPage()->setTitle('Our members');
25
26
// parse it all, and spit it out

27
$registry->getObject('template')->parseOutput();
28
print $registry->getObject('template')->getPage()->getContent();

अगर हम अब इस पेज को हमारे वेब ब्राउज़र में देखते हैं, तो क्वेरी के परिणाम पेज पर डिस्प्ले होते हैं:

भाग 3 में आ रहा है...

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

  • अधिक डेली वेब डेवलपमेंट टुट्स और आर्टिकल्स के लिए NETTUTS RSS Feed की सदस्यता लें।


Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.