├── .State ├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── Documentation ├── En │ └── Index.xyl └── Fr │ └── Index.xyl ├── Exception.php ├── README.md ├── Test └── Unit │ └── Zombie.php ├── Zombie.php ├── bors.toml └── composer.json /.State: -------------------------------------------------------------------------------- 1 | finalized 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor/ 2 | /composer.lock 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | 3 | branches: 4 | only: 5 | - staging 6 | - trying 7 | - master 8 | 9 | matrix: 10 | include: 11 | - php: 5.5 12 | - php: 5.6 13 | - php: 7.0 14 | - php: 7.1 15 | env: 16 | - ENABLE_XDEBUG=true 17 | - php: 7.1 18 | env: 19 | - ENABLE_DEVTOOLS=true 20 | - php: nightly 21 | allow_failures: 22 | - php: nightly 23 | fast_finish: true 24 | 25 | os: 26 | - linux 27 | 28 | notifications: 29 | irc: "chat.freenode.net#hoaproject" 30 | 31 | sudo: false 32 | 33 | env: 34 | global: 35 | - secure: "AAAAB3NzaC1yc2EAAAADAQABAAAAgQC8pyH+AhD98yAuYJPLqhJbutiqsOmlXmsZ8c3i0/ck4a709Dgn8FjlzpUdbauLAkiXyoD7byp8UxAwkZU24KLDEmFbhJ1oR7JNvbWiFnKgHthfFKa/TyfxLT7Z/1/K9H7pmdziiwwDBJNyQKgD0uWSToZv8rnyldYndBB1FtcRvw==" 36 | 37 | cache: 38 | directories: 39 | - vendor/ 40 | 41 | before_script: 42 | - export PATH="$PATH:$HOME/.composer/vendor/bin" 43 | - if [[ ! $ENABLE_XDEBUG ]]; then 44 | phpenv config-rm xdebug.ini || echo "ext-xdebug is not available, cannot remove it."; 45 | fi 46 | 47 | script: 48 | - composer install 49 | - vendor/bin/hoa test:run 50 | - if [[ $ENABLE_DEVTOOLS ]]; then 51 | composer global require friendsofphp/php-cs-fixer; 52 | vendor/bin/hoa devtools:cs --diff --dry-run .; 53 | fi 54 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # 3.17.01.16 2 | 3 | * Quality: Happy new year! (Alexis von Glasow, 2017-01-09T21:36:59+01:00) 4 | * Documentation: New `README.md` file. (Ivan Enderlin, 2016-10-21T17:18:29+02:00) 5 | * Documentation: Update `support` properties. (Ivan Enderlin, 2016-10-11T11:44:15+02:00) 6 | 7 | # 3.16.01.11 8 | 9 | * Quality: Drop PHP5.4. (Ivan Enderlin, 2016-01-11T09:15:27+01:00) 10 | * Quality: Run devtools:cs. (Ivan Enderlin, 2016-01-09T09:12:59+01:00) 11 | * Core: Remove `Hoa\Core`. (Ivan Enderlin, 2016-01-09T08:35:32+01:00) 12 | * Consistency: Use `Hoa\Consistency`. (Ivan Enderlin, 2015-12-08T22:22:44+01:00) 13 | * Exception: Use `Hoa\Exception`. (Ivan Enderlin, 2015-11-20T20:30:20+01:00) 14 | 15 | # 2.15.08.17 16 | 17 | * Add a `.gitignore` file. (Stéphane HULARD, 2015-08-03T11:52:31+02:00) 18 | 19 | # 2.15.05.29 20 | 21 | * Move to PSR-1 and PSR-2. (Ivan Enderlin, 2015-05-22T08:58:37+02:00) 22 | 23 | # 2.15.02.16 24 | 25 | * Add the CHANGELOG.md file. (Ivan Enderlin, 2015-02-16T14:47:03+01:00) 26 | * Fix documentation links. (Ivan Enderlin, 2015-01-23T19:29:32+01:00) 27 | * Happy new year! (Ivan Enderlin, 2015-01-05T15:00:45+01:00) 28 | 29 | # 2.14.12.10 30 | 31 | * Move to PSR-4. (Ivan Enderlin, 2014-12-09T18:57:09+01:00) 32 | * Require `hoa/test`. (Alexis von Glasow, 2014-11-26T13:30:04+01:00) 33 | 34 | # 2.14.11.09 35 | 36 | * Fix API documentation. (Ivan Enderlin, 2014-10-06T15:56:11+02:00) 37 | * Add tests. (Ivan Enderlin, 2014-10-06T15:37:28+02:00) 38 | * `Zombie::fork` returns true on success. (Ivan Enderlin, 2014-10-06T15:37:01+02:00) 39 | * Remove `from`/`import` and update to PHP5.4. (Ivan Enderlin, 2014-10-06T11:38:00+02:00) 40 | 41 | # 2.14.09.23 42 | 43 | * Add `branch-alias` (Stéphane PY, 2014-09-23T12:00:52+02:00) 44 | 45 | # 2.14.09.17 46 | 47 | * Drop PHP5.3. (Ivan Enderlin, 2014-09-17T17:58:46+02:00) 48 | * Add the installation section. (Ivan Enderlin, 2014-09-17T17:58:33+02:00) 49 | 50 | (first snapshot) 51 | -------------------------------------------------------------------------------- /Documentation/En/Index.xyl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |

