
PHP: Advanced Fluid Interface
I am sure that many of you who read this text are familiar with the concept of fluid interface. And even if you have not heard about him, I’m sure that you have used it more than once. It is really convenient. So what is it all about?
Here is a small example. We can line up, sequentially, perform actions. The same principle underlies the popular jQuery library. What can I say, all modern frameworks abound with similar designs. But what if you use a similar mechanism to build the entire site?
Then I will not make a big digression, go back. To continue, you need to answer the question why? Well, really, why come up with a bike if there are standard models and proven architectures. I'm talking about the MVC model family. Why is MVC bad?
No, he's not bad. But it has its limitations, like everything in this world. This is a great model for building a site. It is the site. But when it comes to building, on its basis, web applications, alas, its limitations are felt. Let's take a closer look at the situation. Take for example a standard site. It doesn’t matter what topic it will be. We look at the pictures.

Here is the layout diagram of the site. We see a news block, tabs (maybe just buttons), an advertising block and a content block. The content contains a table - an index. How to organize a request to this page? This is a classic, common mechanism. One parameter passes the section, another task. Here is another picture. We look Here already the content of the site contains the editing form. Here is a request to this page of the site. Everything is good and clear. Programming is also easy. For example, so

The Site class returns the controller for the desired section. The MyController section controller takes the necessary actions.
Tell me what to do if you are developing a web application, not a website. The web application interface is much more complicated than the above. Tabs, tables, menus, etc. After all, we must have access to each element of the page, update it, redraw it? What if most of the content needs to be updated by AJAX? We look at the picture.

Now our site has a tree, a bunch of tabs, a form, several toolbars, etc. The tables that are inserted in the tabs are sorted in all directions. And the Avatar field in the form can load and delete a picture without reloading the entire page. So how do you organize queries for all of these elements?
Let's try to go the same way. Let us have the same MVC scheme. Obviously, we will need another parameter that will indicate what specific page to change. Let it be called part. Then the queries may look something like this: How will the toolbar in the Tree section turn to? Or to the toolbar in the Contents tab? Enter another parameter? Dead end
And again the picture.

This is a structural diagram of the Users section of the Electronic University. I am sure that you do not even need a higher education to understand its content. Understand that Students are made up of Groups, and groups are already made up of Student elements. Before us is nesting. And now we recall the Fluid Interface and make the following assumption. And why not the methods of the root object to return other objects, and not just your object? Actually, as soon as we implement this, we will easily expand this scheme into a chain. Go!
Now, to show the student, you need to complete the following chain of commands. Let's repeat the question, the question that led us to a dead end in the previous paragraph. And how to turn to the toolbar in the Tree section? We answer. This is how the Student class itself can have within itself the same calls to chains to another object. Simply put, a student class consists of a form, the Form () method, Tree () - a tree, and what else is needed. It's like a Lego constructor. What we see, we sculpt, compose, construct!
Above, the proposed scheme of the Advanced Fluid Interface for building web applications is very easily transformed into a query chain, the chain - to the site address, to the user's position on the site.
In case you write the following in .htaccess, then all requests to the site will be redirected to index.php. In it, you will have to turn links like turn into a chain of commands. You can do this like this.
PS: Dear colleagues. The given code examples do not contain checks and therefore cannot be used in working projects as is. They are written solely for clarity.
To prepare this material, I used gomockingbird.com/mockingbird in which I drew the site diagrams.
width = $with;
return $this;
}
public function SetHeight($value) {
$this->height = $value;
return $this;
}
}
$images = new Images();
$images->SetWidth(100)->SetHeight(100);
?>
Here is a small example. We can line up, sequentially, perform actions. The same principle underlies the popular jQuery library. What can I say, all modern frameworks abound with similar designs. But what if you use a similar mechanism to build the entire site?
entrance
Then I will not make a big digression, go back. To continue, you need to answer the question why? Well, really, why come up with a bike if there are standard models and proven architectures. I'm talking about the MVC model family. Why is MVC bad?
No, he's not bad. But it has its limitations, like everything in this world. This is a great model for building a site. It is the site. But when it comes to building, on its basis, web applications, alas, its limitations are felt. Let's take a closer look at the situation. Take for example a standard site. It doesn’t matter what topic it will be. We look at the pictures.

Here is the layout diagram of the site. We see a news block, tabs (maybe just buttons), an advertising block and a content block. The content contains a table - an index. How to organize a request to this page? This is a classic, common mechanism. One parameter passes the section, another task. Here is another picture. We look Here already the content of the site contains the editing form. Here is a request to this page of the site. Everything is good and clear. Programming is also easy. For example, so
mysite.ru/section=2&task=index

mysite.ru/section=2&task=edit
Section($section)->$task();
?>
The Site class returns the controller for the desired section. The MyController section controller takes the necessary actions.
Tell me what to do if you are developing a web application, not a website. The web application interface is much more complicated than the above. Tabs, tables, menus, etc. After all, we must have access to each element of the page, update it, redraw it? What if most of the content needs to be updated by AJAX? We look at the picture.

Now our site has a tree, a bunch of tabs, a form, several toolbars, etc. The tables that are inserted in the tabs are sorted in all directions. And the Avatar field in the form can load and delete a picture without reloading the entire page. So how do you organize queries for all of these elements?
Let's try to go the same way. Let us have the same MVC scheme. Obviously, we will need another parameter that will indicate what specific page to change. Let it be called part. Then the queries may look something like this: How will the toolbar in the Tree section turn to? Or to the toolbar in the Contents tab? Enter another parameter? Dead end
mysite.ru?section=2&part=tree&task=expand
mysite.ru?section=2&part=form&task=delete
Exit
And again the picture.

This is a structural diagram of the Users section of the Electronic University. I am sure that you do not even need a higher education to understand its content. Understand that Students are made up of Groups, and groups are already made up of Student elements. Before us is nesting. And now we recall the Fluid Interface and make the following assumption. And why not the methods of the root object to return other objects, and not just your object? Actually, as soon as we implement this, we will easily expand this scheme into a chain. Go!
Now, to show the student, you need to complete the following chain of commands. Let's repeat the question, the question that led us to a dead end in the previous paragraph. And how to turn to the toolbar in the Tree section? We answer. This is how the Student class itself can have within itself the same calls to chains to another object. Simply put, a student class consists of a form, the Form () method, Tree () - a tree, and what else is needed. It's like a Lego constructor. What we see, we sculpt, compose, construct!
Members::Students()->Group(123)->Student(327)->Show();
Members::Students()->Group(123)->Student(327)->Tree()->Toolbar()->Add();
Dessert
Above, the proposed scheme of the Advanced Fluid Interface for building web applications is very easily transformed into a query chain, the chain - to the site address, to the user's position on the site.
In case you write the following in .htaccess, then all requests to the site will be redirected to index.php. In it, you will have to turn links like turn into a chain of commands. You can do this like this.
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [QSA,L]
mysite.ru/control/members/students/group=123/student=321/show
Application::Control()->Members()->Students()->Group(123)->Student(431)->Show();
request = $this->Request()) {
$this->errors[] = ERROR_PARAM_GET;
}
}
public function Init() {
if (!is_object(self::$instance)) {
self::$instance = new self();
}
return self::$instance;
}
public function Request() {
if (!$uri = explode("/", $_SERVER["REQUEST_URI"])) {
return false;
} else {
foreach ($uri as $item) {
if (strpos($item, "=")) {
$key = substr($item, 0, strpos($item, "="));
$value = substr($item, strpos($item, "=")+1);
} else {
$key = $item;
$value = null;
}
if (!empty($item)) {
$result[] = array(
"key" => $key,
"value" => isset($value) ? $value : null
);
}
}
}
return $result;
}
function Run() {
if (isset($this->errors)) {
foreach ($this->errors as $error) {
echo $error;
}
} else {
$root = $this;
/**
* Запускаю цепочку команд
* если команда не верная, возвращаю преветствие
*/
foreach ($this->request as $element) {
if (is_object($root) && method_exists($root, $element["key"])) {
$root = $root->{$element["key"]}(@$element["value"]);
} else {
return $this->Welcome()->Show();
}
}
}
}
}
Application::Init()->Run();
?>
PS: Dear colleagues. The given code examples do not contain checks and therefore cannot be used in working projects as is. They are written solely for clarity.
References
To prepare this material, I used gomockingbird.com/mockingbird in which I drew the site diagrams.