11package com.github.xepozz.php_dump.services
22
3- import com.github.xepozz.php_dump.SeparateStringBufferProcessAdapter
43import com.github.xepozz.php_dump.command.PathMapper
54import com.github.xepozz.php_dump.command.PhpCommandExecutor
65import com.github.xepozz.php_dump.configuration.PhpDumpSettingsService
7- import com.intellij.execution.configurations.GeneralCommandLine
6+ import com.intellij.execution.process.CapturingProcessAdapter
7+ import com.intellij.execution.process.ProcessOutput
88import com.intellij.openapi.components.Service
99import com.intellij.openapi.project.Project
1010import kotlinx.coroutines.Dispatchers
@@ -14,49 +14,94 @@ import kotlinx.coroutines.withContext
1414class OpcodesDumperService (var project : Project ) : DumperServiceInterface {
1515 val state = PhpDumpSettingsService .getInstance(project)
1616
17- override suspend fun dump (file : String ): Any {
17+ override suspend fun dump (file : String ): ProcessOutput {
1818 val debugLevel = state.debugLevel.value
19- val preloadFile = state.preloadFile
2019
2120 val localFile = PathMapper .map(project, file)
22- val command = GeneralCommandLine (buildList {
23- add(" -l" )
24- addAll(" -d display_errors=0" .split(" " ))
25- addAll(" -d error_reporting=0" .split(" " ))
26-
27- addAll(" -d opcache.enable_cli=1" .split(" " ))
28- addAll(" -d opcache.save_comments=1" .split(" " ))
29- addAll(" -d opcache.opt_debug_level=${debugLevel} " .split(" " ))
30- if (preloadFile != null ) {
31- addAll(" -d opcache.preload=${preloadFile} " .split(" " ))
32- }
33- add(localFile)
34- }).commandLineString
21+ val preloadFile = state.preloadFile.let {
22+ if (! it.isNullOrBlank()) { PathMapper .map(project, it) } else { " " }
23+ }
3524
3625 // language=injectablephp
3726 val phpSnippet = $$"""
38- opcache_compile_file($argv [1]); passthru(PHP_BINARY . ' $$command ');
27+ if (!extension_loaded('opcache') && !extension_loaded('Zend OPcache')) {
28+ exit('Error: opcache extension is not loaded');
29+ }
30+ $file = $argv [1] ?? null;
31+
32+ if (!is_string($file ) || !is_file($file )) {
33+ exit('Error: Could not open input file "' . addcslashes(print_r($file , true), '"') . '"');
34+ }
35+
36+ opcache_invalidate($file );
37+ opcache_compile_file($file );
38+
39+ $iterations = 0;
40+ while (!opcache_is_script_cached($file ) && $iterations ++ < 10) {
41+ usleep(100);
42+ opcache_compile_file($file );
43+ }
44+
45+ if (opcache_is_script_cached($file ) === false) {
46+ exit('Error: Could not compile file "' . addcslashes(print_r($file , true), '"') . '"');
47+ }
48+
49+ $temp = sys_get_temp_dir() . '/opcache_dump';
50+
51+ if (!is_dir($temp )) {
52+ @mkdir($temp );
53+ }
54+
55+ passthru(implode(' ', [
56+ PHP_BINARY, '-l',
57+ '-d', escapeshellarg('display_errors=0'),
58+ '-d', escapeshellarg('error_reporting=0'),
59+
60+ '-d', escapeshellarg('opcache.file_cache_only=1'),
61+ '-d', escapeshellarg('opcache.file_cache=' . $temp ),
62+ '-d', escapeshellarg('opcache.enable=1'),
63+ '-d', escapeshellarg('opcache.enable_cli=1'),
64+ '-d', escapeshellarg('opcache.save_comments=1'),
65+ '-d', escapeshellarg('opcache.opt_debug_level=$$debugLevel '),
66+ ...(!empty('$$preloadFile ') ? ['-d', escapeshellarg('opcache.preload=$$preloadFile ')] : []),
67+ escapeshellarg('$$localFile '),
68+ ]));
69+
70+ $files = new RecursiveIteratorIterator(
71+ new RecursiveDirectoryIterator($temp , FilesystemIterator::SKIP_DOTS),
72+ RecursiveIteratorIterator::CHILD_FIRST,
73+ );
74+
75+ foreach ($files as $info ) {
76+ if ($info ->isDir()) {
77+ @rmdir($info ->getRealPath());
78+ } else {
79+ @unlink($info ->getRealPath());
80+ }
81+ }
3982 """ .trimIndent()
4083
4184// println("command: $command")
4285// println("phpSnippet: $phpSnippet")
4386 return withContext(Dispatchers .IO ) {
44- val opcodes = StringBuilder ()
45- val errors = StringBuilder ()
87+ val output = ProcessOutput ()
4688
4789 PhpCommandExecutor .execute(
4890 localFile,
4991 phpSnippet,
5092 project,
51- SeparateStringBufferProcessAdapter (stderr = opcodes, stdout = errors),
52- (" -d opcache.enable_cli=1" .split(" " )),
93+ CapturingProcessAdapter (output),
94+ buildList {
95+ addAll(" -d display_errors=0" .split(" " ))
96+ addAll(" -d error_reporting=0" .split(" " ))
97+
98+ addAll(" -d opcache.enable=1" .split(" " ))
99+ addAll(" -d opcache.enable_cli=1" .split(" " ))
100+ addAll(" -d opcache.save_comments=1" .split(" " ))
101+ },
53102 )
54103
55- if (opcodes.isEmpty()) {
56- errors.toString()
57- } else {
58- opcodes.toString()
59- }
104+ output
60105 }
61106 }
62107}
0 commit comments