A zombie is a processus which is neither active, nor finished: between 7 | life and death. Hoa\Zombie 8 | allows to turn a PHP execution into a zombie!

9 | 10 |

Table of contents

11 | 12 | 13 | 14 |

Introduction

15 | 16 |

Putting a processus between life and death should be, in general, avoided, 17 | because it is often synonym of a dysfunction. However, it 18 | might happen to be shrewd, notably in the case of a demon 19 | (see the Hoa\Worker library). 20 | It is important to notice that a zombie is also mute: it can no longer write 21 | on its standard output because it is theorically no longer attached to a 22 | parent processus.

23 |

For now, Hoa\Zombie is able to create zombies only if it runs 24 | behind PHP FPM. Remind us how PHP 25 | works: a FastCGI server (such as PHP FastCGI 26 | or PHP FPM) will start a PHP processus when a request is 27 | received and will stop it when a response is sent. Somehow, 28 | the PHP processus is synchronized on the FastCGI protocol. 29 | Fortunately, when we use PHP FPM, we are able to 30 | desynchronize this protocol, and thus, to create zombies, 31 | while delegating the 32 | processus management to PHP FPM!

33 | 34 |

Manipulate zombies

35 | 36 |

Creating a zombie is very simple: we only need to call the 37 | Hoa\Zombie\Zombie::fork method.

38 |

It is common knowledge that killing a zombie is a very 39 | attractive activity, even more if we have the choice of 40 | weapons! That's why Hoa\Zombie\Zombie provides 41 | the following methods:

42 |
    43 |
  • Hoa\Zombie\Zombie::decapitate, to 44 | decapitate a zombie,
  • 45 |
  • Hoa\Zombie\Zombie::bludgeon, to cosh a 46 | zombie,
  • 47 |
  • Hoa\Zombie\Zombie::burn, to burn a 48 | zombie,
  • 49 |
  • Hoa\Zombie\Zombie::explode, to explode a 50 | zombie,
  • 51 |
  • Hoa\Zombie\Zombie::cutOff, to slice 52 | a zombie.
  • 53 |
54 |

All these methods have been proven. Thus:

55 |
// I'm alive!
 56 | Hoa\Zombie\Zombie::fork();
 57 | // I'm a zombie!
 58 | Hoa\Zombie\Zombie::decapitate();
 59 | // I'm dead…
60 |

Hoa\Zombie\Zombie is also able to get the 61 | identifier of the processus, which can be useful sometimes, 62 | through the Hoa\Zombie\Zombie::getPid method. Finally, the 63 | Hoa\Zombie\Zombie::test method allows to know whether we can 64 | create a zombie or not.

