Before we made a direct call to the Route::run () in the portal file, did you have any problem with that?
the answer is YES!
Sometimes you need to do some extra processing before and after routing, and if you call Route::run () directly in the portal file, then these processes can only be written in the entry file, but the entry file should not do such a thing, so how do we solve the problem?
We introduce the concept of a front-end controller, which is equivalent to a total control, all external requests within its control, then these additional processing can be placed in this controller!!
OK, let's change the entry file first:
02 |
Defined (' App_path ') define (' App_path ', DirName (__file__). '/..'); |
03 |
Defined (' Framework_path ') define (' Framework_path ', App_path. '/library/test '); |
04 |
Defined (' Modules_path ') define (' Modules_path ', App_path. '/userapps/modules '); |
05 |
Defined (' Configs_path ') define (' Configs_path ', App_path. '/userapps/configs '); |
06 |
Include Framework_path. '/function.php '; |
07 |
C (Config::factory (Config::P hp)); Write configuration information |
08 |
Include Framework_path. '/frontcontroller.php '; |
09 |
$frontController = Frontcontroller::getinstance (); |
10 |
$frontController->run (); |
This code actually modifies a few things, and modifies it:
1 |
Include Framework_path. '/frontcontroller.php '; |
2 |
$frontController = Frontcontroller::getinstance (); |
3 |
$frontController->run (); |
This code first include the front-end controller this file, and then instantiate the front-end controller, and then call the front-end controller this class of the Run method.
Why not use $frontcontroller = new Frontcontroller () directly?
If you grasp the code behind the download run will find that this will be an error, why?
Here I need to introduce another concept: a single case pattern.
A singleton pattern is one instance of the entire program running, such as a database connection, even if there are many classes, but it is possible that these classes are connected to a common database, then the database connection is a single example.
Why use a single example?
You can think about, the front-end controller to control the operation of the entire program, then it really should not have a lot of, is not it?
To ensure that it is a singleton, we typically use a static method (getinstance) to instantiate it, and in order to prevent users from directly new and clone an object, we need to set __construct and __clone as private.
03 |
private static $_instance = null; |
04 |
Private Function __construct () {} |
05 |
Private Function __clone () {} |
06 |
public static function getinstance () { |
07 |
if (null = = Self::$_instance) { |
08 |
Self::$_instance = new Test (); |
11 |
return self::$_instance; |
15 |
$test = Test::getinstance (); |
16 |
$test 2 = test::getinstance (); |
If you execute this code, you will see that only one 1 is exported, stating that the instantiation was performed only once.
Said so much, we should all understand it, then directly affixed to the front-end controller code it:
02 |
Class Frontcontroller { |
03 |
private static $_instance = null; |
04 |
Private Function __construct () {} |
05 |
Private Function __clone () {} |
06 |
public static function getinstance () { |
07 |
if (!) ( Self::$_instance instanceof Self)) { |
08 |
Self::$_instance = new Frontcontroller (); |
10 |
return self::$_instance; |
12 |
Public Function run () { |
Of course, the front-end controller I used the instanceof to determine, in fact, can also be directly with the NULL = = Self::$_instance to determine.
This code is very simple, in fact, the transfer of Route::run () to Frontcontroller, the rest of the changes.
You may notice that the contents of the entry file is still too much, why can not transfer the entry file to Frontcontroller, then those who can migrate to Frontcontroller, the first is defined constants, in fact, as long as the user defined App_path can, Other constants can be default by the framework, followed by configuration file writes, and the content framework can be completely handled by itself, so the code for the entry file becomes this:
2 |
Defined (' App_path ') define (' App_path ', DirName (__file__). '/..'); |
3 |
Defined (' Framework_path ') define (' Framework_path ', App_path. '/library/test '); |
4 |
Include Framework_path. '/frontcontroller.php '; |
5 |
$frontController = Frontcontroller::getinstance (); |
6 |
$frontController->run (); |
I left the framework_path here because I wanted to refer to the framework's files, and I didn't actually define Frmaework_path, but instead to include App_path. '/library/test/frontcontroller.php '.
Similarly, Frontcontroller's code has changed:
02 |
Defined (' App_path ') exit (' undefined app_path '); |
03 |
Defined (' Framework_path ') define (' Framework_path ', App_path. '/library/test '); |
04 |
Defined (' Modules_path ') define (' Modules_path ', App_path. '/userapps/modules '); |
05 |
Defined (' Configs_path ') define (' Configs_path ', App_path. '/userapps/configs '); |
06 |
Include Framework_path. '/function.php '; |
07 |
Class Frontcontroller { |
08 |
private static $_instance = null; |
09 |
Private Function __construct () { |
10 |
C (Config::factory (Config::P hp)); Write configuration information |
12 |
Private Function __clone () {} |
13 |
public static function getinstance () { |
14 |
if (!) ( Self::$_instance instanceof Self)) { |
15 |
Self::$_instance = new Frontcontroller (); |
17 |
return self::$_instance; |
19 |
Public Function run () { |
First of all, this file determines whether App_path is defined, because this constant is very important, other paths depend on it, so if the user does not specify, the program needs to stop. The other constants, if not defined, are defined, which is simple.
The configuration file is written to the constructor, because no matter how many times the getinstance calls, the constructor is invoked only 1 times, and the configuration file just needs to be written once.