2 namespace TYPO3\CMS\Install\SystemEnvironment;
19 use TYPO3\CMS\Install\Status;
78 $statusArray = array();
111 foreach ($this->requiredPhpExtensions as $extension) {
133 $includePath = ini_get(
'include_path');
135 $pathArray = $this->
trimExplode($delimiter, $includePath);
136 if (!in_array(
'.', $pathArray)) {
138 $status->setTitle(
'Current directory (./) is not within PHP include path');
140 'include_path = ' . implode(
' ', $pathArray) . LF .
141 'Normally the current path \'.\' is included in the' .
142 ' include_path of PHP. Although TYPO3 does not rely on this,' .
143 ' it is an unusual setting that may introduce problems for' .
148 $status->setTitle(
'Current directory (./) is within PHP include path.');
162 $status->setTitle(
'Trusted hosts pattern is insecure');
163 $status->setMessage(
'Trusted hosts pattern is configured to allow all header values. Check the pattern defined in Install Tool -> All configuration -> System -> trustedHostsPattern and adapt it to expected host value(s).');
167 $status->setTitle(
'Trusted hosts pattern is configured to allow current host value.');
170 $status->setTitle(
'Trusted hosts pattern mismatch');
171 $status->setMessage(
'The trusted hosts pattern will be configured to allow all header values. This is because your $SERVER_NAME is "' . htmlspecialchars($_SERVER[
'SERVER_NAME']) .
'" while your HTTP_HOST is "' . htmlspecialchars($_SERVER[
'HTTP_HOST']) .
'". Check the pattern defined in Install Tool -> All configuration -> System -> trustedHostsPattern and adapt it to expected host value(s).');
185 if (!ini_get(
'file_uploads')) {
187 $status->setTitle(
'File uploads not allowed in PHP');
189 'file_uploads=' . ini_get(
'file_uploads') . LF .
190 'TYPO3 uses the ability to upload files from the browser in various cases.' .
191 ' If this flag is disabled in PHP, you won\'t be able to upload files.' .
192 ' But it doesn\'t end here, because not only are files not accepted by' .
193 ' the server - ALL content in the forms are discarded and therefore' .
194 ' nothing at all will be editable if you don\'t set this flag!'
198 $status->setTitle(
'File uploads allowed in PHP');
212 if ($maximumPostSize > 0 && $maximumPostSize < $maximumUploadFilesize) {
214 $status->setTitle(
'Maximum size for POST requests is smaller than maximum upload filesize in PHP');
216 'upload_max_filesize=' . ini_get(
'upload_max_filesize') . LF .
217 'post_max_size=' . ini_get(
'post_max_size') . LF .
218 'You have defined a maximum size for file uploads in PHP which' .
219 ' exceeds the allowed size for POST requests. Therefore the' .
220 ' file uploads can also not be larger than ' . ini_get(
'post_max_size') .
'.'
224 $status->setTitle(
'Maximum post upload size correlates with maximum upload file size in PHP');
236 $minimumMemoryLimit = 32;
237 $recommendedMemoryLimit = 64;
239 if ($memoryLimit <= 0) {
241 $status->setTitle(
'Unlimited memory limit for PHP');
243 'PHP is configured not to limit memory usage at all. This is a risk' .
244 ' and should be avoided in production setup. In general it\'s best practice to limit this.' .
245 ' To be safe, set a limit in PHP, but with a minimum of ' . $recommendedMemoryLimit .
'MB:' . LF .
246 'memory_limit=' . $recommendedMemoryLimit .
'M'
248 }
elseif ($memoryLimit < 1024 * 1024 * $minimumMemoryLimit) {
250 $status->setTitle(
'PHP Memory limit below ' . $minimumMemoryLimit .
'MB');
252 'memory_limit=' . ini_get(
'memory_limit') . LF .
253 'Your system is configured to enforce a memory limit for PHP scripts lower than ' .
254 $minimumMemoryLimit .
'MB. It is required to raise the limit.' .
255 ' We recommend a minimum PHP memory limit of ' . $recommendedMemoryLimit .
'MB:' . LF .
256 'memory_limit=' . $recommendedMemoryLimit .
'M'
258 }
elseif ($memoryLimit < 1024 * 1024 * $recommendedMemoryLimit) {
260 $status->setTitle(
'PHP Memory limit below ' . $recommendedMemoryLimit .
'MB');
262 'memory_limit=' . ini_get(
'memory_limit') . LF .
263 'Your system is configured to enforce a memory limit for PHP scripts lower than ' .
264 $recommendedMemoryLimit .
'MB.' .
265 ' A slim TYPO3 instance without many extensions will probably work, but you should monitor your' .
266 ' system for "allowed memory size of X bytes exhausted" messages, especially if using the backend.' .
267 ' To be on the safe side,' .
' we recommend a minimum PHP memory limit of ' .
268 $recommendedMemoryLimit .
'MB:' . LF .
269 'memory_limit=' . $recommendedMemoryLimit .
'M'
273 $status->setTitle(
'PHP Memory limit is equal to or more than ' . $recommendedMemoryLimit .
'MB');
285 $minimumPhpVersion =
'5.5.0';
286 $currentPhpVersion = phpversion();
287 if (version_compare($currentPhpVersion, $minimumPhpVersion) < 0) {
289 $status->setTitle(
'PHP version too low');
291 'Your PHP version ' . $currentPhpVersion .
' is too old. TYPO3 CMS does not run' .
292 ' with this version. Update to at least PHP ' . $minimumPhpVersion
296 $status->setTitle(
'PHP version is fine');
308 $minimumPcreVersion =
'8.30';
309 if (!extension_loaded(
'pcre')) {
311 $status->setTitle(
'PHP extension pcre not loaded');
313 'TYPO3 CMS uses PHP extension pcre but it is not loaded' .
314 ' in your environment. Change your environment to provide this extension' .
315 ' in with minimum version ' . $minimumPcreVersion .
'.'
318 $installedPcreVersionString = trim(PCRE_VERSION);
319 $mainPcreVersionString = explode(
' ', $installedPcreVersionString);
320 $mainPcreVersionString = $mainPcreVersionString[0];
321 if (version_compare($mainPcreVersionString, $minimumPcreVersion) < 0) {
323 $status->setTitle(
'PCRE version too low');
325 'Your PCRE version ' . PCRE_VERSION .
' is too old. TYPO3 CMS may trigger PHP segmentantion' .
326 ' faults with this version. Update to at least PCRE ' . $minimumPcreVersion
330 $status->setTitle(
'PHP extension PCRE is loaded and version is fine');
343 $minimumMaximumExecutionTime = 30;
344 $recommendedMaximumExecutionTime = 240;
345 $currentMaximumExecutionTime = ini_get(
'max_execution_time');
346 if ($currentMaximumExecutionTime == 0) {
348 $status->setTitle(
'Infinite PHP script execution time');
350 'max_execution_time=0' . LF .
351 'While TYPO3 is fine with this, you risk a denial-of-service for your system if for whatever' .
352 ' reason some script hangs in an infinite loop. You are usually on the safe side ' .
353 ' if it is reduced to ' . $recommendedMaximumExecutionTime .
' seconds:' . LF .
354 'max_execution_time=' . $recommendedMaximumExecutionTime
356 }
elseif ($currentMaximumExecutionTime < $minimumMaximumExecutionTime) {
358 $status->setTitle(
'Low PHP script execution time');
360 'max_execution_time=' . $currentMaximumExecutionTime . LF .
361 'Your max_execution_time is too low. Some expensive operations in TYPO3 can take longer than that.' .
362 ' It is recommended to raise the limit to ' . $recommendedMaximumExecutionTime .
' seconds:' . LF .
363 'max_execution_time=' . $recommendedMaximumExecutionTime
365 }
elseif ($currentMaximumExecutionTime < $recommendedMaximumExecutionTime) {
367 $status->setTitle(
'Low PHP script execution time');
369 'max_execution_time=' . $currentMaximumExecutionTime . LF .
370 'Your max_execution_time is low. While TYPO3 often runs without problems' .
371 ' with ' . $minimumMaximumExecutionTime .
' seconds,' .
372 ' it may still happen that script execution is stopped before finishing' .
373 ' calculations. You should monitor the system for messages in this area' .
374 ' and maybe raise the limit to ' . $recommendedMaximumExecutionTime .
' seconds:' . LF .
375 'max_execution_time=' . $recommendedMaximumExecutionTime
379 $status->setTitle(
'Maximum PHP script execution time is equal to or more than '
380 . $recommendedMaximumExecutionTime);
392 $disabledFunctions = trim(ini_get(
'disable_functions'));
395 $disabledFunctionsArray = $this->
trimExplode(
',', $disabledFunctions);
398 $findStrings = array(
402 foreach ($disabledFunctionsArray as $key => $disabledFunction) {
403 foreach ($findStrings as $findString) {
404 if (strpos($disabledFunction, $findString) !==
false) {
405 unset($disabledFunctionsArray[$key]);
410 if ($disabledFunctions !==
'') {
411 if (!empty($disabledFunctionsArray)) {
413 $status->setTitle(
'Some PHP functions disabled');
415 'disable_functions=' . implode(
' ', explode(
',', $disabledFunctions)) . LF .
416 'These function(s) are disabled. TYPO3 uses some of those, so there might be trouble.' .
417 ' TYPO3 is designed to use the default set of PHP functions plus some common extensions.' .
418 ' Possibly these functions are disabled' .
419 ' due to security considerations and most likely the list would include a function like' .
420 ' exec() which is used by TYPO3 at various places. Depending on which exact functions' .
421 ' are disabled, some parts of the system may just break without further notice.'
425 $status->setTitle(
'Some PHP functions currently disabled but OK');
427 'disable_functions=' . implode(
' ', explode(
',', $disabledFunctions)) . LF .
428 'These function(s) are disabled. TYPO3 uses currently none of those, so you are good to go.'
433 $status->setTitle(
'No disabled PHP functions');
446 $allowUrlFopen = (bool)ini_get(
'allow_url_fopen');
447 $curlEnabled = !empty(
$GLOBALS[
'TYPO3_CONF_VARS'][
'SYS'][
'curlUse']);
448 if ($allowUrlFopen || $curlEnabled) {
450 $status->setTitle(
'Fetching external URLs is allowed');
453 $status->setTitle(
'Fetching external URLs is not allowed');
455 'Either enable PHP runtime setting "allow_url_fopen"' . LF .
'or enable curl by setting [SYS][curlUse] accordingly.'
468 $currentMysqliReconnectSetting = ini_get(
'mysqli.reconnect');
469 if ($currentMysqliReconnectSetting ===
'1') {
471 $status->setTitle(
'PHP mysqli.reconnect is enabled');
473 'mysqli.reconnect=1' . LF .
474 'PHP is configured to automatically reconnect the database connection on disconnection.' . LF .
475 ' Warning: If (e.g. during a long-running task) the connection is dropped and automatically reconnected, ' .
476 ' it may not be reinitialized properly (e.g. charset) and write mangled data to the database!'
480 $status->setTitle(
'PHP mysqli.reconnect is fine');
492 $minimumPhpVersion =
'5.6.0';
493 $maximumPhpVersion =
'7.0.0';
494 $currentPhpVersion = phpversion();
495 $currentAlwaysPopulaterRawPostDataSetting = ini_get(
'always_populate_raw_post_data');
496 if (version_compare($currentPhpVersion, $maximumPhpVersion) >= 0) {
498 $status->setTitle(
'PHP always_populate_raw_post_data is removed as of PHP 7.0 or newer');
499 }
elseif (version_compare($currentPhpVersion, $minimumPhpVersion) >= 0 && $currentAlwaysPopulaterRawPostDataSetting !==
'-1') {
501 $status->setTitle(
'PHP always_populate_raw_post_data is deprecated');
503 'always_populate_raw_post_data=' . $currentAlwaysPopulaterRawPostDataSetting . LF .
504 'PHP is configured to automatically populate $HTTP_RAW_POST_DATA.' . LF .
505 ' Warning: Expect fatal errors in central parts of the CMS' .
506 ' if the value is not changed to:' . LF .
507 'always_populate_raw_post_data=-1'
511 $status->setTitle(
'PHP always_populate_raw_post_data is fine');
523 $docRootSetting = trim(ini_get(
'doc_root'));
524 if ($docRootSetting !==
'') {
526 $status->setTitle(
'doc_root is set');
528 'doc_root=' . $docRootSetting . LF .
529 'PHP cannot execute scripts' .
530 ' outside this directory. This setting is seldom used and must correlate' .
531 ' with your actual document root. You might be in trouble if your' .
532 ' TYPO3 CMS core code is linked to some different location.' .
533 ' If that is a problem, the setting must be changed.'
537 $status->setTitle(
'PHP doc_root is not set');
549 $openBaseDirSetting = trim(ini_get(
'open_basedir'));
550 if ($openBaseDirSetting !==
'') {
552 $status->setTitle(
'PHP open_basedir is set');
554 'open_basedir = ' . ini_get(
'open_basedir') . LF .
555 'This restricts TYPO3 to open and include files only in this' .
556 ' path. Please make sure that this does not prevent TYPO3 from running,' .
557 ' if for example your TYPO3 CMS core is linked to a different directory' .
558 ' not included in this path.'
562 $status->setTitle(
'PHP open_basedir is off');
574 if (extension_loaded(
'xdebug')) {
575 $recommendedMaxNestingLevel = 400;
576 $errorThreshold = 250;
577 $currentMaxNestingLevel = ini_get(
'xdebug.max_nesting_level');
578 if ($currentMaxNestingLevel < $errorThreshold) {
580 $status->setTitle(
'PHP xdebug.max_nesting_level is critically low');
582 'xdebug.max_nesting_level=' . $currentMaxNestingLevel . LF .
583 'This setting controls the maximum number of nested function calls to protect against' .
584 ' infinite recursion. The current value is too low for TYPO3 CMS and must' .
585 ' be either raised or xdebug has to be unloaded. A value of ' . $recommendedMaxNestingLevel .
586 ' is recommended. Warning: Expect fatal PHP errors in central parts of the CMS' .
587 ' if the value is not raised significantly to:' . LF .
588 'xdebug.max_nesting_level=' . $recommendedMaxNestingLevel
590 }
elseif ($currentMaxNestingLevel < $recommendedMaxNestingLevel) {
592 $status->setTitle(
'PHP xdebug.max_nesting_level is low');
594 'xdebug.max_nesting_level=' . $currentMaxNestingLevel . LF .
595 'This setting controls the maximum number of nested function calls to protect against' .
596 ' infinite recursion. The current value is high enough for the TYPO3 CMS core to work' .
597 ' fine, but still some extensions could raise fatal PHP errors if the setting is not' .
598 ' raised further. A value of ' . $recommendedMaxNestingLevel .
' is recommended.' . LF .
599 'xdebug.max_nesting_level=' . $recommendedMaxNestingLevel
603 $status->setTitle(
'PHP xdebug.max_nesting_level ok');
607 $status->setTitle(
'PHP xdebug extension not loaded');
619 if (extension_loaded(
'openssl')) {
620 $testKey = @openssl_pkey_new();
621 if (is_resource($testKey)) {
622 openssl_free_key($testKey);
624 $status->setTitle(
'PHP OpenSSL extension installed properly');
627 $status->setTitle(
'PHP OpenSSL extension not working');
629 'Something went wrong while trying to create a new private key for testing.' .
630 ' Please check the integration of the PHP OpenSSL extension and if it is installed correctly.'
635 $status->setTitle(
'PHP OpenSSL extension not loaded');
637 'OpenSSL is a PHP extension to encrypt/decrypt data between requests.' .
638 ' TYPO3 CMS requires it to be able to encrypt stored passwords to improve the security in the' .
653 $recommendedMaxInputVars = 1500;
654 $minimumMaxInputVars = 1000;
655 $currentMaxInputVars = ini_get(
'max_input_vars');
657 if ($currentMaxInputVars < $minimumMaxInputVars) {
659 $status->setTitle(
'PHP max_input_vars too low');
661 'max_input_vars=' . $currentMaxInputVars . LF .
662 'This setting can lead to lost information if submitting forms with lots of data in TYPO3 CMS' .
663 ' (as the install tool does). It is highly recommended to raise this' .
664 ' to at least ' . $recommendedMaxInputVars .
':' . LF .
665 'max_input_vars=' . $recommendedMaxInputVars
667 }
elseif ($currentMaxInputVars < $recommendedMaxInputVars) {
669 $status->setTitle(
'PHP max_input_vars very low');
671 'max_input_vars=' . $currentMaxInputVars . LF .
672 'This setting can lead to lost information if submitting forms with lots of data in TYPO3 CMS' .
673 ' (as the install tool does). It is highly recommended to raise this' .
674 ' to at least ' . $recommendedMaxInputVars .
':' . LF .
675 'max_input_vars=' . $recommendedMaxInputVars
679 $status->setTitle(
'PHP max_input_vars ok');
695 $status->setTitle(
'PHP suhosin extension loaded and active');
698 throw new \BadMethodCallException(
'Should be called only if suhosin extension is loaded', 1422634778);
709 $recommendedRequestMaxVars = 400;
711 $currentRequestMaxVars = ini_get(
'suhosin.request.max_vars');
712 if ($currentRequestMaxVars < $recommendedRequestMaxVars) {
714 $status->setTitle(
'PHP suhosin.request.max_vars too low');
716 'suhosin.request.max_vars=' . $currentRequestMaxVars . LF .
717 'This setting can lead to lost information if submitting forms with lots of data in TYPO3 CMS' .
718 ' (as the install tool does). It is highly recommended to raise this' .
719 ' to at least ' . $recommendedRequestMaxVars .
':' . LF .
720 'suhosin.request.max_vars=' . $recommendedRequestMaxVars
724 $status->setTitle(
'PHP suhosin.request.max_vars ok');
728 $status->setTitle(
'Suhosin not loaded');
730 'If enabling suhosin, suhosin.request.max_vars' .
731 ' should be set to at least ' . $recommendedRequestMaxVars .
':' . LF .
732 'suhosin.request.max_vars=' . $recommendedRequestMaxVars
745 $recommendedRequestMaxVarnameLength = 200;
747 $currentRequestMaxVarnameLength = ini_get(
'suhosin.request.max_varname_length');
748 if ($currentRequestMaxVarnameLength < $recommendedRequestMaxVarnameLength) {
750 $status->setTitle(
'PHP suhosin.request.max_varname_length too low');
752 'suhosin.request.max_varname_length=' . $currentRequestMaxVarnameLength . LF .
753 'This setting can lead to lost information if submitting forms with lots of data in TYPO3 CMS' .
754 ' (as the install tool does). It is highly recommended to raise this' .
755 ' to at least ' . $recommendedRequestMaxVarnameLength .
':' . LF .
756 'suhosin.request.max_varname_length=' . $recommendedRequestMaxVarnameLength
760 $status->setTitle(
'PHP suhosin.request.max_varname_length ok');
764 $status->setTitle(
'Suhosin not loaded');
766 'If enabling suhosin, suhosin.request.max_varname_length' .
767 ' should be set to at least ' . $recommendedRequestMaxVarnameLength .
':' . LF .
768 'suhosin.request.max_varname_length=' . $recommendedRequestMaxVarnameLength
781 $recommendedPostMaxNameLength = 200;
783 $currentPostMaxNameLength = ini_get(
'suhosin.post.max_name_length');
784 if ($currentPostMaxNameLength < $recommendedPostMaxNameLength) {
786 $status->setTitle(
'PHP suhosin.post.max_name_length too low');
788 'suhosin.post.max_name_length=' . $currentPostMaxNameLength . LF .
789 'This setting can lead to lost information if submitting forms with lots of data in TYPO3 CMS' .
790 ' (as the install tool does). It is highly recommended to raise this' .
791 ' to at least ' . $recommendedPostMaxNameLength .
':' . LF .
792 'suhosin.post.max_name_length=' . $recommendedPostMaxNameLength
796 $status->setTitle(
'PHP suhosin.post.max_name_length ok');
800 $status->setTitle(
'Suhosin not loaded');
802 'If enabling suhosin, suhosin.post.max_name_length' .
803 ' should be set to at least ' . $recommendedPostMaxNameLength .
':' . LF .
804 'suhosin.post.max_name_length=' . $recommendedPostMaxNameLength
817 $recommendedPostMaxVars = 400;
819 $currentPostMaxVars = ini_get(
'suhosin.post.max_vars');
820 if ($currentPostMaxVars < $recommendedPostMaxVars) {
822 $status->setTitle(
'PHP suhosin.post.max_vars too low');
824 'suhosin.post.max_vars=' . $currentPostMaxVars . LF .
825 'This setting can lead to lost information if submitting forms with lots of data in TYPO3 CMS' .
826 ' (as the install tool does). It is highly recommended to raise this' .
827 ' to at least ' . $recommendedPostMaxVars .
':' . LF .
828 'suhosin.post.max_vars=' . $recommendedPostMaxVars
832 $status->setTitle(
'PHP suhosin.post.max_vars ok');
836 $status->setTitle(
'Suhosin not loaded');
838 'If enabling suhosin, suhosin.post.max_vars' .
839 ' should be set to at least ' . $recommendedPostMaxVars .
':' . LF .
840 'suhosin.post.max_vars=' . $recommendedPostMaxVars
853 $recommendedGetMaxValueLength = 2000;
855 $currentGetMaxValueLength = ini_get(
'suhosin.get.max_value_length');
856 if ($currentGetMaxValueLength < $recommendedGetMaxValueLength) {
858 $status->setTitle(
'PHP suhosin.get.max_value_length too low');
860 'suhosin.get.max_value_length=' . $currentGetMaxValueLength . LF .
861 'This setting can lead to lost information if submitting forms with lots of data in TYPO3 CMS' .
862 ' (as the install tool does). It is highly recommended to raise this' .
863 ' to at least ' . $recommendedGetMaxValueLength .
':' . LF .
864 'suhosin.get.max_value_length=' . $recommendedGetMaxValueLength
868 $status->setTitle(
'PHP suhosin.get.max_value_length ok');
872 $status->setTitle(
'Suhosin not loaded');
874 'If enabling suhosin, suhosin.get.max_value_length' .
875 ' should be set to at least ' . $recommendedGetMaxValueLength .
':' . LF .
876 'suhosin.get.max_value_length=' . $recommendedGetMaxValueLength
889 $recommendedGetMaxNameLength = 200;
891 $currentGetMaxNameLength = ini_get(
'suhosin.get.max_name_length');
892 if ($currentGetMaxNameLength < $recommendedGetMaxNameLength) {
894 $status->setTitle(
'PHP suhosin.get.max_name_length too low');
896 'suhosin.get.max_name_length=' . $currentGetMaxNameLength . LF .
897 'This setting can lead to lost information if submitting forms with lots of data in TYPO3 CMS' .
898 ' (as the install tool does). It is highly recommended to raise this' .
899 ' to at least ' . $recommendedGetMaxNameLength .
':' . LF .
900 'suhosin.get.max_name_length=' . $recommendedGetMaxNameLength
904 $status->setTitle(
'PHP suhosin.get.max_name_length ok');
908 $status->setTitle(
'Suhosin not loaded');
910 'If enabling suhosin, suhosin.get.max_name_length' .
911 ' should be set to at least ' . $recommendedGetMaxNameLength .
':' . LF .
912 'suhosin.get.max_name_length=' . $recommendedGetMaxNameLength
926 $whitelist = (string)ini_get(
'suhosin.executor.include.whitelist');
927 if (strpos($whitelist,
'phar') ===
false) {
929 $status->setTitle(
'PHP suhosin.executor.include.whitelist does not contain phar');
931 'suhosin.executor.include.whitelist= ' . $whitelist . LF .
932 '"phar" is currently not a hard requirement of TYPO3 CMS but is nice to have and a possible' .
933 ' requirement in future versions. A useful setting is:' . LF .
934 'suhosin.executor.include.whitelist=phar,vfs'
938 $status->setTitle(
'PHP suhosin.executor.include.whitelist contains phar');
942 $status->setTitle(
'Suhosin not loaded');
944 'If enabling suhosin, a useful setting is:' . LF .
945 'suhosin.executor.include.whitelist=phar,vfs'
959 $whitelist = (string)ini_get(
'suhosin.executor.include.whitelist');
960 if (strpos($whitelist,
'vfs') ===
false) {
962 $status->setTitle(
'PHP suhosin.executor.include.whitelist does not contain vfs');
964 'suhosin.executor.include.whitelist= ' . $whitelist . LF .
965 '"vfs" is currently not a hard requirement of TYPO3 CMS but tons of unit tests rely on it.' .
966 ' Furthermore, vfs will likely be a base for an additional compatibility layer in the future.' .
967 ' A useful setting is:' . LF .
968 'suhosin.executor.include.whitelist=phar,vfs'
972 $status->setTitle(
'PHP suhosin.executor.include.whitelist contains vfs');
976 $status->setTitle(
'Suhosin not loaded');
978 'If enabling suhosin, a useful setting is:' . LF .
979 'suhosin.executor.include.whitelist=phar,vfs'
993 $wikiLink =
'For more information take a look in our wiki ' . TYPO3_URL_WIKI_OPCODECACHE .
'.';
995 if (empty($opcodeCaches)) {
998 $status->setTitle(
'No PHP opcode cache loaded');
1000 'PHP opcode caches hold a compiled version of executed PHP scripts in' .
1001 ' memory and do not require to recompile a script each time it is accessed.' .
1002 ' This can be a massive performance improvement and can reduce the load on a' .
1003 ' server in general. A parse time reduction by factor three for fully cached' .
1004 ' pages can be achieved easily if using an opcode cache.' .
1011 foreach ($opcodeCaches as $opcodeCache => $properties) {
1012 $message .=
'Name: ' . $opcodeCache .
' Version: ' . $properties[
'version'];
1015 if ($properties[
'error']) {
1017 if ($status->getSeverity() !==
'error') {
1020 $message .=
' This opcode cache is marked as malfunctioning by the TYPO3 CMS Team.';
1021 }
elseif ($properties[
'canInvalidate']) {
1022 $message .=
' This opcode cache should work correctly and has good performance.';
1025 if ($status->getSeverity() !==
'error' || $status->getSeverity() !==
'warning') {
1028 $message .=
' This opcode cache may work correctly but has medium performance.';
1033 $message .= $wikiLink;
1036 switch ($status->getSeverity()) {
1038 $status->setTitle(
'A possibly malfunctioning PHP opcode cache is loaded');
1041 $status->setTitle(
'A PHP opcode cache is loaded which may cause problems');
1045 $status->setTitle(
'A PHP opcode cache is loaded');
1048 $status->setMessage($message);
1060 $testReflection = new \ReflectionMethod(get_class($this), __FUNCTION__);
1061 if ($testReflection->getDocComment() ===
false) {
1063 $status->setTitle(
'PHP Doc comment reflection broken');
1064 $status->setMessage(
1065 'TYPO3 CMS core extensions like extbase and fluid heavily rely on method'
1066 .
' comment parsing to fetch annotations and add magic belonging to them.'
1067 .
' This does not work in the current environment and so we cannot install'
1068 .
' TYPO3 CMS.' . LF
1069 .
' Here are some possibilities: ' . LF
1070 .
'* In Zend OPcache you can disable saving/loading comments. If you are using'
1071 .
' Zend OPcache (included since PHP 5.5) then check your php.ini settings for'
1072 .
' opcache.save_comments and opcache.load_comments and enable them.' . LF
1073 .
'* In Zend Optimizer+ you can disable saving comments. If you are using'
1074 .
' Zend Optimizer+ then check your php.ini settings for'
1075 .
' zend_optimizerplus.save_comments and enable it.' . LF
1076 .
'* The PHP extension eaccelerator is known to break this if'
1077 .
' it is compiled without --with-eaccelerator-doc-comment-inclusion flag.'
1078 .
' This compile flag must be specified, otherwise TYPO3 CMS will not work.' . LF
1079 .
'For more information take a look in our wiki ' . TYPO3_URL_WIKI_OPCODECACHE .
'.'
1083 $status->setTitle(
'PHP Doc comment reflection works');
1095 $currentLocale = setlocale(LC_CTYPE, 0);
1098 if (
$GLOBALS[
'TYPO3_CONF_VARS'][
'SYS'][
'systemLocale'] ===
'' && TYPO3_OS !==
'WIN') {
1100 $status->setTitle(
'Empty systemLocale setting');
1101 $status->setMessage(
1102 '$GLOBALS[TYPO3_CONF_VARS][SYS][systemLocale] is not set. This is fine as long as no UTF-8' .
1103 ' file system is used.'
1105 }
elseif (setlocale(LC_CTYPE,
$GLOBALS[
'TYPO3_CONF_VARS'][
'SYS'][
'systemLocale']) ===
false) {
1107 $status->setTitle(
'Incorrect systemLocale setting');
1108 $status->setMessage(
1109 'Current value of the $GLOBALS[TYPO3_CONF_VARS][SYS][systemLocale] is incorrect. A locale with' .
1110 ' this name doesn\'t exist in the operating system.'
1112 setlocale(LC_CTYPE, $currentLocale);
1115 $status->setTitle(
'System locale is correct');
1129 if (
$GLOBALS[
'TYPO3_CONF_VARS'][
'SYS'][
'UTF8filesystem']) {
1131 if (
$GLOBALS[
'TYPO3_CONF_VARS'][
'SYS'][
'systemLocale'] ===
'' && TYPO3_OS !==
'WIN') {
1133 $status->setTitle(
'System locale not set on UTF-8 file system');
1134 $status->setMessage(
1135 '$GLOBALS[TYPO3_CONF_VARS][SYS][UTF8filesystem] is set, but $GLOBALS[TYPO3_CONF_VARS][SYS][systemLocale]' .
1136 ' is empty. Make sure a valid locale which supports UTF-8 is set.'
1139 $testString =
'ÖöĄĆŻĘĆćążąęó.jpg';
1140 $currentLocale = setlocale(LC_CTYPE, 0);
1141 $quote = TYPO3_OS ===
'WIN' ?
'"' :
'\'';
1143 setlocale(LC_CTYPE,
$GLOBALS[
'TYPO3_CONF_VARS'][
'SYS'][
'systemLocale']);
1145 if (escapeshellarg($testString) === $quote . $testString . $quote) {
1147 $status->setTitle(
'File names with UTF-8 characters can be used.');
1150 $status->setTitle(
'System locale setting doesn\'t support UTF-8 file names.');
1151 $status->setMessage(
1152 'Please check your $GLOBALS[TYPO3_CONF_VARS][SYS][systemLocale] setting.'
1156 setlocale(LC_CTYPE, $currentLocale);
1160 $status->setTitle(
'Skipping test, as UTF8filesystem is not enabled.');
1174 && substr($_SERVER[
'SERVER_SOFTWARE'], 0, 6) ===
'Apache'
1177 $status->setTitle(
'Windows apache thread stack size');
1178 $status->setMessage(
1179 'This current value cannot be checked by the system, so please ignore this warning if it' .
1180 ' is already taken care of: Fluid uses complex regular expressions which require a lot' .
1181 ' of stack space during the first processing.' .
1182 ' On Windows the default stack size for Apache is a lot smaller than on UNIX.' .
1183 ' You can increase the size to 8MB (default on UNIX) by adding the following configuration' .
1184 ' to httpd.conf and restarting Apache afterwards:' . LF .
1185 '<IfModule mpm_winnt_module>' . LF .
1186 'ThreadStackSize 8388608' . LF .
1191 $status->setTitle(
'Apache ThreadStackSize is not an issue on UNIX systems');
1204 if (!extension_loaded($extension)) {
1206 $status->setTitle(
'PHP extension ' . $extension .
' not loaded');
1207 $status->setMessage(
1208 'TYPO3 CMS uses PHP extension ' . $extension .
' but it is not loaded' .
1209 ' in your environment. Change your environment to provide this extension.'
1213 $status->setTitle(
'PHP extension ' . $extension .
' loaded');
1225 if (function_exists(
'imagecreatetruecolor')) {
1226 $imageResource = @imagecreatetruecolor(50, 100);
1227 if (is_resource($imageResource)) {
1228 imagedestroy($imageResource);
1230 $status->setTitle(
'PHP GD library true color works');
1233 $status->setTitle(
'PHP GD library true color support broken');
1234 $status->setMessage(
1235 'GD is loaded, but calling imagecreatetruecolor() fails.' .
1236 ' This must be fixed, TYPO3 CMS won\'t work well otherwise.'
1241 $status->setTitle(
'PHP GD library true color support missing');
1242 $status->setMessage(
1243 'Gdlib is essential for TYPO3 CMS to work properly.'
1256 if (function_exists(
'imagecreatefromgif')
1257 && function_exists(
'imagegif')
1258 && (imagetypes() & IMG_GIF)
1260 $imageResource = @imagecreatefromgif(__DIR__ .
'/../../Resources/Public/Images/TestInput/Test.gif');
1261 if (is_resource($imageResource)) {
1262 imagedestroy($imageResource);
1264 $status->setTitle(
'PHP GD library has gif support');
1267 $status->setTitle(
'PHP GD library gif support broken');
1268 $status->setMessage(
1269 'GD is loaded, but calling imagecreatefromgif() fails.' .
1270 ' This must be fixed, TYPO3 CMS won\'t work well otherwise.'
1275 $status->setTitle(
'PHP GD library gif support missing');
1276 $status->setMessage(
1277 'GD must be compiled with gif support. This is essential for' .
1278 ' TYPO3 CMS to work properly.'
1291 if (function_exists(
'imagecreatefromjpeg')
1292 && function_exists(
'imagejpeg')
1293 && (imagetypes() & IMG_JPG)
1296 $status->setTitle(
'PHP GD library has jpg support');
1299 $status->setTitle(
'PHP GD library jpg support missing');
1300 $status->setMessage(
1301 'GD must be compiled with jpg support. This is essential for' .
1302 ' TYPO3 CMS to work properly.'
1315 if (function_exists(
'imagecreatefrompng')
1316 && function_exists(
'imagepng')
1317 && (imagetypes() & IMG_PNG)
1319 $imageResource = @imagecreatefrompng(__DIR__ .
'/../../Resources/Public/Images/TestInput/Test.png');
1320 if (is_resource($imageResource)) {
1321 imagedestroy($imageResource);
1323 $status->setTitle(
'PHP GD library has png support');
1326 $status->setTitle(
'PHP GD library png support broken');
1327 $status->setMessage(
1328 'GD is compiled with png support, but calling imagecreatefrompng() fails.' .
1329 ' Check your environment and fix it, png in GD lib is important' .
1330 ' for TYPO3 CMS to work properly.'
1335 $status->setTitle(
'PHP GD library png support missing');
1336 $status->setMessage(
1337 'GD must be compiled with png support. This is essential for' .
1338 ' TYPO3 CMS to work properly'
1351 if (function_exists(
'imagettftext')) {
1353 $status->setTitle(
'PHP GD library has freetype font support');
1354 $status->setMessage(
1355 'There is a difference between the font size setting which the GD' .
1356 ' library should be supplied with. If installation is completed' .
1357 ' a test in the install tool helps to find out the value you need.'
1361 $status->setTitle(
'PHP GD library freetype support missing');
1362 $status->setMessage(
1363 'Some core functionality and extension rely on the GD' .
1364 ' to render fonts on images. This support is missing' .
1365 ' in your environment. Install it.'
1378 if (function_exists(
'imageftbbox')) {
1380 $fontSize = (20 / 96 * 72);
1381 $textDimensions = @imageftbbox(
1384 __DIR__ .
'/../../Resources/Private/Font/vera.ttf',
1385 'Testing true type support'
1387 $fontBoxWidth = $textDimensions[2] - $textDimensions[0];
1388 if ($fontBoxWidth < 300 && $fontBoxWidth > 200) {
1390 $status->setTitle(
'FreeType True Type Font DPI');
1391 $status->setMessage(
'Fonts are rendered by FreeType library. ' .
1392 'We need to ensure that the final dimensions are as expected. ' .
1393 'This server renderes fonts based on 96 DPI correctly');
1396 $status->setTitle(
'FreeType True Type Font DPI');
1397 $status->setMessage(
'Fonts are rendered by FreeType library. ' .
1398 'This server does not render fonts as expected. ' .
1399 'Please check your FreeType 2 module.');
1403 $status->setTitle(
'PHP GD library freetype2 support missing');
1404 $status->setMessage(
1405 'The core relies on GD library compiled into PHP with freetype2' .
1406 ' support. This is missing on your system. Please install it.'
1420 $registerGlobalsEnabled = filter_var(
1421 ini_get(
'register_globals'),
1422 FILTER_VALIDATE_BOOLEAN,
1423 array(FILTER_REQUIRE_SCALAR, FILTER_NULL_ON_FAILURE)
1425 if ($registerGlobalsEnabled ===
true) {
1427 $status->setTitle(
'PHP register globals on');
1428 $status->setMessage(
1429 'register_globals=' . ini_get(
'register_globals') . LF .
1430 'TYPO3 requires PHP setting "register_globals" set to off.' .
1431 ' This ancient PHP setting is a big security problem and should' .
1432 ' never be enabled:' . LF .
1433 'register_globals=Off'
1437 $status->setTitle(
'PHP register globals off');
1449 $sampleArray = array(
'Test>><<Data');
1451 $xmlContent =
'<numIndex index="0">Test>><<Data</numIndex>' . LF;
1453 $xml = \TYPO3\CMS\Core\Utility\GeneralUtility::array2xml($sampleArray,
'', -1);
1455 if ($xmlContent !== $xml) {
1457 $status->setTitle(
'PHP libxml bug present');
1458 $status->setMessage(
1459 'Some hosts have problems saving ">><<" in a flexform.' .
1460 ' To fix this, enable [BE][flexformForceCDATA] in' .
1461 ' All Configuration.'
1465 $status->setTitle(
'PHP libxml bug not present');
1482 return filter_var($ip, FILTER_VALIDATE_IP) !==
false;
1493 if (!stristr(PHP_OS,
'darwin') && stristr(PHP_OS,
'win')) {
1506 $suhosinLoaded =
false;
1507 if (extension_loaded(
'suhosin')) {
1508 $suhosinInSimulationMode = filter_var(
1509 ini_get(
'suhosin.simulation'),
1510 FILTER_VALIDATE_BOOLEAN,
1511 array(FILTER_REQUIRE_SCALAR, FILTER_NULL_ON_FAILURE)
1513 if (!$suhosinInSimulationMode) {
1514 $suhosinLoaded =
true;
1517 return $suhosinLoaded;
1530 $explodedValues = explode($delimiter, $string);
1531 $resultWithPossibleEmptyValues = array_map(
'trim', $explodedValues);
1533 foreach ($resultWithPossibleEmptyValues as $value) {
1534 if ($value !==
'') {
1549 $bytes = doubleval($measurement);
1550 if (stripos($measurement,
'G')) {
1551 $bytes *= 1024 * 1024 * 1024;
1552 }
elseif (stripos($measurement,
'M')) {
1553 $bytes *= 1024 * 1024;
1554 }
elseif (stripos($measurement,
'K')) {