65 | 66 |

Example

67 | 68 |

To create a zombie, we said we need to use PHP FPM. Next, there is 69 | different ways to execute our PHP program, which will be our future zombie: 70 | either through HTTP (which will automatically create a FastCGI request to 71 | PHP FPM) or directly by sending a FastCGI request to PHP FPM. 72 | We will choose this latter.

73 |

We start with the Zombie.php file:

74 |
echo 'I guess I am sick…', "\n";
 75 | Hoa\Zombie\Zombie::fork();
 76 | 
 77 | // Do whatever you want here, e.g.:
 78 | sleep(10);
 79 | file_put_contents(
 80 |     __DIR__ . DS . 'AMessage',
 81 |     'Hello from after-life… or somewhere about!'
 82 | );
 83 | 
84 |

Next, we continue with the Run.php file which will execute 85 | Zombie.php thanks to 86 | Hoa\Fastcgi:

87 |
$fastcgi = new Hoa\Fastcgi\Responder(
 88 |     new Hoa\Socket\Client('tcp://127.0.0.1:9000')
 89 | );
 90 | 
 91 | // Start Zombie.php and print the response before it becomes undead.
 92 | echo $fastcgi->send([
 93 |     'GATEWAY_INTERFACE' => 'FastCGI/1.0',
 94 |     'REQUEST_METHOD'    => 'GET',
 95 |     'SCRIPT_FILENAME'   => __DIR__ . DS . 'Zombie.php'
 96 | ]);
97 |

And finally, we test:

98 |
$ php-fpm -d listen=127.0.0.1:9000
 99 | $ php Run.php
100 | I guess I am sick…
101 |

After 10 seconds, we will see the AMessage file appears, 102 | containing Hello from after-life… or somewhere about!.

103 |

We can create a zombie at any moment and kill it as we 104 | want. If the end of the program is reached, the zombie will kill 105 | itself. We will anticipate that a demon is just a zombie that 106 | starts a server.

107 | 108 |

Conclusion

109 | 110 |

Hoa\Zombie allows to turn a processus into a 111 | zombie only when it is used with PHP FPM. We invite you to 112 | take a look at Hoa\Worker for 113 | a complete example.

114 | 115 |
116 |
117 | -------------------------------------------------------------------------------- /Documentation/Fr/Index.xyl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |

Un zombie est un processus qui n'est ni actif, ni terminé : il est entre la 7 | vie et la mort. Hoa\Zombie 8 | permet de transformer une exécution PHP en zombie !

9 | 10 |

Table des matières

11 | 12 | 13 | 14 |

Introduction

15 | 16 |

Placer un processus entre la vie et la mort est en général à éviter car 17 | cela est souvent synonyme de dysfonctionnement. Toutefois, il 18 | peut arriver que ce soit astucieux de le faire, notamment dans le cas de 19 | démons (voir 20 | Hoa\Worker). Il est à noter 21 | qu'un zombie est également muet : il ne peut plus écrire sur 22 | la sortie standard puisqu'il n'est théoriquement plus attaché à aucun 23 | processus parent.

24 |

Actuellement, Hoa\Zombie ne permet de créer des zombies que 25 | s'il est utilisé derrière 26 | PHP FPM. Rappelons-nous du 27 | fonctionnement de PHP : un serveur FastCGI 28 | (comme PHP FastCGI ou PHP FPM) va démarrer un processus PHP quand une 29 | requête arrive et la terminer quand la 30 | réponse est envoyée. D'une certaine manière, le processus PHP 31 | est synchronisé sur le protocole FastCGI. Heureusement, quand 32 | nous utilisons PHP FPM, nous pouvons désynchroniser ce 33 | protocole, et ainsi créer des zombies tout en délégant 34 | la gestion des processus à 35 | PHP FPM !

36 | 37 |

Manipuler des 38 | zombies

39 | 40 |

