2024.8.23
Loading...
Searching...
No Matches
class.bin.php.php
Go to the documentation of this file.
1<?php
2/*
3 *
4 * * Copyright (c) 2021-2024 Bearsampp
5 * * License: GNU General Public License version 3 or later; see LICENSE.txt
6 * * Website: https://bearsampp.com
7 * * Github: https://github.com/Bearsampp
8 *
9 */
10
11/**
12 * Class BinPhp
13 *
14 * This class extends the Module class and provides functionalities specific to managing PHP binaries within the Bearsampp application.
15 * It includes methods for reloading configurations, switching versions, updating configurations, and retrieving various PHP settings and extensions.
16 */
17class BinPhp extends Module
18{
19 const ROOT_CFG_ENABLE = 'phpEnable';
20 const ROOT_CFG_VERSION = 'phpVersion';
21
22 const LOCAL_CFG_CLI_EXE = 'phpCliExe';
23 const LOCAL_CFG_CLI_SILENT_EXE = 'phpCliSilentExe';
24 const LOCAL_CFG_CONF = 'phpConf';
25 const LOCAL_CFG_PEAR_EXE = 'phpPearExe';
26
27 const INI_SHORT_OPEN_TAG = 'short_open_tag';
28 const INI_ASP_TAGS = 'asp_tags';
29 const INI_Y2K_COMPLIANCE = 'y2k_compliance';
30 const INI_OUTPUT_BUFFERING = 'output_buffering';
31 const INI_ZLIB_OUTPUT_COMPRESSION = 'zlib.output_compression';
32 const INI_IMPLICIT_FLUSH = 'implicit_flush';
33 const INI_ALLOW_CALL_TIME_PASS_REFERENCE = 'allow_call_time_pass_reference';
34 const INI_SAFE_MODE = 'safe_mode';
35 const INI_SAFE_MODE_GID = 'safe_mode_gid';
36 const INI_EXPOSE_PHP = 'expose_php';
37 const INI_DISPLAY_ERRORS = 'display_errors';
38 const INI_DISPLAY_STARTUP_ERRORS = 'display_startup_errors';
39 const INI_LOG_ERRORS = 'log_errors';
40 const INI_IGNORE_REPEATED_ERRORS = 'ignore_repeated_errors';
41 const INI_IGNORE_REPEATED_SOURCE = 'ignore_repeated_source';
42 const INI_REPORT_MEMLEAKS = 'report_memleaks';
43 const INI_TRACK_ERRORS = 'track_errors';
44 const INI_HTML_ERRORS = 'html_errors';
45 const INI_REGISTER_GLOBALS = 'register_globals';
46 const INI_REGISTER_LONG_ARRAYS = 'register_long_arrays';
47 const INI_REGISTER_ARGC_ARGV = 'register_argc_argv';
48 const INI_AUTO_GLOBALS_JIT = 'auto_globals_jit';
49 const INI_MAGIC_QUOTES_GPC = 'magic_quotes_gpc';
50 const INI_MAGIC_QUOTES_RUNTIME = 'magic_quotes_runtime';
51 const INI_MAGIC_QUOTES_SYBASE = 'magic_quotes_sybase';
52 const INI_ENABLE_DL = 'enable_dl';
53 const INI_CGI_FORCE_REDIRECT = 'cgi.force_redirect';
54 const INI_CGI_FIX_PATHINFO = 'cgi.fix_pathinfo';
55 const INI_FILE_UPLOADS = 'file_uploads';
56 const INI_ALLOW_URL_FOPEN = 'allow_url_fopen';
57 const INI_ALLOW_URL_INCLUDE = 'allow_url_include';
58 const INI_PHAR_READONLY = 'phar.readonly';
59 const INI_PHAR_REQUIRE_HASH = 'phar.require_hash';
60 const INI_DEFINE_SYSLOG_VARIABLES = 'define_syslog_variables';
61 const INI_MAIL_ADD_X_HEADER = 'mail.add_x_header';
62 const INI_SQL_SAFE_MODE = 'sql.safe_mode';
63 const INI_ODBC_ALLOW_PERSISTENT = 'odbc.allow_persistent';
64 const INI_ODBC_CHECK_PERSISTENT = 'odbc.check_persistent';
65 const INI_MYSQL_ALLOW_LOCAL_INFILE = 'mysql.allow_local_infile';
66 const INI_MYSQL_ALLOW_PERSISTENT = 'mysql.allow_persistent';
67 const INI_MYSQL_TRACE_MODE = 'mysql.trace_mode';
68 const INI_MYSQLI_ALLOW_PERSISTENT = 'mysqli.allow_persistent';
69 const INI_MYSQLI_RECONNECT = 'mysqli.reconnect';
70 const INI_MYSQLND_COLLECT_STATISTICS = 'mysqlnd.collect_statistics';
71 const INI_MYSQLND_COLLECT_MEMORY_STATISTICS = 'mysqlnd.collect_memory_statistics';
72 const INI_PGSQL_ALLOW_PERSISTENT = 'pgsql.allow_persistent';
73 const INI_PGSQL_AUTO_RESET_PERSISTENT = 'pgsql.auto_reset_persistent';
74 const INI_SYBCT_ALLOW_PERSISTENT = 'sybct.allow_persistent';
75 const INI_SESSION_USE_COOKIES = 'session.use_cookies';
76 const INI_SESSION_USE_ONLY_COOKIES = 'session.use_only_cookies';
77 const INI_SESSION_AUTO_START = 'session.auto_start';
78 const INI_SESSION_COOKIE_HTTPONLY = 'session.cookie_httponly';
79 const INI_SESSION_BUG_COMPAT_42 = 'session.bug_compat_42';
80 const INI_SESSION_BUG_COMPAT_WARN = 'session.bug_compat_warn';
81 const INI_SESSION_USE_TRANS_SID = 'session.use_trans_sid';
82 const INI_MSSQL_ALLOW_PERSISTENT = 'mssql.allow_persistent';
83 const INI_MSSQL_COMPATIBILITY_MODE = 'mssql.compatability_mode';
84 const INI_MSSQL_SECURE_CONNECTION = 'mssql.secure_connection';
85 const INI_TIDY_CLEAN_OUTPUT = 'tidy.clean_output';
86 const INI_SOAP_WSDL_CACHE_ENABLED = 'soap.wsdl_cache_enabled';
87 const INI_XDEBUG_REMOTE_ENABLE = 'xdebug.remote_enable';
88 const INI_XDEBUG_PROFILER_ENABLE = 'xdebug.profiler_enable';
89 const INI_XDEBUG_PROFILER_ENABLE_TRIGGER = 'xdebug.profiler_enable_trigger';
90 const INI_APC_ENABLED = 'apc.enabled';
91 const INI_APC_INCLUDE_ONCE_OVERRIDE = 'apc.include_once_override';
92 const INI_APC_CANONICALIZE = 'apc.canonicalize';
93 const INI_APC_STAT = 'apc.stat';
94
95 private $apacheConf;
96 private $errorLog;
97
98 private $cliExe;
100 private $conf;
101 private $pearExe;
102
103 /**
104 * Constructor for the BinPhp class.
105 *
106 * @param string $id The ID of the module.
107 * @param string $type The type of the module.
108 */
109 public function __construct($id, $type) {
110 Util::logInitClass($this);
111 $this->reload($id, $type);
112 }
113
114 /**
115 * Reloads the module configuration based on the provided ID and type.
116 *
117 * @param string|null $id The ID of the module. If null, the current ID is used.
118 * @param string|null $type The type of the module. If null, the current type is used.
119 */
120 public function reload($id = null, $type = null) {
123
124 $this->name = $bearsamppLang->getValue(Lang::PHP);
125 $this->version = $bearsamppConfig->getRaw(self::ROOT_CFG_VERSION);
126 parent::reload($id, $type);
127
128 $this->enable = $this->enable && $bearsamppConfig->getRaw(self::ROOT_CFG_ENABLE);
129 $this->apacheConf = $bearsamppBins->getApache()->getCurrentPath() . '/' . $this->apacheConf; //FIXME: Useful ?
130 $this->errorLog = $bearsamppRoot->getLogsPath() . '/php_error.log';
131
132 if ($this->bearsamppConfRaw !== false) {
133 $this->cliExe = $this->symlinkPath . '/' . $this->bearsamppConfRaw[self::LOCAL_CFG_CLI_EXE];
134 $this->cliSilentExe = $this->symlinkPath . '/' . $this->bearsamppConfRaw[self::LOCAL_CFG_CLI_SILENT_EXE];
135 $this->conf = $this->symlinkPath . '/' . $this->bearsamppConfRaw[self::LOCAL_CFG_CONF];
136 $this->pearExe = $this->symlinkPath . '/' . $this->bearsamppConfRaw[self::LOCAL_CFG_PEAR_EXE];
137 }
138
139 if (!$this->enable) {
140 Util::logInfo($this->name . ' is not enabled!');
141 return;
142 }
143 if (!is_dir($this->currentPath)) {
144 Util::logError(sprintf($bearsamppLang->getValue(Lang::ERROR_FILE_NOT_FOUND), $this->name . ' ' . $this->version, $this->currentPath));
145 return;
146 }
147 if (!is_dir($this->symlinkPath)) {
148 Util::logError(sprintf($bearsamppLang->getValue(Lang::ERROR_FILE_NOT_FOUND), $this->name . ' ' . $this->version, $this->symlinkPath));
149 return;
150 }
151 if (!is_file($this->bearsamppConf)) {
152 Util::logError(sprintf($bearsamppLang->getValue(Lang::ERROR_CONF_NOT_FOUND), $this->name . ' ' . $this->version, $this->bearsamppConf));
153 return;
154 }
155 if (!is_file($this->cliExe)) {
156 Util::logError(sprintf($bearsamppLang->getValue(Lang::ERROR_EXE_NOT_FOUND), $this->name . ' ' . $this->version, $this->cliExe));
157 }
158 if (!is_file($this->cliSilentExe)) {
159 Util::logError(sprintf($bearsamppLang->getValue(Lang::ERROR_EXE_NOT_FOUND), $this->name . ' ' . $this->version, $this->cliSilentExe));
160 }
161 if (!is_file($this->conf)) {
162 Util::logError(sprintf($bearsamppLang->getValue(Lang::ERROR_CONF_NOT_FOUND), $this->name . ' ' . $this->version, $this->conf));
163 }
164 if (!is_file($this->pearExe)) {
165 Util::logError(sprintf($bearsamppLang->getValue(Lang::ERROR_EXE_NOT_FOUND), $this->name . ' ' . $this->version, $this->pearExe));
166 }
167 }
168
169 /**
170 * Switches the PHP version to the specified version.
171 *
172 * @param string $version The version to switch to.
173 * @param bool $showWindow Whether to show a window during the switch process.
174 * @return bool True if the switch was successful, false otherwise.
175 */
176 public function switchVersion($version, $showWindow = false) {
177 Util::logDebug('Switch ' . $this->name . ' version to ' . $version);
178 return $this->updateConfig($version, 0, $showWindow);
179 }
180
181 /**
182 * Updates the PHP configuration to the specified version.
183 *
184 * @param string|null $version The version to update to. If null, the current version is used.
185 * @param int $sub The sub-level for logging indentation.
186 * @param bool $showWindow Whether to show a window during the update process.
187 * @return bool True if the update was successful, false otherwise.
188 */
189 protected function updateConfig($version = null, $sub = 0, $showWindow = false) {
190 global $bearsamppLang, $bearsamppBins, $bearsamppApps, $bearsamppWinbinder;
191
192 if (!$this->enable) {
193 return true;
194 }
195
196 $version = $version == null ? $this->version : $version;
197 Util::logDebug(($sub > 0 ? str_repeat(' ', 2 * $sub) : '') . 'Update ' . $this->name . ' ' . $version . ' config');
198
199 $boxTitle = sprintf($bearsamppLang->getValue(Lang::SWITCH_VERSION_TITLE), $this->getName(), $version);
200
201 $conf = str_replace('php' . $this->getVersion(), 'php' . $version, $this->getConf());
202 $bearsamppConf = str_replace('php' . $this->getVersion(), 'php' . $version, $this->bearsamppConf);
203
204 $tsDll = $this->getTsDll($version);
205 $apachePhpModulePath = $this->getApacheModule($bearsamppBins->getApache()->getVersion(), $version);
206
207 Util::logDebug(($sub > 0 ? str_repeat(' ', 2 * $sub) : '') . 'PHP TsDll found: ' . $tsDll);
208 Util::logDebug(($sub > 0 ? str_repeat(' ', 2 * $sub) : '') . 'PHP Apache module found: ' . $apachePhpModulePath);
209
210 if (!file_exists($conf) || !file_exists($bearsamppConf)) {
211 Util::logError('bearsampp config files not found for ' . $this->getName() . ' ' . $version);
212 if ($showWindow) {
213 $bearsamppWinbinder->messageBoxError(
214 sprintf($bearsamppLang->getValue(Lang::BEARSAMPP_CONF_NOT_FOUND_ERROR), $this->getName() . ' ' . $version),
215 $boxTitle
216 );
217 }
218 return false;
219 }
220
221 $bearsamppConfRaw = parse_ini_file($bearsamppConf);
222 if ($bearsamppConfRaw === false || !isset($bearsamppConfRaw[self::ROOT_CFG_VERSION]) || $bearsamppConfRaw[self::ROOT_CFG_VERSION] != $version) {
223 Util::logError('bearsampp config file malformed for ' . $this->getName() . ' ' . $version);
224 if ($showWindow) {
225 $bearsamppWinbinder->messageBoxError(
226 sprintf($bearsamppLang->getValue(Lang::BEARSAMPP_CONF_MALFORMED_ERROR), $this->getName() . ' ' . $version),
227 $boxTitle
228 );
229 }
230 return false;
231 }
232
233 if ($tsDll === false || $apachePhpModulePath === false) {
234 Util::logDebug($this->getName() . ' ' . $version . ' does not seem to be compatible with Apache ' . $bearsamppBins->getApache()->getVersion());
235 if ($showWindow) {
236 $bearsamppWinbinder->messageBoxError(
237 sprintf($bearsamppLang->getValue(Lang::PHP_INCPT), $version, $bearsamppBins->getApache()->getVersion()),
238 $boxTitle
239 );
240 }
241 return false;
242 }
243
244 // bearsampp.conf
245 $this->setVersion($version);
246
247 // conf
248 Util::replaceInFile($this->getConf(), array(
249 '/^mysql.default_port\s=\s(\d+)/' => 'mysql.default_port = ' . $bearsamppBins->getMysql()->getPort(),
250 '/^mysqli.default_port\s=\s(\d+)/' => 'mysqli.default_port = ' . $bearsamppBins->getMysql()->getPort()
251 ));
252
253 // apache
254 $bearsamppBins->getApache()->update($sub + 1);
255
256 // phpmyadmin
257 $bearsamppApps->getPhpmyadmin()->update($sub + 1);
258
259 return true;
260 }
261
262 /**
263 * Retrieves the PHP settings.
264 *
265 * @return array An associative array of PHP settings.
266 */
267 public function getSettings() {
268 return array(
269 'Language options' => array(
270 'Short open tag' => self::INI_SHORT_OPEN_TAG,
271 'ASP-style tags' => self::INI_ASP_TAGS,
272 'Year 2000 compliance' => self::INI_Y2K_COMPLIANCE,
273 'Output buffering' => self::INI_OUTPUT_BUFFERING,
274 'Zlib output compression' => self::INI_ZLIB_OUTPUT_COMPRESSION,
275 'Implicit flush' => self::INI_IMPLICIT_FLUSH,
276 'Allow call time pass reference' => self::INI_ALLOW_CALL_TIME_PASS_REFERENCE,
277 'Safe mode' => self::INI_SAFE_MODE,
278 'Safe mode GID' => self::INI_SAFE_MODE_GID,
279 ),
280 'Miscellaneous' => array(
281 'Expose PHP' => self::INI_EXPOSE_PHP,
282 ),
283 'Error handling and logging' => array(
284 'Display errors' => self::INI_DISPLAY_ERRORS,
285 'Display startup errors' => self::INI_DISPLAY_STARTUP_ERRORS,
286 'Log errors' => self::INI_LOG_ERRORS,
287 'Ignore repeated errors' => self::INI_IGNORE_REPEATED_ERRORS,
288 'Ignore repeated source' => self::INI_IGNORE_REPEATED_SOURCE,
289 'Report memory leaks' => self::INI_REPORT_MEMLEAKS,
290 'Track errors' => self::INI_TRACK_ERRORS,
291 'HTML errors' => self::INI_HTML_ERRORS,
292 ),
293 'Data Handling' => array(
294 'Register globals' => self::INI_REGISTER_GLOBALS,
295 'Register long arrays' => self::INI_REGISTER_LONG_ARRAYS,
296 'Register argc argv' => self::INI_REGISTER_ARGC_ARGV,
297 'Auto globals just in time' => self::INI_AUTO_GLOBALS_JIT,
298 'Magic quotes gpc' => self::INI_MAGIC_QUOTES_GPC,
299 'Magic quotes runtime' => self::INI_MAGIC_QUOTES_RUNTIME,
300 'Magic quotes Sybase' => self::INI_MAGIC_QUOTES_SYBASE,
301 ),
302 'Paths and Directories' => array(
303 'Enable dynamic loading' => self::INI_ENABLE_DL,
304 'CGI force redirect' => self::INI_CGI_FORCE_REDIRECT,
305 'CGI fix path info' => self::INI_CGI_FIX_PATHINFO,
306 ),
307 'File uploads' => array(
308 'File uploads' => self::INI_FILE_UPLOADS,
309 ),
310 'Fopen wrappers' => array(
311 'Allow url fopen' => self::INI_ALLOW_URL_FOPEN,
312 'Allow url include' => self::INI_ALLOW_URL_INCLUDE,
313 ),
314 'Module settings' => array(
315 'Phar' => array(
316 'Read only' => self::INI_PHAR_READONLY,
317 'Require hash' => self::INI_PHAR_REQUIRE_HASH,
318 ),
319 'Syslog' => array(
320 'Define syslog variables' => self::INI_DEFINE_SYSLOG_VARIABLES,
321 ),
322 'Mail' => array(
323 'Add X-PHP-Originating-Script' => self::INI_MAIL_ADD_X_HEADER,
324 ),
325 'SQL' => array(
326 'Safe mode' => self::INI_SQL_SAFE_MODE,
327 ),
328 'ODBC' => array(
329 'Allow persistent' => self::INI_ODBC_ALLOW_PERSISTENT,
330 'Check persistent' => self::INI_ODBC_CHECK_PERSISTENT,
331 ),
332 'MySQL' => array(
333 'Allow local infile' => self::INI_MYSQL_ALLOW_LOCAL_INFILE,
334 'Allow persistent' => self::INI_MYSQL_ALLOW_PERSISTENT,
335 'Trace mode' => self::INI_MYSQL_TRACE_MODE,
336 ),
337 'MySQLi' => array(
338 'Allow persistent' => self::INI_MYSQLI_ALLOW_PERSISTENT,
339 'Reconnect' => self::INI_MYSQLI_RECONNECT,
340 ),
341 'MySQL Native Driver' => array(
342 'Collect statistics' => self::INI_MYSQLND_COLLECT_STATISTICS,
343 'Collect memory statistics' => self::INI_MYSQLND_COLLECT_MEMORY_STATISTICS,
344 ),
345 'PostgresSQL' => array(
346 'Allow persistent' => self::INI_PGSQL_ALLOW_PERSISTENT,
347 'Auto reset persistent' => self::INI_PGSQL_AUTO_RESET_PERSISTENT,
348 ),
349 'Sybase-CT' => array(
350 'Allow persistent' => self::INI_SYBCT_ALLOW_PERSISTENT,
351 ),
352 'Session' => array(
353 'Use cookies' => self::INI_SESSION_USE_COOKIES,
354 'Use only cookies' => self::INI_SESSION_USE_ONLY_COOKIES,
355 'Auto start' => self::INI_SESSION_AUTO_START,
356 'Cookie HTTP only' => self::INI_SESSION_COOKIE_HTTPONLY,
357 'Bug compat 42' => self::INI_SESSION_BUG_COMPAT_42,
358 'Bug compat warning' => self::INI_SESSION_BUG_COMPAT_WARN,
359 'Use trans sid' => self::INI_SESSION_USE_TRANS_SID,
360 ),
361 'MSSQL' => array(
362 'Allow persistent' => self::INI_MSSQL_ALLOW_PERSISTENT,
363 'Compatibility mode' => self::INI_MSSQL_COMPATIBILITY_MODE,
364 'Secure connection' => self::INI_MSSQL_SECURE_CONNECTION,
365 ),
366 'Tidy' => array(
367 'Clean output' => self::INI_TIDY_CLEAN_OUTPUT,
368 ),
369 'SOAP' => array(
370 'WSDL cache enabled' => self::INI_SOAP_WSDL_CACHE_ENABLED,
371 ),
372 'XDebug' => array(
373 'Remote enable' => self::INI_XDEBUG_REMOTE_ENABLE,
374 'Profiler enable' => self::INI_XDEBUG_PROFILER_ENABLE,
375 'Profiler enable trigger' => self::INI_XDEBUG_PROFILER_ENABLE_TRIGGER,
376 ),
377 'APC' => array(
378 'Enabled' => self::INI_APC_ENABLED,
379 'Include once override' => self::INI_APC_INCLUDE_ONCE_OVERRIDE,
380 'Canonicalize' => self::INI_APC_CANONICALIZE,
381 'Stat' => self::INI_APC_STAT,
382 ),
383 ),
384 );
385 }
386
387 /**
388 * Retrieves the default, off, and current values for various PHP settings.
389 *
390 * @return array An associative array where the key is the setting name and the value is an array containing the default, off, and current values.
391 */
392 public function getSettingsValues() {
393 return array(
394 self::INI_SHORT_OPEN_TAG => array('On', 'Off', 'On'),
395 self::INI_ASP_TAGS => array('On', 'Off', 'Off'),
396 self::INI_Y2K_COMPLIANCE => array('1', '0', '1'),
397 self::INI_OUTPUT_BUFFERING => array('4096', 'Off', '4096'),
398 self::INI_ZLIB_OUTPUT_COMPRESSION => array('On', 'Off', 'Off'),
399 self::INI_IMPLICIT_FLUSH => array('On', 'Off', 'Off'),
400 self::INI_ALLOW_CALL_TIME_PASS_REFERENCE => array('On', 'Off', 'On'),
401 self::INI_SAFE_MODE => array('On', 'Off', 'Off'),
402 self::INI_SAFE_MODE_GID => array('On', 'Off', 'Off'),
403 self::INI_EXPOSE_PHP => array('On', 'Off', 'On'),
404 self::INI_DISPLAY_ERRORS => array('On', 'Off', 'On'),
405 self::INI_DISPLAY_STARTUP_ERRORS => array('On', 'Off', 'On'),
406 self::INI_LOG_ERRORS => array('On', 'Off', 'On'),
407 self::INI_IGNORE_REPEATED_ERRORS => array('On', 'Off', 'Off'),
408 self::INI_IGNORE_REPEATED_SOURCE => array('On', 'Off', 'Off'),
409 self::INI_REPORT_MEMLEAKS => array('On', 'Off', 'On'),
410 self::INI_TRACK_ERRORS => array('On', 'Off', 'On'),
411 self::INI_HTML_ERRORS => array('On', 'Off', 'On'),
412 self::INI_REGISTER_GLOBALS => array('On', 'Off', 'Off'),
413 self::INI_REGISTER_LONG_ARRAYS => array('On', 'Off', 'Off'),
414 self::INI_REGISTER_ARGC_ARGV => array('On', 'Off', 'Off'),
415 self::INI_AUTO_GLOBALS_JIT => array('On', 'Off', 'On'),
416 self::INI_MAGIC_QUOTES_GPC => array('On', 'Off', 'Off'),
417 self::INI_MAGIC_QUOTES_RUNTIME => array('On', 'Off', 'Off'),
418 self::INI_MAGIC_QUOTES_SYBASE => array('On', 'Off', 'Off'),
419 self::INI_ENABLE_DL => array('On', 'Off', 'Off'),
420 self::INI_CGI_FORCE_REDIRECT => array('1', '0', '1'),
421 self::INI_FILE_UPLOADS => array('On', 'Off', 'On'),
422 self::INI_ALLOW_URL_FOPEN => array('On', 'Off', 'On'),
423 self::INI_ALLOW_URL_INCLUDE => array('On', 'Off', 'Off'),
424 self::INI_DEFINE_SYSLOG_VARIABLES => array('On', 'Off', 'Off'),
425 self::INI_MAIL_ADD_X_HEADER => array('On', 'Off', 'On'),
426 self::INI_SQL_SAFE_MODE => array('On', 'Off', 'Off'),
427 self::INI_ODBC_ALLOW_PERSISTENT => array('On', 'Off', 'On'),
428 self::INI_ODBC_CHECK_PERSISTENT => array('On', 'Off', 'On'),
429 self::INI_MYSQL_ALLOW_LOCAL_INFILE => array('On', 'Off', 'Off'),
430 self::INI_MYSQL_ALLOW_PERSISTENT => array('On', 'Off', 'On'),
431 self::INI_MYSQL_TRACE_MODE => array('On', 'Off', 'Off'),
432 self::INI_MYSQLI_ALLOW_PERSISTENT => array('On', 'Off', 'On'),
433 self::INI_MYSQLI_RECONNECT => array('On', 'Off', 'Off'),
434 self::INI_MYSQLND_COLLECT_STATISTICS => array('On', 'Off', 'On'),
435 self::INI_MYSQLND_COLLECT_MEMORY_STATISTICS => array('On', 'Off', 'On'),
436 self::INI_PGSQL_ALLOW_PERSISTENT => array('On', 'Off', 'On'),
437 self::INI_PGSQL_AUTO_RESET_PERSISTENT => array('On', 'Off', 'Off'),
438 self::INI_SYBCT_ALLOW_PERSISTENT => array('On', 'Off', 'On'),
439 self::INI_SESSION_USE_COOKIES => array('1', '0', '1'),
440 self::INI_SESSION_USE_ONLY_COOKIES => array('1', '0', '1'),
441 self::INI_SESSION_AUTO_START => array('1', '0', '0'),
442 self::INI_SESSION_COOKIE_HTTPONLY => array('1', '', ''),
443 self::INI_SESSION_BUG_COMPAT_42 => array('On', 'Off', 'On'),
444 self::INI_SESSION_BUG_COMPAT_WARN => array('On', 'Off', 'On'),
445 self::INI_SESSION_USE_TRANS_SID => array('1', '0', '0'),
446 self::INI_MSSQL_ALLOW_PERSISTENT => array('On', 'Off', 'On'),
447 self::INI_MSSQL_COMPATIBILITY_MODE => array('On', 'Off', 'Off'),
448 self::INI_MSSQL_SECURE_CONNECTION => array('On', 'Off', 'Off'),
449 self::INI_TIDY_CLEAN_OUTPUT => array('On', 'Off', 'Off'),
450 self::INI_SOAP_WSDL_CACHE_ENABLED => array('1', '0', '1'),
451 self::INI_XDEBUG_REMOTE_ENABLE => array('On', 'Off', 'On'),
452 self::INI_XDEBUG_PROFILER_ENABLE => array('On', 'Off', 'Off'),
453 self::INI_XDEBUG_PROFILER_ENABLE_TRIGGER => array('On', 'Off', 'Off'),
454 self::INI_APC_ENABLED => array('1', '0', '1'),
455 self::INI_APC_INCLUDE_ONCE_OVERRIDE => array('1', '0', '1'),
456 self::INI_APC_CANONICALIZE => array('1', '0', '1'),
457 self::INI_APC_STAT => array('1', '0', '1'),
458 );
459 }
460
461 /**
462 * Checks if a specific PHP setting is active.
463 *
464 * @param string $name The name of the setting to check.
465 * @return bool True if the setting is active, false otherwise.
466 */
467 public function isSettingActive($name) {
468 $settingsValues = $this->getSettingsValues();
469
470 $confContent = file($this->getConf());
471 foreach ($confContent as $row) {
472 $settingMatch = array();
473 if (preg_match('/^' . $name . '\s*=\s*(.+)/i', $row, $settingMatch)) {
474 return isset($settingMatch[1]) && isset($settingsValues[$name]) && $settingsValues[$name][0] == trim($settingMatch[1]);
475 }
476 }
477
478 return false;
479 }
480
481 /**
482 * Checks if a specific PHP setting exists in the configuration file.
483 *
484 * @param string $name The name of the setting to check.
485 * @return bool True if the setting exists, false otherwise.
486 */
487 public function isSettingExists($name) {
488 $confContent = file($this->getConf());
489 foreach ($confContent as $row) {
490 if (preg_match('/^\s*?;?\s*?' . $name . '\s*=\s*.*/i', $row)) {
491 return true;
492 }
493 }
494
495 return false;
496 }
497
498 /**
499 * Retrieves the list of PHP extensions from both the configuration file and the extensions folder.
500 *
501 * @return array An associative array where the key is the extension name and the value is the status (on/off).
502 */
503 public function getExtensions() {
504 $fromFolder = $this->getExtensionsFromConf();
505 $fromConf = $this->getExtensionsFromFolder();
506 $result = array_merge($fromConf, $fromFolder);
507 ksort($result);
508 return $result;
509 }
510
511 /**
512 * Checks if a specific PHP extension is excluded from the list.
513 *
514 * @param string $ext The name of the extension to check.
515 * @return bool True if the extension is excluded, false otherwise.
516 */
517 private function isExtensionExcluded($ext) {
518 return in_array($ext, array(
519 'opcache',
520 'xdebug'
521 ));
522 }
523
524 /**
525 * Retrieves the list of PHP extensions from the configuration file.
526 *
527 * @return array An associative array where the key is the extension name and the value is the status (on/off).
528 */
529 public function getExtensionsFromConf() {
530 $result = array();
531
532 $confContent = file($this->getConf());
533 foreach ($confContent as $row) {
534 $extMatch = array();
535 if (preg_match('/^(;)?extension\s*=\s*"?(.+)"?/i', $row, $extMatch)) {
536 $name = preg_replace("/^php_/", "", preg_replace("/\.dll$/", "", trim($extMatch[2])));
537 if ($this->isExtensionExcluded($name)) {
538 continue;
539 }
540 if ($extMatch[1] == ';') {
542 } else {
544 }
545 }
546 }
547
548 ksort($result);
549 return $result;
550 }
551
552 /**
553 * Retrieves the list of currently loaded PHP extensions.
554 *
555 * @return array An array of extension names that are currently loaded.
556 */
557 public function getExtensionsLoaded() {
558 $result = array();
559 foreach ($this->getExtensionsFromConf() as $name => $status) {
561 $result[] = $name;
562 }
563 }
564 return $result;
565 }
566
567 /**
568 * Retrieves the list of PHP extensions from the extensions folder.
569 *
570 * @return array An associative array where the key is the extension name and the value is the status (off).
571 */
572 public function getExtensionsFromFolder() {
573 $result = array();
574
575 $handle = @opendir($this->getCurrentPath(). '/ext');
576 if (!$handle) {
577 return $result;
578 }
579
580 while (false !== ($file = readdir($handle))) {
581 if ($file != "." && $file != ".." && Util::endWith($file, '.dll')) {
582 $name = preg_replace("/^php_/", "", preg_replace("/\.dll$/", "", trim($file)));
583 if ($this->isExtensionExcluded($name)) {
584 continue;
585 }
587 }
588 }
589
590 closedir($handle);
591 ksort($result);
592 return $result;
593 }
594
595 /**
596 * Retrieves the path to the Apache module for the specified Apache and PHP versions.
597 *
598 * @param string $apacheVersion The version of Apache.
599 * @param string|null $phpVersion The version of PHP. If null, the current PHP version is used.
600 * @return string|false The path to the Apache module, or false if not found.
601 */
602 public function getApacheModule($apacheVersion, $phpVersion = null) {
603 $apacheVersion = substr(str_replace('.', '', $apacheVersion), 0, 2);
604 $phpVersion = $phpVersion == null ? $this->getVersion() : $phpVersion;
605
606 $currentPath = str_replace('php' . $this->getVersion(), 'php' . $phpVersion, $this->getCurrentPath());
607 $bearsamppConf = str_replace('php' . $this->getVersion(), 'php' . $phpVersion, $this->bearsamppConf);
608
609 if (in_array($phpVersion, $this->getVersionList()) && file_exists($bearsamppConf)) {
610 $apacheCpt = parse_ini_file($bearsamppConf);
611 if ($apacheCpt !== false) {
612 foreach ($apacheCpt as $aVersion => $apacheModule) {
613 $aVersion = str_replace('apache', '', $aVersion);
614 $aVersion = str_replace('.', '', $aVersion);
615 if ($apacheVersion == $aVersion && file_exists($currentPath . '/' . $apacheModule)) {
616 return $currentPath . '/' . $apacheModule;
617 }
618 }
619 }
620 }
621
622 return false;
623 }
624
625 /**
626 * Retrieves the name of the PHP Thread Safe (TS) DLL for the specified PHP version.
627 *
628 * @param string|null $phpVersion The version of PHP. If null, the current PHP version is used.
629 * @return string|false The name of the PHP TS DLL, or false if not found.
630 */
631 public function getTsDll($phpVersion = null) {
632 $phpVersion = $phpVersion == null ? $this->getVersion() : $phpVersion;
633 $currentPath = str_replace('php' . $this->getVersion(), 'php' . $phpVersion, $this->getCurrentPath());
634
635 if (file_exists($currentPath . '/php7ts.dll')) {
636 return 'php7ts.dll';
637 } elseif (file_exists($currentPath . '/php8ts.dll')) {
638 return 'php8ts.dll';
639 }
640
641 return false;
642 }
643
644 /**
645 * Sets the PHP version and updates the configuration.
646 *
647 * @param string $version The version to set.
648 */
649 public function setVersion($version) {
650 global $bearsamppConfig;
651 $this->version = $version;
652 $bearsamppConfig->replace(self::ROOT_CFG_VERSION, $version);
653 $this->reload();
654 }
655
656 /**
657 * Enables or disables the module and updates the configuration.
658 *
659 * @param int $enabled The enable status (Config::ENABLED or Config::DISABLED).
660 * @param bool $showWindow Whether to show a window during the process.
661 */
662 public function setEnable($enabled, $showWindow = false) {
663 global $bearsamppConfig, $bearsamppBins, $bearsamppLang, $bearsamppWinbinder;
664
665 if ($enabled == Config::ENABLED && !is_dir($this->currentPath)) {
666 Util::logDebug($this->getName() . ' cannot be enabled because bundle ' . $this->getVersion() . ' does not exist in ' . $this->currentPath);
667 if ($showWindow) {
668 $bearsamppWinbinder->messageBoxError(
669 sprintf($bearsamppLang->getValue(Lang::ENABLE_BUNDLE_NOT_EXIST), $this->getName(), $this->getVersion(), $this->currentPath),
670 sprintf($bearsamppLang->getValue(Lang::ENABLE_TITLE), $this->getName())
671 );
672 }
673 $enabled = Config::DISABLED;
674 }
675
676 Util::logInfo($this->getName() . ' switched to ' . ($enabled == Config::ENABLED ? 'enabled' : 'disabled'));
677 $this->enable = $enabled == Config::ENABLED;
678 $bearsamppConfig->replace(self::ROOT_CFG_ENABLE, $enabled);
679
680 $this->reload();
681 $bearsamppBins->getApache()->update();
682 if ($bearsamppBins->getApache()->isEnable() && $bearsamppBins->getApache()->getService()->isRunning()) {
683 $bearsamppBins->getApache()->getService()->stop();
685 }
686 }
687
688 /**
689 * Retrieves the path to the PHP error log file.
690 *
691 * @return string The path to the PHP error log file.
692 */
693 public function getErrorLog() {
694 return $this->errorLog;
695 }
696
697 /**
698 * Retrieves the path to the PHP CLI executable.
699 *
700 * @return string The path to the PHP CLI executable.
701 */
702 public function getCliExe() {
703 return $this->cliExe;
704 }
705
706 /**
707 * Retrieves the path to the PHP CLI silent executable.
708 *
709 * @return string The path to the PHP CLI silent executable.
710 */
711 public function getCliSilentExe() {
712 return $this->cliSilentExe;
713 }
714
715 /**
716 * Retrieves the path to the PHP configuration file.
717 *
718 * @return string The path to the PHP configuration file.
719 */
720 public function getConf() {
721 return $this->conf;
722 }
723
724 /**
725 * Retrieves the path to the PHP PEAR executable.
726 *
727 * @return string The path to the PHP PEAR executable.
728 */
729 public function getPearExe() {
730 return $this->pearExe;
731 }
732
733 /**
734 * Retrieves the version of PEAR.
735 *
736 * @param bool $cache Whether to use the cached version.
737 * @return string|null The PEAR version, or null if not found.
738 */
739 public function getPearVersion($cache = false) {
740 $cacheFile = $this->getCurrentPath() . '/pear/version';
741 if (!$cache) {
742 file_put_contents($cacheFile, Batch::getPearVersion());
743 }
744 return file_exists($cacheFile) ? file_get_contents($cacheFile) : null;
745 }}
$result
global $bearsamppBins
global $bearsamppLang
global $bearsamppRoot
static getPearVersion()
const CMD_SYNTAX_CHECK
const INI_SESSION_BUG_COMPAT_WARN
const LOCAL_CFG_CLI_EXE
getExtensionsFromConf()
const INI_ODBC_ALLOW_PERSISTENT
const INI_PHAR_READONLY
const ROOT_CFG_ENABLE
getExtensionsFromFolder()
const INI_APC_INCLUDE_ONCE_OVERRIDE
const INI_APC_CANONICALIZE
const INI_ZLIB_OUTPUT_COMPRESSION
const LOCAL_CFG_PEAR_EXE
const INI_MSSQL_ALLOW_PERSISTENT
const INI_MYSQL_ALLOW_LOCAL_INFILE
getApacheModule($apacheVersion, $phpVersion=null)
switchVersion($version, $showWindow=false)
getPearVersion($cache=false)
const INI_Y2K_COMPLIANCE
const INI_MAGIC_QUOTES_GPC
const INI_TRACK_ERRORS
getTsDll($phpVersion=null)
const INI_XDEBUG_REMOTE_ENABLE
const INI_ODBC_CHECK_PERSISTENT
const INI_REGISTER_ARGC_ARGV
const INI_SOAP_WSDL_CACHE_ENABLED
const INI_MAGIC_QUOTES_RUNTIME
const INI_CGI_FORCE_REDIRECT
const INI_EXPOSE_PHP
const INI_MYSQLND_COLLECT_MEMORY_STATISTICS
const INI_XDEBUG_PROFILER_ENABLE_TRIGGER
getSettingsValues()
const INI_SAFE_MODE_GID
const INI_AUTO_GLOBALS_JIT
const INI_SESSION_COOKIE_HTTPONLY
const INI_SAFE_MODE
const INI_SESSION_USE_TRANS_SID
const INI_MAIL_ADD_X_HEADER
const INI_ALLOW_CALL_TIME_PASS_REFERENCE
const INI_ENABLE_DL
const INI_LOG_ERRORS
const INI_TIDY_CLEAN_OUTPUT
const INI_ALLOW_URL_FOPEN
const INI_MYSQL_TRACE_MODE
const INI_PGSQL_AUTO_RESET_PERSISTENT
const INI_FILE_UPLOADS
const INI_SESSION_AUTO_START
setEnable($enabled, $showWindow=false)
const INI_DISPLAY_ERRORS
const INI_MYSQLND_COLLECT_STATISTICS
const INI_MYSQL_ALLOW_PERSISTENT
const INI_SYBCT_ALLOW_PERSISTENT
const INI_PGSQL_ALLOW_PERSISTENT
const INI_MYSQLI_RECONNECT
const INI_ASP_TAGS
updateConfig($version=null, $sub=0, $showWindow=false)
__construct($id, $type)
isExtensionExcluded($ext)
const INI_SHORT_OPEN_TAG
const INI_MAGIC_QUOTES_SYBASE
getExtensionsLoaded()
const INI_REPORT_MEMLEAKS
const ROOT_CFG_VERSION
const INI_IGNORE_REPEATED_SOURCE
reload($id=null, $type=null)
const INI_APC_ENABLED
const INI_SESSION_USE_ONLY_COOKIES
const INI_DEFINE_SYSLOG_VARIABLES
const INI_SQL_SAFE_MODE
setVersion($version)
isSettingActive($name)
const INI_HTML_ERRORS
const INI_MSSQL_SECURE_CONNECTION
const INI_MYSQLI_ALLOW_PERSISTENT
const INI_SESSION_USE_COOKIES
const INI_APC_STAT
const INI_CGI_FIX_PATHINFO
const INI_PHAR_REQUIRE_HASH
const INI_XDEBUG_PROFILER_ENABLE
const INI_OUTPUT_BUFFERING
const INI_IGNORE_REPEATED_ERRORS
const INI_IMPLICIT_FLUSH
const LOCAL_CFG_CONF
const INI_REGISTER_GLOBALS
const INI_ALLOW_URL_INCLUDE
const INI_REGISTER_LONG_ARRAYS
isSettingExists($name)
const INI_MSSQL_COMPATIBILITY_MODE
const LOCAL_CFG_CLI_SILENT_EXE
const INI_SESSION_BUG_COMPAT_42
const INI_DISPLAY_STARTUP_ERRORS
const DISABLED
const ENABLED
const ENABLE_TITLE
const PHP_INCPT
const ERROR_FILE_NOT_FOUND
const BEARSAMPP_CONF_NOT_FOUND_ERROR
const ENABLE_BUNDLE_NOT_EXIST
const ERROR_CONF_NOT_FOUND
const SWITCH_VERSION_TITLE
const ERROR_EXE_NOT_FOUND
const PHP
const BEARSAMPP_CONF_MALFORMED_ERROR
static logReloadClass($classInstance)
static replaceInFile($path, $replaceList)
static logError($data, $file=null)
static endWith($string, $search)
static logDebug($data, $file=null)
static startService($bin, $syntaxCheckCmd, $showWindow=false)
static logInitClass($classInstance)
static logInfo($data, $file=null)
global $bearsamppConfig
Definition homepage.php:26