Disclaimer : I have more than ten years of PHP development behind me. I started using it when PHP4 was a kid and PHP5 was just a Zend dream. With his help, I did a lot, I loved him, cursed him, and not without shame I watched him grow and develop. I still use it in some inherited projects, but I prefer not to use it anymore. I also want to note that I do not cooperate with the creators of the frameworks or tools mentioned in the article.TL; DR (English too long; did not read. So, in particular, they say when they are too lazy to read the whole article - approx. Lane): if your project is based on the functions of background processes (background services, daemons - approx. .), avoid PHP.
In my opinion, in most cases, PHP haters miss one very important point:
PHP is created to die . This does not mean that a fairly capable (to some extent) programming language will disappear nowhere; it just means that your PHP code cannot run forever. Currently,
13 years after the first official release in 2000, this thought still seems to me quite reasonable.
Model of the dying program
The PHP core follows the simplest workflow: retrieve the entered data, process it, display the output, and die. I think sites like
PHP Sadness , which, in a fun and easy way, help reveal the inadequacy of a language, can best affect its architecture as a whole. But, for sure, there were other attempts.
')
At the very beginning, the completion of the process (eng. Dying) was not a big concern of websites. You read something from a database, applied logic or formatted data, and output the result among a sea of ​​HTML tags. PHP
is still hard to beat (this is a feature of its kernel), despite all the horror introduced by this approach to the world of programming. It’s good that all the problems that could have been solved in this way have already been solved, and the rest are solved by smarter and more modern tools, because such tiny functionality is usually a small part of a large, complex project. Alas,
PHP insists on death after execution . And when you try to do the opposite, bad things happen.
Not just a website anymore.
A good task for PHP is still sending information from the feedback form via email. There is nothing wrong with that (well, if I continue to do these things in ten years, then maybe this will mean that I made very bad decisions earlier). But it is also an example of what has already been solved a million times in a million different ways. Virtually any other web-based language or framework can also do this.
Let's skip this moment. Now we are writing a real and complex application. Simultaneously with the complexity of the growing amount of software code. Suppose you are a fairly capable programmer. You use PHP 5.x and modern programming methods. Everything is extremely abstract in interfaces and classes. You know what to do with existing libraries. Now you may depend on your own ORM models, third-party code, the developed interface, perhaps your client API functions for third-party REST interfaces, etc. Everything is written in PHP.
This is where the nightmare begins: you will inevitably have to run the code in the background. Your application has reached a level of difficulty where waiting for an HTTP request to complete is not enough. The reasons may be the following: you need to process request queues or cache information to speed up HTTP responses; you periodically need to check the required payments and act depending on the result or constantly update the data received from external sources; You may also need to write entire data packets to the database to avoid performance loss; you may need to create and keep open several network connections or to perform the work of the server side of the WebSocket application. These are just examples and can be listed endlessly, depending on what you are developing.
Call online
The worst implementation of the things described above, however, may seem rather familiar: it doesn't matter what PHP or the chosen framework requires - for sure, your hosting does not have SSH access, cron utility or similar tool for $ 5 a month.
What is the simplest solution? Of course, to transfer the execution of tasks from the background to the interactive mode! Run them randomly through every nth page visit (for 1 / nth of page visits - orig.). Then the random visitor will spend his time waiting for the system-wide background task to be completed, and only after its completion the user's personal request will be processed.
It becomes alarming at the thought that many “serious” and “developed” frameworks have such a function built in initially , because it is rather difficult not only to find the code segments that are responsible for this process, but also to understand their interweaving.
So what's the trouble? First, there is no need for special server access parameters; old enough, good and simple-minded FTP. Secondly, everything works at the request of the client, and a small delay is invisible to him. That is why the failure is ensured: everything works fine during testing, also good at the implementation stage, but ugly under real load. You arrogantly think that there will be about as many visits as you need to run tasks at intervals of several minutes.
But pseudo-randomness on a sample of n-hundreds cannot be compared with thousands of requests per minute . Tasks that need to run after a certain time are actually processed several times in the blink of an eye. Funny things start to happen: for example, the same task starts and ends at the same time, errors appear when several processes try to gain access to shared resources with a lock mechanism, etc. Keep in mind that crashing processes also makes it impossible to load the requested page, because, as you know, PHP dies, and everything else follows, including the user's request. In this case, death is not a guarantee of success.
If you are quite adventurous, you can move the background processes to the task list of the cron handler. It's already better: it works while there is enough time, because in this case, we have only one control variable. In the case of recursive tasks (
recursion here is the core of the crond daemon kernel), you always assume that one task will complete before it is called again. In most cases this may turn out to be the case, but, on the other hand, you may have to adjust the scheduler intervals, if the server load increases, or hope for one of them to take a long time, which can be safe but harmful for your speed. applications. On a system scale, this method can be very, very difficult. By this time you can already think about splitting system-wide tasks into separate packages. But someone has to watch over it, someone who will not die.
Summon the demons
A real nightmare begins when the creation of demons or more robust processes seems like the right decision. In confirmation, you can lead the establishment and maintenance of
WebSocket connections or the creation of components of the
manufacturer-consumer .
But PHP will fail you.There are several tasks for which PHP is not suitable. Remember that PHP is dying, no matter how hard you try to prevent it. First, it’s a memory leak issue. PHP never cares about its release if it is no longer used, because everything will be released at the end -
after death . In continuously running processes,
allocated memory (which, in fact, is empty) will accumulate until the
memory_limit threshold is reached. After that, your process will be completed without warning. The problem is not with you, unless you expect the process to live forever. Under real load, replace “slow” processes with “
fairly fast ” ones.
Of course, there were improvements in the “don't waste your memory” plan, but it turned out to be not enough. As soon as the complexity increases or the load increases, everything breaks down. Consider the following code snippet:
class FOO {
public $f;
}
class BAR {
public $f;
}
while(1) {
$a = new FOO();
$b = new BAR();
$a->f = $b;
$b->f = $a;
print "Memory usage: " . number_format(memory_get_usage(true)) . " bytes\n";
unset($a);
unset($b);
}
, , , . , PHP , , , ,
unset().
. , , , . , , , :
ORM. , ,
, , . , . , … ,
? PHP , , , , , PHP .
,
PHP, : ( ) .
(Garbage collection — .) PHP 5.3 . :
«, ?». 2009 , . ?
. , PHP ,
, , . PHP, — .
. PHP ,
:
Fatal error: Exception thrown without a stack frame in Unknown on line 0
? , . 0 PHP-.
, , . ,
PHP. , , : , , . .
, . . PHP , .
.
? , PHP — web- ( «yes, i'm a
hyred keyboard» — . .) — . , ; , , ,
, . , , PHP , . ,
, .
Python, virtualenv,
Flask,
Supervisor Gunicorn. , , — -. , . : ? , Python . , . , . , PHP .
, . , memory_limit . cron, shell- UNIX. PHP web-, — . , , , , , , , . , 30- .
, , , - PHP. , , , PHP 5.4 PHP 5.5 .
, .
HN Reddit.