Créer un zombie est très simple : il suffit d'appeler la 41 | méthode Hoa\Zombie\Zombie::fork().

42 |

Il est de notoriété publique que tuer un zombie est une activité 43 | amusante, d'autant plus si nous avons le choix des 44 | armes ! C'est pourquoi Hoa\Zombie\Zombie propose 45 | les méthodes suivantes :

46 |
    47 |
  • Hoa\Zombie\Zombie::decapitate, pour 48 | décapiter un zombie ;
  • 49 |
  • Hoa\Zombie\Zombie::bludgeon, pour 50 | matraquer un zombie ;
  • 51 |
  • Hoa\Zombie\Zombie::burn, pour brûler un 52 | zombie ;
  • 53 |
  • Hoa\Zombie\Zombie::explode, pour faire 54 | exploser un zombie ;
  • 55 |
  • Hoa\Zombie\Zombie::cutOff, pour découper 56 | un zombie en rondelles.
  • 57 |
58 |

Toutes ces méthodes ont fait leurs preuves. Ainsi :

59 |
// I'm alive!
 60 | Hoa\Zombie\Zombie::fork();
 61 | // I'm a zombie!
 62 | Hoa\Zombie\Zombie::decapitate();
 63 | // I'm dead…
64 |

Hoa\Zombie\Zombie propose également d'obtenir 65 | l'identifiant du processus, ce qui peut parfois être utile, à 66 | travers la méthode Hoa\Zombie\Zombie::getPid. Enfin, il existe la 67 | méthode Hoa\Zombie\Zombie::test qui permet de savoir si nous 68 | pouvons créer un zombie ou pas.

69 | 70 |

Exemple

71 | 72 |

Pour créer un zombie, nous avons dit qu'il fallait utiliser PHP FPM. 73 | Ensuite, nous avons plusieurs possibilités pour exécuter notre programme PHP 74 | qui sera notre futur zombie : soit à travers HTTP (qui fera automatiquement 75 | une requête FastCGI vers PHP FPM) ou alors directement en 76 | émettant une requête FastCGI vers PHP FPM. C'est ce dernier 77 | choix que nous allons retenir.

78 |

Nous commençons avec le fichier Zombie.php :

79 |
echo 'I guess I am sick…', "\n";
 80 | Hoa\Zombie\Zombie::fork();
 81 | 
 82 | // Do whatever you want here, e.g.:
 83 | sleep(10);
 84 | file_put_contents(
 85 |     __DIR__ . DS . 'AMessage',
 86 |     'Hello from after-life… or somewhere about!'
 87 | );
 88 | 
89 |

Ensuite, nous continuons avec le fichier Run.php qui va 90 | exécuter Zombie.php grâce à 91 | Hoa\Fastcgi :

92 |
$fastcgi = new Hoa\Fastcgi\Responder(
 93 |     new Hoa\Socket\Client('tcp://127.0.0.1:9000')
 94 | );
 95 | 
 96 | // Start Zombie.php and print the response before it becomes undead.
 97 | echo $fastcgi->send([
 98 |     'GATEWAY_INTERFACE' => 'FastCGI/1.0',
 99 |     'REQUEST_METHOD'    => 'GET',
100 |     'SCRIPT_FILENAME'   => __DIR__ . DS . 'Zombie.php'
101 | ]);
102 |

Et enfin, nous testons :

103 |
$ php-fpm -d listen=127.0.0.1:9000
104 | $ php Run.php
105 | I guess I am sick…
106 |

Et après 10 secondes, nous verrons le fichier AMessage 107 | apparaître et contenant Hello from after-life… or somewhere 108 | about!.

109 |

Nous pouvons créer un zombie à tout moment et le tuer 110 | comme nous le voulons. Si la fin du programme est atteinte, le zombie se tuera 111 | de lui-même. Nous anticiperons qu'un démon n'est finalement 112 | rien d'autre qu'un zombie qui démarre un serveur.

113 | 114 |

Conclusion

115 | 116 |

