1 | <?php |
||
14 | final class Factory |
||
15 | { |
||
16 | const INTERVAL = 0.1; |
||
17 | const TIMEOUT = 13; |
||
18 | const TERMINATE_TIMEOUT = 1; |
||
19 | const PROCESS_REGISTER = 'wyrihaximus.react.child-process.messenger.child.register'; |
||
20 | |||
21 | public static function parent( |
||
37 | |||
38 | /** |
||
39 | * @param string $process |
||
40 | * @param LoopInterface $loop |
||
41 | * @param array $options |
||
42 | * @param mixed $class |
||
43 | * @return Promise\PromiseInterface<Messenger> |
||
44 | */ |
||
45 | 2 | public static function parentFromClass( |
|
46 | $class, |
||
47 | LoopInterface $loop, |
||
48 | array $options = [] |
||
49 | ) { |
||
50 | 2 | if (!is_subclass_of($class, 'WyriHaximus\React\ChildProcess\Messenger\ChildInterface')) { |
|
51 | 1 | throw new \Exception('Given class doesn\'t implement ChildInterface'); |
|
52 | } |
||
53 | |||
54 | return new Promise\Promise(function ($resolve, $reject) use ($class, $loop, $options) { |
||
55 | 1 | $server = new Server('127.0.0.1:0', $loop); |
|
56 | 1 | $options['address'] = $server->getAddress(); |
|
57 | |||
58 | 1 | $template = '%s'; |
|
59 | 1 | if (isset($options['cmdTemplate'])) { |
|
60 | $template = $options['cmdTemplate']; |
||
61 | unset($options['cmdTemplate']); |
||
62 | } |
||
63 | |||
64 | 1 | $phpBinary = \escapeshellarg(PHP_BINARY . (PHP_SAPI === 'phpdbg' ? ' -qrr --' : '')); |
|
65 | 1 | $childProcessPath = \escapeshellarg(__DIR__ . DIRECTORY_SEPARATOR . 'child-process.php'); |
|
66 | 1 | $argvString = \escapeshellarg(ArgvEncoder::encode($options)); |
|
67 | 1 | $command = $phpBinary . ' ' . $childProcessPath; |
|
68 | 1 | $process = new Process( |
|
69 | 1 | sprintf( |
|
70 | 1 | $template, |
|
71 | 1 | $command . ' ' . $argvString |
|
72 | ) |
||
73 | ); |
||
74 | |||
75 | self::startParent($process, $server, $loop, $options)->then(function (Messenger $messenger) use ($class) { |
||
76 | 1 | return $messenger->rpc(MessengesFactory::rpc(Factory::PROCESS_REGISTER, [ |
|
77 | 1 | 'className' => $class, |
|
78 | ]))->then(function () use ($messenger) { |
||
79 | 1 | return Promise\resolve($messenger); |
|
80 | 1 | }); |
|
81 | 1 | })->done($resolve, $reject); |
|
82 | 1 | }); |
|
83 | } |
||
84 | |||
85 | /** |
||
86 | * @param LoopInterface $loop |
||
87 | * @param array $options |
||
88 | * @param callable $termiteCallable |
||
89 | * @return Promise\PromiseInterface<Messenger> |
||
90 | */ |
||
91 | 1 | public static function child(LoopInterface $loop, array $options = [], callable $termiteCallable = null) |
|
123 | |||
124 | 1 | private static function startParent( |
|
146 | } |
||
147 |
Let’s assume that you have a directory layout like this:
and let’s assume the following content of
Bar.php
:If both files
OtherDir/Foo.php
andSomeDir/Foo.php
are loaded in the same runtime, you will see a PHP error such as the following:PHP Fatal error: Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php
However, as
OtherDir/Foo.php
does not necessarily have to be loaded and the error is only triggered if it is loaded beforeOtherDir/Bar.php
, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias: