MediaWiki master
PHPVersionCheck.php
Go to the documentation of this file.
1<?php
7// phpcs:disable Generic.Arrays.DisallowLongArraySyntax,PSR2.Classes.PropertyDeclaration,MediaWiki.Usage.DirUsage
8// phpcs:disable Squiz.Scope.MemberVarScope.Missing,Squiz.Scope.MethodScope.Missing
9// phpcs:disable MediaWiki.Usage.StaticClosure.StaticClosure
23 var $mwVersion = '1.46';
24
27 'mb_substr' => 'mbstring',
28 'xml_parser_create' => 'xml',
29 'ctype_digit' => 'ctype',
30 'iconv' => 'iconv',
31 'mime_content_type' => 'fileinfo',
32 'intl_is_failure' => 'intl',
33 );
34
38 var $format = 'text';
39
43 var $scriptPath = '/';
44
50 function setFormat( $format ) {
51 $this->format = $format;
52 }
53
60 $this->scriptPath = $scriptPath;
61 }
62
67 // NOTE: Keep this in sync with composer.json and ScopeStructureTest.php
68 $minimumVersion = '8.2.0';
69
83 $knownBad = array(
84 );
85
86 $passes = version_compare( PHP_VERSION, $minimumVersion, '>=' );
87
88 $versionString = "PHP $minimumVersion or higher";
89
90 // Left as a programmatic check to make it easier to update.
91 if ( count( $knownBad ) ) {
92 $versionString .= ' (and not ' . implode( ', ', array_values( $knownBad ) ) . ')';
93
94 foreach ( $knownBad as $range ) {
95 // As we don't have composer at this point, we have to do our own version range checking.
96 if ( strpos( $range, '-' ) ) {
97 $passes = $passes && !(
98 version_compare( PHP_VERSION, trim( strstr( $range, '-', true ) ), '>=' )
99 && version_compare( PHP_VERSION, trim( substr( strstr( $range, '-', false ), 1 ) ), '<' )
100 );
101 } else {
102 $passes = $passes && version_compare( PHP_VERSION, trim( $range ), '<>' );
103 }
104 }
105 }
106
107 if ( !$passes ) {
108 $cliText = "Error: You are using an unsupported PHP version (PHP " . PHP_VERSION . ").\n"
109 . "MediaWiki $this->mwVersion needs $versionString.\n\nCheck if you might have a newer "
110 . "PHP executable with a different name.\n\n";
111
112 $web = array();
113 $web['intro'] = "MediaWiki $this->mwVersion requires $versionString; you are using PHP "
114 . PHP_VERSION . ".";
115
116 $web['longTitle'] = "Supported PHP versions";
117 // phpcs:disable Generic.Files.LineLength
118 $web['longHtml'] = <<<HTML
119 <p>
120 Please consider <a href="https://www.php.net/downloads.php">upgrading your copy of PHP</a>.
121 PHP versions less than v8.2.0 are no longer <a href="https://www.php.net/supported-versions.php">supported</a>
122 by the PHP Group and will not receive security or bugfix updates.
123 </p>
124 <p>
125 If for some reason you are unable to upgrade your PHP version, you will need to
126 <a href="https://www.mediawiki.org/wiki/Download">download</a> an older version of
127 MediaWiki from our website. See our
128 <a href="https://www.mediawiki.org/wiki/Compatibility#PHP">compatibility page</a>
129 for details of which versions are compatible with prior versions of PHP.
130 </p>
131HTML;
132 // phpcs:enable Generic.Files.LineLength
133 $this->triggerError(
134 $web,
135 $cliText
136 );
137 }
138 }
139
144 if ( !file_exists( dirname( __FILE__ ) . '/../vendor/autoload.php' ) ) {
145 $cliText = "Error: You are missing some dependencies. \n"
146 . "MediaWiki has dependencies that need to be installed via Composer\n"
147 . "or from a separate repository. Please see\n"
148 . "https://www.mediawiki.org/wiki/Download_from_Git#Fetch_external_libraries\n"
149 . "for help with installing them.";
150
151 $web = array();
152 $web['intro'] = "Installing some dependencies is required.";
153 $web['longTitle'] = 'Dependencies';
154 // phpcs:disable Generic.Files.LineLength
155 $web['longHtml'] = <<<HTML
156 <p>
157 MediaWiki has dependencies that need to be installed via Composer
158 or from a separate repository. Please see the
159 <a href="https://www.mediawiki.org/wiki/Download_from_Git#Fetch_external_libraries">instructions
160 for installing external libraries</a> on MediaWiki.org.
161 </p>
162HTML;
163 // phpcs:enable Generic.Files.LineLength
164
165 $this->triggerError( $web, $cliText );
166 }
167 }
168
173 $missingExtensions = array();
174 foreach ( $this->functionsExtensionsMapping as $function => $extension ) {
175 if ( !function_exists( $function ) ) {
176 $missingExtensions[] = array( $extension );
177 }
178 }
179
180 // Special case: either of those is required, but only on 32-bit systems (T391169)
181 if ( PHP_INT_SIZE < 8 && !extension_loaded( 'gmp' ) && !extension_loaded( 'bcmath' ) ) {
182 $missingExtensions[] = array( 'bcmath', 'gmp' );
183 }
184
185 if ( $missingExtensions ) {
186 $missingExtText = '';
187 $missingExtHtml = '';
188 $baseUrl = 'https://www.php.net';
189 foreach ( $missingExtensions as $extNames ) {
190 $plaintextLinks = array();
191 $htmlLinks = array();
192 foreach ( $extNames as $ext ) {
193 $plaintextLinks[] = "$ext <$baseUrl/$ext>";
194 $htmlLinks[] = "<b>$ext</b> (<a href=\"$baseUrl/$ext\">more information</a>)";
195 }
196
197 $missingExtText .= ' * ' . implode( ' or ', $plaintextLinks ) . "\n";
198 $missingExtHtml .= "<li>" . implode( ' or ', $htmlLinks ) . "</li>";
199 }
200
201 $cliText = "Error: Missing one or more required PHP extensions. Please see\n"
202 . "https://www.mediawiki.org/wiki/Manual:Installation_requirements#PHP\n"
203 . "for help with installing them.\n"
204 . "Please install or enable:\n" . $missingExtText;
205
206 $web = array();
207 $web['intro'] = "Installing some PHP extensions is required.";
208 $web['longTitle'] = 'Required PHP extensions';
209 $web['longHtml'] = <<<HTML
210 <p>
211 You are missing one or more extensions to PHP that MediaWiki requires to run. Please see the
212 <a href="https://www.mediawiki.org/wiki/Manual:Installation_requirements#PHP">PHP
213 installation requirements</a> on MediaWiki.org.
214 </p>
215 <p>Please install or enable:</p>
216 <ul>
217 $missingExtHtml
218 </ul>
219HTML;
220
221 $this->triggerError( $web, $cliText );
222 }
223 }
224
228 function outputHTMLHeader() {
229 $protocol = isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0';
230
231 header( "$protocol 500 MediaWiki configuration Error" );
232 // Don't cache error pages! They cause no end of trouble...
233 header( 'Cache-Control: no-cache' );
234 }
235
244 function getIndexErrorOutput( $introText, $longTitle, $longHtml ) {
245 $encLogo =
246 htmlspecialchars( str_replace( '//', '/', $this->scriptPath . '/' ) .
247 'resources/assets/mediawiki.png' );
248
249 $introHtml = htmlspecialchars( $introText );
250 $longTitleHtml = htmlspecialchars( $longTitle );
251
252 header( 'Content-type: text/html; charset=UTF-8' );
253
254 $finalOutput = <<<HTML
255<!DOCTYPE html>
256<html lang="en" dir="ltr">
257 <head>
258 <meta charset="UTF-8" />
259 <title>MediaWiki {$this->mwVersion}</title>
260 <style media="screen">
261 body {
262 color: #000;
263 background-color: #fff;
264 font-family: sans-serif;
265 padding: 2em;
266 text-align: center;
267 }
268 p, img, h1, h2, ul {
269 text-align: left;
270 margin: 0.5em 0 1em;
271 }
272 h1 {
273 font-size: 120%;
274 }
275 h2 {
276 font-size: 110%;
277 }
278 </style>
279 </head>
280 <body>
281 <img src="{$encLogo}" alt="The MediaWiki logo" />
282 <h1>MediaWiki {$this->mwVersion} internal error</h1>
283 <p>
284 {$introHtml}
285 </p>
286 <h2>{$longTitleHtml}</h2>
287 {$longHtml}
288 </body>
289</html>
290HTML;
291
292 return $finalOutput;
293 }
294
309 function triggerError( $web, $cliText ) {
310 if ( $this->format === 'html' ) {
311 // Used by index.php and mw-config/index.php
312 $this->outputHTMLHeader();
313 $finalOutput = $this->getIndexErrorOutput(
314 $web['intro'],
315 $web['longTitle'],
316 $web['longHtml']
317 );
318 } else {
319 // Used by Maintenance.php (CLI)
320 $finalOutput = $cliText;
321 }
322
323 echo "$finalOutput\n";
324 die( 1 );
325 }
326}
327
335function wfEntryPointCheck( $format = 'text', $scriptPath = '/' ) {
336 $phpVersionCheck = new PHPVersionCheck();
337 $phpVersionCheck->setFormat( $format );
338 $phpVersionCheck->setScriptPath( $scriptPath );
339 $phpVersionCheck->checkRequiredPHPVersion();
340 $phpVersionCheck->checkVendorExistence();
341 $phpVersionCheck->checkExtensionExistence();
342}
wfEntryPointCheck( $format='text', $scriptPath='/')
Check PHP version and that external dependencies are installed, and display an informative error if e...
Check PHP Version, as well as for composer dependencies in entry points, and display something vaguel...
setFormat( $format)
Set the format used for errors.
string $mwVersion
The number of the MediaWiki version used.
outputHTMLHeader()
Output headers that prevents error pages to be cached.
setScriptPath( $scriptPath)
Set the script path used for images in HTML-formatted errors.
triggerError( $web, $cliText)
Display something vaguely comprehensible in the event of a totally unrecoverable error.
getIndexErrorOutput( $introText, $longTitle, $longHtml)
Returns an error page, which is suitable for output to the end user via a web browser.
checkExtensionExistence()
Displays an error, if a PHP extension does not exist.
checkRequiredPHPVersion()
Displays an error, if the installed PHP version does not meet the minimum requirement.
string[] $functionsExtensionsMapping
A mapping of PHP functions to PHP extensions.
checkVendorExistence()
Displays an error, if the vendor/autoload.php file could not be found.
string $format
The format used for errors.
Helper trait for implementations \DAO.