Hoa\Zombie permet de transformer un processus en 117 | zombie uniquement lorsqu'il est utilisé avec PHP FPM. Nous 118 | vous invitons à regarder 119 | Hoa\Worker pour un exemple 120 | d'utilisation plus complet.

121 | 122 |
123 |
124 | -------------------------------------------------------------------------------- /Exception.php: -------------------------------------------------------------------------------- 1 | 2 | Hoa 3 |

4 | 5 | --- 6 | 7 |

8 | Build status 9 | Code coverage 10 | Packagist 11 | License 12 |

13 |

14 | Hoa is a modular, extensible and 15 | structured set of PHP libraries.
16 | Moreover, Hoa aims at being a bridge between industrial and research worlds. 17 |

18 | 19 | # Hoa\Zombie 20 | 21 | [![Help on IRC](https://img.shields.io/badge/help-%23hoaproject-ff0066.svg)](https://webchat.freenode.net/?channels=#hoaproject) 22 | [![Help on Gitter](https://img.shields.io/badge/help-gitter-ff0066.svg)](https://gitter.im/hoaproject/central) 23 | [![Documentation](https://img.shields.io/badge/documentation-hack_book-ff0066.svg)](https://central.hoa-project.net/Documentation/Library/Zombie) 24 | [![Board](https://img.shields.io/badge/organisation-board-ff0066.svg)](https://waffle.io/hoaproject/zombie) 25 | 26 | This library allows to transform a process into a zombie: not alive, nor dead! 27 | 28 | This is possible only if the program is running behind 29 | [PHP-FPM](http://php.net/install.fpm) (which manages processes for us). 30 | 31 | [Learn more](https://central.hoa-project.net/Documentation/Library/Zombie). 32 | 33 | ## Installation 34 | 35 | With [Composer](https://getcomposer.org/), to include this library into 36 | your dependencies, you need to 37 | require [`hoa/zombie`](https://packagist.org/packages/hoa/zombie): 38 | 39 | ```sh 40 | $ composer require hoa/zombie '~3.0' 41 | ``` 42 | 43 | For more installation procedures, please read [the Source 44 | page](https://hoa-project.net/Source.html). 45 | 46 | ## Testing 47 | 48 | Before running the test suites, the development dependencies must be installed: 49 | 50 | ```sh 51 | $ composer install 52 | ``` 53 | 54 | Then, to run all the test suites: 55 | 56 | ```sh 57 | $ vendor/bin/hoa test:run 58 | ``` 59 | 60 | For more information, please read the [contributor 61 | guide](https://hoa-project.net/Literature/Contributor/Guide.html). 62 | 63 | ## Quick usage 64 | 65 | To create a zombie, all we have to do is to call the `Hoa\Zombie\Zombie::fork` 66 | method. To kill a zombie, we have the choice between different weapons: 67 | 68 | * `Hoa\Zombie\Zombie::decapitate`, *ziip*; 69 | * `Hoa\Zombie\Zombie::bludgeon`, *tap tap*; 70 | * `Hoa\Zombie\Zombie::burn`, if you are cold; 71 | * `Hoa\Zombie\Zombie::explode`, *boom*; 72 | * `Hoa\Zombie\Zombie::cutOff`, sausage? 73 | 74 | All these methods have been proven. Thus: 75 | 76 | ```php 77 | // I'm alive! 78 | Hoa\Zombie\Zombie::fork(); 79 | // I'm a zombie! 80 | Hoa\Zombie\Zombie::decapitate(); 81 | // I'm dead… 82 | ``` 83 | 84 | But we have to run the script behind FastCGI, that is why we will use the 85 | [`Hoa\Fastcgi` library](https://central.hoa-project.net/Resource/Library/Fastcgi) in the 86 | following example. 87 | 88 | In the `Zombie.php` file, we write the following instructions: 89 | 90 | ```php 91 | echo 'I guess I am sick…', "\n"; 92 | Hoa\Zombie\Zombie::fork(); 93 | 94 | // Do whatever you want here, e.g.: 95 | sleep(10); 96 | file_put_contents( 97 | __DIR__ . DS . 'AMessage', 98 | 'Hello from after-life… or somewhere about!' 99 | ); 100 | Hoa\Zombie\Zombie::decapitate(); 101 | ``` 102 | 103 | Then, in the `Run.php` file, we write: 104 | 105 | ```php 106 | $fastcgi = new Hoa\Fastcgi\Responder( 107 | new Hoa\Socket\Client('tcp://127.0.0.1:9000') 108 | ); 109 | echo $fastcgi->send([ 110 | 'GATEWAY_INTERFACE' => 'FastCGI/1.0', 111 | 'REQUEST_METHOD' => 'GET', 112 | 'SCRIPT_FILENAME' => __DIR__ . DS . 'Zombie.php' 113 | ]); 114 | ``` 115 | 116 | And finally, we can test: 117 | 118 | ```sh 119 | $ php-fpm -d listen=127.0.0.1:9000 120 | $ php Run.php 121 | I guess I am sick… 122 | ``` 123 | 124 | And 10 seconds after, we will see the `AMessage` file appear with the content: 125 | *Hello from after-life… or somewhere about!*. 126 | 127 | ## Documentation 128 | 129 | The 130 | [hack book of `Hoa\Zombie`](https://central.hoa-project.net/Documentation/Library/Zombie) 131 | contains detailed information about how to use this library and how it works. 132 | 133 | To generate the documentation locally, execute the following commands: 134 | 135 | ```sh 136 | $ composer require --dev hoa/devtools 137 | $ vendor/bin/hoa devtools:documentation --open 138 | ``` 139 | 140 | More documentation can be found on the project's website: 141 | [hoa-project.net](https://hoa-project.net/). 142 | 143 | ## Getting help 144 | 145 | There are mainly two ways to get help: 146 | 147 | * On the [`#hoaproject`](https://webchat.freenode.net/?channels=#hoaproject) 148 | IRC channel, 149 | * On the forum at [users.hoa-project.net](https://users.hoa-project.net). 150 | 151 | ## Contribution 152 | 153 | Do you want to contribute? Thanks! A detailed [contributor 154 | guide](https://hoa-project.net/Literature/Contributor/Guide.html) explains 155 | everything you need to know. 156 | 157 | ## License 158 | 159 | Hoa is under the New BSD License (BSD-3-Clause). Please, see 160 | [`LICENSE`](https://hoa-project.net/LICENSE) for details. 161 | -------------------------------------------------------------------------------- /Test/Unit/Zombie.php: -------------------------------------------------------------------------------- 1 | given( 56 | $this->function->function_exists = function ($name) { 57 | if ('fastcgi_finish_request' === $name) { 58 | return false; 59 | } 60 | 61 | return true; 62 | } 63 | ) 64 | ->exception(function () { 65 | LUT::fork(); 66 | }) 67 | ->isInstanceOf('Hoa\Zombie\Exception'); 68 | } 69 | 70 | public function case_with_fpm() 71 | { 72 | $this 73 | ->given( 74 | $this->function->function_exists = function ($name) { 75 | return true; 76 | }, 77 | $this->function->fastcgi_finish_request = true 78 | ) 79 | ->when($result = LUT::fork()) 80 | ->boolean($result) 81 | ->isTrue(); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /Zombie.php: -------------------------------------------------------------------------------- 1 | =5.5.0", 27 | "hoa/consistency": "~1.0", 28 | "hoa/exception" : "~1.0" 29 | }, 30 | "require-dev": { 31 | "hoa/test": "~2.0" 32 | }, 33 | "autoload": { 34 | "psr-4": { 35 | "Hoa\\Zombie\\": "." 36 | } 37 | }, 38 | "extra": { 39 | "branch-alias": { 40 | "dev-master": "3.x-dev" 41 | } 42 | } 43 | } 44 | --------------------------------------------------------------------------------