Hello Friends, Today I am going to share a code for Url rewriting like WordPress do. I have taken help to develop this code from WordPress codex link mentioned below:-
https://core.trac.wordpress.org/browser/tags/5.2/src/wp-includes/class-wp-post-type.php#L532
https://core.trac.wordpress.org/browser/tags/5.2/src/wp-includes/class-wp-matchesmapregex.php
Actually, these days I am developing CMS in which I was required to do Url rewriting code. So to do Url Rewriting like WordPress I have googled and researched on WordPress codex. Now Here is the final code..
config.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 |
<?php include_once 'matches.php'; define("SITE_URL", "http://localhost/urlrewriting"); $rewrite = array(); function updateSlugForRewrite(&$items, $parentId = "0", $parentItem = array()) { // Parent items control $isParentItem = false; foreach ($items as $item) { if ($item['parent'] == $parentId) { $isParentItem = true; break; } } // Prepare items if ($isParentItem) { foreach ($items as &$item) { if ($item['parent'] == $parentId) { $item['slug'] = isset($parentItem['slug']) ? ($parentItem['slug'] . "/" . $item['slug']) : $item['slug']; updateSlugForRewrite($items, $item['id'], $item); } } } } function updateRewriteRules($additional_rules = array(), $location = "bottom") { $rewrite_rules = array(); //adding additional rules in array at the top if (!empty($additional_rules) && $location == 'top') { foreach ($additional_rules as $key => $value) { $rewrite_rules[$key] = $value; } } /* login, logout & register rewrites */ $rewrite_rules['login$'] = 'index.php?login=1'; $rewrite_rules['logout$'] = 'index.php?logout=1'; $rewrite_rules['register$'] = 'index.php?register=1'; /* * categories rewrites * categories will be fetched from database dynamically but for testing I am using fixed data */ $categories = array( array('id' => "1", 'name' => "Java", 'slug' => "java", 'description' => "", 'parent' => "0"), array('id' => "2", 'name' => "JavaFX", 'slug' => "javafx", 'description' => "", 'parent' => "0"), array('id' => "3", 'name' => "Projects", 'slug' => "projects", 'description' => "", 'parent' => "0"), array('id' => "4", 'name' => "Java Projects", 'slug' => "java-projects", 'description' => "", 'parent' => "3"), array('id' => "5", 'name' => "PHP Projects", 'slug' => "php-projects", 'description' => "", 'parent' => "3"), array('id' => "6", 'name' => "Uncategorized", 'slug' => "uncategorized", 'description' => "", 'parent' => "0") ); updateSlugForRewrite($categories, 0); foreach ($categories as $c) { $rewrite_rules['(' . $c['slug'] . ')/page/?([0-9]{1,})/?$'] = 'index.php?category_name=$matches[1]&paged=$matches[2]'; $rewrite_rules['(' . $c['slug'] . ')/?$'] = 'index.php?category_name=$matches[1]'; } /* tag rewrites */ $rewrite_rules['tag/([^/]+)/page/?([0-9]{1,})/?$'] = 'index.php?tag=$matches[1]&paged=$matches[2]'; $rewrite_rules['tag/([^/]+)/?$'] = 'index.php?tag=$matches[1]'; /* blogs paging */ $rewrite_rules['page/?([0-9]{1,})/?$'] = 'index.php?&paged=$matches[1]'; /* search rewrites */ $rewrite_rules['search/(.+)/page/?([0-9]{1,})/?$'] = 'index.php?s=$matches[1]&paged=$matches[2]'; $rewrite_rules['search/(.+)/?$'] = 'index.php?s=$matches[1]'; /* author rewrites */ $rewrite_rules['author/([^/]+)/page/?([0-9]{1,})/?$'] = 'index.php?author_name=$matches[1]&paged=$matches[2]'; $rewrite_rules['author/([^/]+)/?$'] = 'index.php?author_name=$matches[1]'; /* year month day wise posts */ $rewrite_rules['([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/page/?([0-9]{1,})/?$'] = 'index.php?year=$matches[1]&month=$matches[2]&day=$matches[3]&paged=$matches[4]'; $rewrite_rules['([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/?$'] = 'index.php?year=$matches[1]&month=$matches[2]&day=$matches[3]'; $rewrite_rules['([0-9]{4})/([0-9]{1,2})/page/?([0-9]{1,})/?$'] = 'index.php?year=$matches[1]&month=$matches[2]&paged=$matches[3]'; $rewrite_rules['([0-9]{4})/([0-9]{1,2})/?$'] = 'index.php?year=$matches[1]&month=$matches[2]'; $rewrite_rules['([0-9]{4})/page/?([0-9]{1,})/?$'] = 'index.php?year=$matches[1]&paged=$matches[2]'; $rewrite_rules['([0-9]{4})/?$'] = 'index.php?year=$matches[1]'; /**/ $rewrite_rules['(.?.+?)/page/?([0-9]{1,})/?$'] = 'index.php?pagename=$matches[1]&paged=$matches[2]'; $rewrite_rules['(.?.+?)(?:/([0-9]+))?/?$'] = 'index.php?pagename=$matches[1]&page=$matches[2]'; $rewrite_rules['([^/]+)/page/?([0-9]{1,})/?$'] = 'index.php?name=$matches[1]&paged=$matches[2]'; $rewrite_rules['([^/]+)(?:/([0-9]+))?/?$'] = 'index.php?name=$matches[1]&page=$matches[2]'; //adding additional rules in array in the bottom if (!empty($additional_rules) && $location == 'bottom') { foreach ($additional_rules as $key => $value) { $rewrite_rules[$key] = $value; } } /* * Here rewrite rules I am storing in global variable named rewrite but * this can be serialized and stored to database so that it can be accessed wherever needed just like * I have called saveConfig in comment for real project to save rewrite rules in Database */ $GLOBALS['rewrite'] = $rewrite_rules; //saveConfig('rewrite_rules', serialize($rewrite_rules)); } function parse_request($extra_query_vars = '') { $rewrite_index = "index.php"; // Process PATH_INFO, REQUEST_URI, and 404 for permalinks. // Fetch the rewrite rules. /* * Here rewrite rules I am fetching from global variable named rewrite but * this can be unserialize after fetching from database just like * I have called getConfig function to fetch from database and unserialized in real project */ $rewrite = $GLOBALS['rewrite']; //$rewrite = unserialize(getConfig("rewrite_rules")); if (!empty($rewrite)) { // If we match a rewrite rule, this will be cleared. $error = '404'; $pathinfo = isset($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : ''; list( $pathinfo ) = explode('?', $pathinfo); $pathinfo = str_replace('%', '%25', $pathinfo); list( $req_uri ) = explode('?', $_SERVER['REQUEST_URI']); $self = $_SERVER['PHP_SELF']; $home_path = trim(parse_url(SITE_URL, PHP_URL_PATH), '/'); $home_path_regex = sprintf('|^%s|i', preg_quote($home_path, '|')); // Trim path info from the end and the leading home path from the // front. For path info requests, this leaves us with the requesting // filename, if any. For 404 requests, this leaves us with the // requested permalink. $req_uri = str_replace($pathinfo, '', $req_uri); $req_uri = trim($req_uri, '/'); $req_uri = preg_replace($home_path_regex, '', $req_uri); $req_uri = trim($req_uri, '/'); $pathinfo = trim($pathinfo, '/'); $pathinfo = preg_replace($home_path_regex, '', $pathinfo); $pathinfo = trim($pathinfo, '/'); $self = trim($self, '/'); $self = preg_replace($home_path_regex, '', $self); $self = trim($self, '/'); // The requested permalink is in $pathinfo for path info requests and // $req_uri for other requests. if (!empty($pathinfo) && !preg_match('|^.*' . $rewrite_index . '$|', $pathinfo)) { $requested_path = $pathinfo; } else { // If the request uri is the index, blank it out so that we don't try to match it against a rule. if ($req_uri == $rewrite_index) { $req_uri = ''; } $requested_path = $req_uri; } $requested_file = $req_uri; // Look for matches. $request_match = $requested_path; if (empty($request_match)) { // An empty request could only match against ^$ regex if (isset($rewrite['$'])) { $query = $rewrite['$']; $matches = array(''); } } else { foreach ((array) $rewrite as $match => $query) { // If the requested file is the anchor of the match, prepend it to the path info. if (!empty($requested_file) && strpos($match, $requested_file) === 0 && $requested_file != $requested_path) { $request_match = $requested_file . '/' . $requested_path; } if (preg_match("#^$match#", $request_match, $matches) || preg_match("#^$match#", urldecode($request_match), $matches)) { // Got a match. $matched_rule = $match; break; } } } if (isset($matched_rule)) { // Trim the query of everything up to the '?'. $query = preg_replace('!^.+\?!', '', $query); // Substitute the substring matches into the query. $matched_query = addslashes(MatchesMapRegex::apply($query, $matches)); // Parse the query. parse_str($matched_query, $perma_query_vars); // If we're processing a 404 request, clear the error var since we found something. if ('404' == $error) { unset($error, $_GET['error']); } } // If req_uri is empty or if it is a request for ourself, unset error. if (empty($requested_path) || $requested_file == $self) { unset($error, $_GET['error']); if (isset($perma_query_vars)) { unset($perma_query_vars); } } } if (isset($perma_query_vars)) { return $perma_query_vars; } return null; } |
matches.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
<?php /** * Helper class to remove the need to use eval to replace $matches[] in query strings. * Taken From Wordpress */ class MatchesMapRegex { private $_matches; public $output; private $_subject; public $_pattern = '(\$matches\[[1-9]+[0-9]*\])'; // magic number public function __construct($subject, $matches) { $this->_subject = $subject; $this->_matches = $matches; $this->output = $this->_map(); } public static function apply($subject, $matches) { $oSelf = new MatchesMapRegex($subject, $matches); return $oSelf->output; } private function _map() { $callback = array($this, 'callback'); return preg_replace_callback($this->_pattern, $callback, $this->_subject); } public function callback($matches) { $index = intval(substr($matches[0], 9, -1)); return ( isset($this->_matches[$index]) ? urlencode($this->_matches[$index]) : '' ); } } |
index.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
<?php include_once 'config.php'; /* * This function can be called where updatation of rewrite rules required * and can be updated to database i.e while creating new Category or updating permalink, etc */ updateRewriteRules(); $request = parse_request(); ?> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <?php if ($request == null || empty($request)) { //Process home page echo "include home page here"; //include('home.php'); } else if (isset($request['category_name'])) { //Process category page echo "inclue category page here"; //include('category.php'); } else if (isset($request['tag'])) { //Process tag page echo "include tag page here"; //include('tag.php'); } else if (isset($request['s'])) { //Process search page echo "include search page here"; //include('search.php'); } else if (isset($request['author_name'])) { //Process author page echo "include author page here"; //include('author.php'); } else if (isset($request['pagename'])) { //Process page/post page echo "page/post page here and show page or post according to post_type"; //include('post.php'); } else if (isset($request['year']) || isset($request['month']) || isset($request['day'])) { //Process page/post page echo "include posts page here"; //include('post.php'); } else if (isset($request['login'])) { //Process product page echo "include login page here"; //include('login.php'); } else if (isset($request['logout'])) { //Process logout page echo "logout code or logout page here"; //include('logout.php'); } else if (isset($request['register'])) { //Process register page echo "include registration page here"; //include('register.php'); } else { //Process 404 page echo "include Page not found template here"; //include('404.php'); } ?> </body> </html> |
.htaccess
1 2 3 4 5 6 7 8 9 10 |
# BEGIN <IfModule mod_rewrite.c> RewriteEngine On RewriteBase /urlrewriting/ RewriteRule ^index\.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /urlrewriting/index.php [L] </IfModule> # END |
Note: Here RewriteBase and RewriteRule starts with “/urlrewrting/“, because the all code is in urlrewriting directory but you can change it to “/“, if you put your code in www directory in case of LAMP, WAMP or MAMP htdocs in case of XAMPP or public_html in case of hosted on server.
Output
Download
Url Rewriting Like WordPress
Thanks for Visiting
Please do share if you like it
Comments