P
P
Petrusha Ukropov2013-08-31 21:52:53
PHP
Petrusha Ukropov, 2013-08-31 21:52:53

How do you implement cnc?

I want to change the implementation of the cnc in myself, but I don’t know how it will be better. My method is described under the spoiler. I would like to see how you implement this without using frameworks
Header We write this in the index.php file after loading the core and all necessary files

define('MAIN_URI', ($_SERVER['REQUEST_URI'] == '/' ? '/index.php' : $_SERVER['REQUEST_URI']) );

// грузим правила для ЧПУ
include 'incl/furl_patterns.php';

$res =  preg_replace($patterns_keys, $patterns_values, MAIN_URI);
if ($res == MAIN_URI){
  // если не совпало ни одно из правил, выводим ошибку 404 или редиректим...
}	

// разбираем url и преопределяем суперглобальный массив _REQUEST
parse_str($res, $_REQUEST);	

$module = $_REQUEST['module'];

// далее подгружаем нужный модуль -  упрощенный вариант
// например modules/news/index.php
if(file_exists("modules/".$module."/index.php")) {		
  include "modules/".$module."/index.php";			
} else {		
  //опять 404 или редирект	
}

the rules file looks like this:
$patterns_keys = array(
      '#^/(id([0-9]*)/?)?$#i',				//test.ru/id154 можно без слеша после ид, а можно и с ним
      '#^/(user/?)(new/?)?$#i',
      '#^/(user/?)(settings/?)?$#i',
      '#^/(user/?)(settings/?)?((general|avatar|security|social)/?)$#i'
      );

$patterns_values = array(
      'module=account&id=$2',
      'module=account&action=new', 
      'module=account&action=settings', 
      'module=account&action=settings&do=$4'				//модулю можно передавать дополнительные параметры
      );

For example, for test.ru/user/new, the modules/account/new_user.php file will be connected,
for the test.ru/user/settings link - modules/account/settings.php, and depending on what settings are specified, they will be displayed (by default general). True, in this case, the module is connected differently:
switch ($module) {			
  case 'account':				
    switch ($_REQUEST['action']) {						
      case 'new':
        include 'modules/account/new_user.php';
      break;
      case 'settings':
        include 'modules/account/settings.php';
      break;
      default:
        include 'modules/account/profile.php';
    }						
  break;
  ...
}

You can, of course, load the modules/account/index.php file and define actions in it already, and this is inconvenient for each module, so I decided: let everything be in one place (you can put it in a separate file).
htaccess file looks simple
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d 
RewriteRule ^(.*)$ index.php?%{REQUEST_URI} [l]

This method was written a long time ago and works quite well, and I've been using it for so long that I can't think of anything new.
The only plus is that you can specify any rules, for example:
test.ru/
  id15484
  userid15484
  15484
  erth15484yryu
  user/15484
  user/id/15484
  ...

will display the user's profile page with id=15484
or just the user's login, without specifying his id
test.ru/artishok
test.ru/user/artishok

There are several downsides. In addition to the obvious ones, you cannot pass parameters through the $_GET array.
If the search here is simple:
habrahabr.ru/search/?target_type=posts&q=text&orde...
then in this case I need to write additional rules taking into account the type and sorting, it will look something like this:
'#^/(search/?)(([a-zA-Zа-яА-Я0-9%\+]*)/?)?((posts|comments|questions|users)/?)?((time|relevance)/?)?(page([0-9]*)/?)?$#i'

and
'module=search&text=$3&type=$5&sort=$7&page=$9',
test.ru/search/text/posts/time/page2 - it is not clear what is happening, and if the type and sorting are reversed in the link, it will give an error, it will also give an error if one of the parameters is removed ...
ps: sorry if something vaguely described - sticking already

Answer the question

In order to leave comments, you need to log in

7 answer(s)
S
Sergey, 2013-09-01
Protko @Fesor

That's why you constantly fence bicycles ... there are millions of them, and even if you look for something more interesting it will be. Things like routing, logging, etc. in general, it is desirable to reuse, and writing your own bicycles is of little use. Just a discussion.
github.com/chriso/klein.php
noodlehaus.github.io/dispatch/

M
Maxim Dyachenko, 2013-09-01
@Mendel

Why CNC at all?
CNC is a legacy of old engines.
The solution must be initially in the architecture.
those. CNC usually implies that we have a certain map, and then we make it more beautiful ...
We will still make certain queries to the database, so why not look for this information by key in the form of a full path?
Proper optimization will more than cover the overhead of what we are looking for in a longer than numeric index.
Theoretically, here it is possible to optimize, but in practice, I personally have not reached this point.
There was an idea to use not the path itself, but md5 from it, and if this is not fast enough, then cut it to bigint or even to int because md5 is only 16 bytes, and in case of a hash conflict, we will simply get two pages instead of one, and choose before the output you need ...
Although with a reasonable number of pages, conflicts are unlikely even for a regular int.
But in practice, our delays are either too small, or there are simply too many such requests, and if there are a lot of them, then they will be closed by the cache anyway, so is it worth worrying about them?

P
Pavel Volintsev, 2013-09-01
@copist

CNC is a human- readable URL
not
h_ttp://example.com/post/121212
but
h_ttp://example.com/post/latest%20news
So that a person can read and understand what kind of link this is

V
Vladislav Soprun, 2014-01-05
@soprun

Well, why can't you transfer?)
If you do, for example, like this:

$route = preg_replace( '/(\?.*)?$/', '', $_SERVER["REQUEST_URI"] );
$route = preg_replace( '/%2F/' , '/' , urlencode( trim( $route , '/' ) ) );
define( 'MAIN_URI' , $route );

That can be implemented like this:
/search/search_request?type=posts&sort=time

M
mgkirs, 2013-08-31
@mgkirs

I have it implemented using apache
Here is one of the examples:

RewriteRule ^(.[^/]*)/([0-9]*)$ /index.php?a=$1&n=$2 [QSA]

I
Ivan Maslov, 2013-09-01
@student_ivan

At one time, in one of his trash projects, I made a compiled router that compiled static routes for apache + mod rewrite and nginx via the command line. It looked something like this , and the routes are something like this

S
Sergey Cherepanov, 2013-09-01
@fear86

I like the option to store all links in the database, there is a CNC and there is a system url to which it leads. Thus, links can be created programmatically, by hand, you can make support for 301 redirects for moved / renamed pages, and so on. and do not bind the NC logic to the server.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question