1<?php 2/* 3 4 This script handles all 401, 403 and 404 error redirects, 5 and some directory requests (like /images). Uses the 6 preferred language setting and the REQUEST_URI to guess what 7 page should be displayed. In case there is no page that can 8 be displayed, the user is redirected to a search page. 9 10*/ 11 12use phpweb\I18n\Languages; 13use phpweb\UserPreferences; 14 15// Ensure that our environment is set up 16include_once __DIR__ . '/include/prepend.inc'; 17include_once __DIR__ . '/include/errors.inc'; 18 19// Get URI for this request, strip leading slash 20// See langchooser.inc for more info on STRIPPED_URI 21$URI = substr($_SERVER['STRIPPED_URI'], 1); 22 23// ============================================================================ 24// Mozilla Search Sidebar plugin resource file handling (need to be mirror 25// dependent, so the search results will show up in the sidebar) 26if ($URI == 'phpnetsearch.src') { 27 status_header(200); 28 include_once __DIR__ . '/include/mozsearch.inc'; 29 exit; 30} 31// FIXME: Nuke the old firefox search plugin 32if ($URI == 'phpnetimprovedsearch.src') { 33 status_header(200); 34 include_once __DIR__ . '/include/mozopensearch.inc'; 35 exit; 36} 37 38// ============================================================================ 39// BC: handle bugs.php moved completely to bugs.php.net 40if (preg_match("!^bugs.php\\?(.+)$!", $URI, $array)) { 41 mirror_redirect("https://bugs.php.net/?$array[1]"); 42} 43 44// ============================================================================ 45// FC: handle advisories 46if (preg_match("!^security/advisories/PHPSA-(\\d+)\\.php$!", $URI, $array)) { 47 status_header(200); 48 $_GET["id"] = $array[1]; 49 include_once __DIR__ . '/security/index.php'; 50 exit; 51} 52 53// ============================================================================ 54// Omit query string from URL and urldecode special chars 55$URI = urldecode(preg_replace("!(\\?.*$)!", "", $URI)); 56 57// ============================================================================ 58// An empty URI is useless at this point, so let's give them the search page 59if (empty($URI)) { 60 mirror_redirect("/search.php"); 61} 62 63// ============================================================================ 64// Perform a redirect for manual figures, other images display a 404 automatically 65if (preg_match("!^manual/(\\w+)/(print|printwn)/figures/(.+)$!", $URI, $parts)) { 66 mirror_redirect("/manual/$parts[1]/figures/$parts[3]"); 67} elseif (preg_match("!\\.(pdf|gif|jpg|png)$!i", $URI)) { 68 error_404(); 69} 70 71// ============================================================================ 72// BC: handle .php3 files that were renamed to .php 73if (preg_match("!(.*\\.php)3$!", $URI, $array)) { 74 mirror_redirect("/$array[1]"); 75} 76 77// ============================================================================ 78// BC: handle moving english manual down into its own directory (also supports 79// default language manual accessibility on mirror sites through /manual/filename) 80// @todo do we rely on this? how about removing it... 81if (preg_match("!^manual/([^/]*)$!", $URI, $array)) { 82 if (!isset(Languages::INACTIVE_ONLINE_LANGUAGES[$array[1]])) { 83 mirror_redirect("/manual/$LANG/$array[1]"); 84 } 85} elseif (preg_match("!^manual/html/([^/]+)$!", $URI, $array)) { 86 $array[1] = preg_replace("!.html$!", ".php", $array[1]); 87 mirror_redirect("/manual/$LANG/$array[1]"); 88} 89 90// ============================================================================ 91// BC: News archive moved to subfolder 92if (preg_match("!^news-(\\d+)(\\.|$)!", $URI, $array)) { 93 mirror_redirect("/archive/$array[1].php"); 94} 95 96// ============================================================================ 97// BC: Release files moved to subfolder 98if (preg_match("!^release_([^\\.]+)(\\.php$|$)!", $URI, $array)) { 99 mirror_redirect("/releases/$array[1].php"); 100} 101 102// ============================================================================ 103// BC: Printer friendly manual page handling was separate previously, but we 104// only need to redirect the old URLs now. Our pages are now printer friendly 105// by design. 106if (preg_match("!^manual/(\\w+)/(print|printwn|html)((/.+)|$)!", $URI, $array)) { 107 $array[3] = preg_replace("!.html$!", ".php", $array[3]); 108 mirror_redirect("/manual/$array[1]$array[3]"); 109} 110 111// ============================================================================ 112// If someone is looking for something in distributions/* and it isn't there, 113// send them to the /releases page since that is likely to be most helpful. 114if (preg_match("!^distributions/.*!", $URI, $array)) { 115 status_header(404); 116 include_once __DIR__ . "/releases/index.php"; 117} 118 119// ============================================================================ 120// The trailing slash only causes problems from now on 121$URI = rtrim($URI, '/'); 122 123// ============================================================================ 124// Some nice URLs for getting something for download 125if (preg_match("!^get/([^/]+)$!", $URI, $what)) { 126 switch ($what[1]) { 127 case "php": 128 $URI = "downloads"; 129 break; 130 case "docs": // intentional 131 case "documentation": 132 $URI = "download-docs"; 133 break; 134 } 135} 136 137// ============================================================================ 138// Nice URLs for download files, so wget works completely well with download links 139if (preg_match("!^get/([^/]+)/from/([^/]+)(/mirror)?$!", $URI, $dlinfo)) { 140 141 $df = $dlinfo[1]; 142 if (strpos($df, "7-LATEST") !== false) { 143 include_once __DIR__ . "/include/version.inc"; 144 [$latest] = release_get_latest(); 145 $df = str_replace("7-LATEST", $latest, $df); 146 } 147 148 $mr = "https://www.php.net/"; 149 150 // Check if that mirror really exists if not, bail out 151 if (!isset($MIRRORS[$mr])) { 152 error_nomirror($mr); 153 exit; 154 } 155 156 // Start the download process 157 include __DIR__ . "/include/do-download.inc"; 158 $filename = get_actual_download_file($df); 159 if ($filename) { 160 status_header(200); 161 download_file($mr, $filename); 162 } else { 163 status_header(404); 164 /* The file didn't exist on this server.. ask the user to pick another mirror */ 165 include __DIR__ . "/include/get-download.inc"; 166 } 167 exit; 168} 169 170// php.net/42 --> likely a bug number 171if (is_numeric($URI)) { 172 mirror_redirect("http://bugs.php.net/bug.php?id=$URI"); 173} 174 175// php.net/GH-123 -> php-src GH issue #123 176if (preg_match('/^GH-(\d+)$/', $URI, $matches)) { 177 mirror_redirect("https://github.com/php/php-src/issues/" . $matches[1]); 178} 179 180// php.net/supported-versions.PHP -> supported-versions.php 181if ($URI == 'supported-versions.PHP') { 182 mirror_redirect("https://www.php.net/supported-versions.php"); 183} 184 185 186// ============================================================================ 187// Redirect if the entered URI was a PHP page name (except some pages, 188// which we display in the mirror's language or the explicitly specified 189// language [see below]) 190if (!in_array($URI, ['mirror-info', 'error', 'mod'], true) && 191 file_exists($_SERVER['DOCUMENT_ROOT'] . "/$URI.php")) { 192 mirror_redirect("/$URI.php"); 193} 194 195// Work with lowercased URI from now 196$URI = strtolower($URI); 197 198// Redirection hack, see error.inc for detailed description 199// These expect -foo not _foo 200$term = str_replace('_', '-', $URI); 201 202if ($path = is_known_ini($term)) { 203 status_header(301); 204 mirror_redirect("/manual/$LANG/$path"); 205 exit; 206} 207if ($path = is_known_variable($term)) { 208 status_header(301); 209 mirror_redirect("/manual/$LANG/$path"); 210 exit; 211} 212if ($path = is_known_term($term)) { 213 status_header(301); 214 mirror_redirect("/manual/$LANG/$path"); 215 exit; 216} 217 218// ============================================================================ 219// Major manual page modifications (need to handle shortcuts and pages in all languages) 220// Used permanent HTTP redirects, so search engines will be able to pick up the correct 221// new URLs for these pages. 222$manual_page_moves = [ 223 // entry point changed 224 'installation' => 'install', 225 226 // was split among platforms (don't know where to redirect) 227 'install.apache' => 'install', 228 'install.apache2' => 'install', 229 'install.netscape-enterprise' => 'install', 230 'install.otherhttpd' => 'install', 231 232 // moved to platform sections 233 'install.caudium' => 'install.unix.caudium', 234 'install.commandline' => 'install.unix.commandline', 235 'install.fhttpd' => 'install.unix.fhttpd', 236 'install.hpux' => 'install.unix.hpux', 237 'install.iis' => 'install.windows.iis', 238 'install.linux' => 'install.unix', 239 'install.omnihttpd' => 'install.windows.omnihttpd', 240 'install.openbsd' => 'install.unix.openbsd', 241 'install.sambar' => 'install.windows.sambar', 242 'install.solaris' => 'install.unix.solaris', 243 'install.xitami' => 'install.windows.xitami', 244 'install.windows.installer.msi' => 'install.windows', 245 'install.windows.installer' => 'install.windows', 246 247 // Internals docs where moved 248 'zend' => 'internals2.ze1.zendapi', 249 'zend-api' => 'internals2.ze1.zendapi', 250 'internals.pdo' => 'internals2.pdo', 251 'phpdevel' => 'internals2.ze1.php3devel', 252 'tsrm' => 'internals2.ze1.tsrm', 253 254 // Replaced extensions 255 'aspell' => 'pspell', 256 257 // Refactored 258 'regexp.reference' => 'regexp.introduction', 259 "security" => "manual/security", 260 261 // MongoDB converted from set to book 262 'set.mongodb' => 'book.mongodb', 263 'mongodb.installation.homebrew' => 'mongodb.installation#mongodb.installation.homebrew', 264 'mongodb.installation.manual' => 'mongodb.installation#mongodb.installation.manual', 265 'mongodb.installation.pecl' => 'mongodb.installation#mongodb.installation.pecl', 266 'mongodb.installation.windows' => 'mongodb.installation#mongodb.installation.windows', 267 'mongodb.persistence.deserialization' => 'mongodb.persistence#mongodb.persistence.deserialization', 268 'mongodb.persistence.serialization' => 'mongodb.persistence#mongodb.persistence.serialization', 269]; 270 271if (isset($manual_page_moves[$URI])) { 272 status_header(301); 273 mirror_redirect("/" . $manual_page_moves[$URI]); 274} elseif (preg_match("!^manual/([^/]+)/([^/]+).php$!", $URI, $match) && 275 isset($manual_page_moves[$match[2]])) { 276 status_header(301); 277 278 $parts = explode('#', $manual_page_moves[$match[2]], 2); 279 if (count($parts) === 1) { 280 mirror_redirect("/manual/{$match[1]}/{$parts[0]}.php"); 281 } else { 282 mirror_redirect("/manual/{$match[1]}/{$parts[0]}.php#{$parts[1]}"); 283 } 284} 285 286$manual_redirections = [ 287 'class.oci-lob' => 'class.ocilob', 288 'oci-lob.append' => 'ocilob.append', 289 'oci-lob.close' => 'ocilob.close', 290 'oci-lob.eof' => 'ocilob.eof', 291 'oci-lob.erase' => 'ocilob.erase', 292 'oci-lob.export' => 'ocilob.export', 293 'oci-lob.flush' => 'ocilob.flush', 294 'oci-lob.free' => 'ocilob.free', 295 'oci-lob.getbuffering' => 'ocilob.getbuffering', 296 'oci-lob.import' => 'ocilob.import', 297 'oci-lob.load' => 'ocilob.load', 298 'oci-lob.read' => 'ocilob.read', 299 'oci-lob.rewind' => 'ocilob.rewind', 300 'oci-lob.save' => 'ocilob.save', 301 'oci-lob.seek' => 'ocilob.seek', 302 'oci-lob.setbuffering' => 'ocilob.setbuffering', 303 'oci-lob.size' => 'ocilob.size', 304 'oci-lob.tell' => 'ocilob.tell', 305 'oci-lob.truncate' => 'ocilob.truncate', 306 'oci-lob.write' => 'ocilob.write', 307 'oci-lob.writetemporary' => 'ocilob.writetemporary', 308 'class.oci-collection' => 'class.ocicollection', 309 'oci-collection.append' => 'ocicollection.append', 310 'oci-collection.assign' => 'ocicollection.assign', 311 'oci-collection.assignelem' => 'ocicollection.assignelem', 312 'oci-collection.free' => 'ocicollection.free', 313 'oci-collection.getelem' => 'ocicollection.getelem', 314 'oci-collection.max' => 'ocicollection.max', 315 'oci-collection.size' => 'ocicollection.size', 316 'oci-collection.trim' => 'ocicollection.trim', 317 'splstack.setiteratormode' => 'spldoublylinkedlist.setiteratormode', 318 'splqueue.setiteratormode' => 'spldoublylinkedlist.setiteratormode', 319 'class.allow-dynamic-properties' => 'class.allowdynamicproperties', 320 'class.return-type-will-change' => 'class.returntypewillchange', 321 'class.sensitive-parameter' => 'class.sensitiveparameter', 322 'function.curl-file-create' => 'curlfile.construct', 323 'simplexmliterator.current' => 'simplexmlelement.current', 324 'simplexmliterator.getchildren' => 'simplexmlelement.getchildren', 325 'simplexmliterator.haschildren' => 'simplexmlelement.haschildren', 326 'simplexmliterator.key' => 'simplexmlelement.key', 327 'simplexmliterator.next' => 'simplexmlelement.next', 328 'simplexmliterator.rewind' => 'simplexmlelement.rewind', 329 'simplexmliterator.valid' => 'simplexmlelement.valid', 330]; 331 332if (preg_match("!^manual/([^/]+)/([^/]+?)(?:\.php)?$!", $URI, $match) && isset($manual_redirections[$match[2]])) { 333 status_header(301); 334 mirror_redirect("/manual/$match[1]/" . $manual_redirections[$match[2]]); 335} 336 337// ============================================================================ 338// Define shortcuts for PHP files, manual pages and external redirects 339$uri_aliases = [ 340 341 # PHP page shortcuts 342 "download" => "downloads", 343 "getphp" => "downloads", 344 "getdocs" => "download-docs", 345 "documentation" => "docs", 346 "mailinglists" => "mailing-lists", 347 "mailinglist" => "mailing-lists", 348 "changelog" => "ChangeLog-8", 349 "gethelp" => "support", 350 "help" => "support", 351 "unsubscribe" => "unsub", 352 "subscribe" => "mailing-lists", 353 "logos" => "download-logos", 354 355 # manual shortcuts 356 "intro" => "introduction", 357 "whatis" => "introduction", 358 "whatisphp" => "introduction", 359 "what_is_php" => "introduction", 360 361 "windows" => "install.windows", 362 "win32" => "install.windows", 363 364 "globals" => "language.variables.predefined", 365 "register_globals" => "security.globals", 366 "registerglobals" => "security.globals", 367 "manual/en/security.registerglobals.php" => "security.globals", // fix for 4.3.8 configure 368 "magic_quotes" => "security.magicquotes", 369 "magicquotes" => "security.magicquotes", 370 "gd" => "image", 371 "bcmath" => "bc", 372 'streams' => 'book.stream', 373 "mongodb" => "book.mongodb", 374 "hrtime" => "function.hrtime", // Prefer function over PECL ext 375 376 "callback" => "language.pseudo-types", 377 "number" => "language.pseudo-types", 378 "mixed" => "language.pseudo-types", 379 "bool" => "language.types.boolean", 380 "boolean" => "language.types.boolean", 381 "int" => "language.types.integer", 382 "integer" => "language.types.integer", 383 "float" => "language.types.float", 384 "string" => "language.types.string", 385 "heredoc" => "language.types.string", 386 "<<<" => "language.types.string", 387 "object" => "language.types.object", 388 "null" => "language.types.null", 389 'callable' => 'language.types.callable', 390 391 "htaccess" => "configuration.changes", 392 "php_value" => "configuration.changes", 393 394 "ternary" => "language.operators.comparison", 395 "instanceof" => "language.operators.type", 396 "if" => "language.control-structures", 397 "static" => "language.variables.scope", 398 "global" => "language.variables.scope", 399 "@" => "language.operators.errorcontrol", 400 "&" => "language.references", 401 "**" => "language.operators.arithmetic", 402 "..." => "functions.arguments", 403 "splat" => "functions.arguments", 404 "arrow" => "functions.arrow", 405 "fn" => "functions.arrow", 406 // ?:, ??, ??= 407 // These shortcuts can not be captured here since they 408 // don't actually produce a 404 error. 409 // Instead, we have a small check in index.php directly. 410 411 "dowhile" => "control-structures.do.while", 412 413 "tut" => "tutorial", 414 "tut.php" => "tutorial", // BC 415 416 "faq.php" => "faq", // BC 417 "bugs.php" => "bugs", // BC 418 "bugstats.php" => "bugstats", // BC 419 "docs-echm.php" => "download-docs", // BC 420 421 "odbc" => "uodbc", // BC 422 423 "links" => "support", // BC 424 "links.php" => "support", // BC 425 "oracle" => "oci8", 426 "cli" => "features.commandline", 427 428 "oop" => "language.oop5", 429 "enum" => "language.enumerations", 430 "enums" => "language.enumerations", 431 432 "const" => "language.constants.syntax", 433 "class" => "language.oop5.basic", 434 "new" => "language.oop5.basic", 435 "extends" => "language.oop5.basic", 436 "clone" => "language.oop5.cloning", 437 "construct" => "language.oop5.decon", 438 "destruct" => "language.oop5.decon", 439 "public" => "language.oop5.visibility", 440 "private" => "language.oop5.visibility", 441 "protected" => "language.oop5.visibility", 442 "var" => "language.oop5.visibility", 443 "abstract" => "language.oop5.abstract", 444 "interface" => "language.oop5.interfaces", 445 "interfaces" => "language.oop5.interfaces", 446 "autoload" => "language.oop5.autoload", 447 "__autoload" => "language.oop5.autoload", 448 "language.oop5.reflection" => "book.reflection", // BC 449 "::" => "language.oop5.paamayim-nekudotayim", 450 451 "__construct" => "language.oop5.decon", 452 "__destruct" => "language.oop5.decon", 453 "__call" => "language.oop5.overloading", 454 "__callstatic" => "language.oop5.overloading", 455 "__get" => "language.oop5.overloading", 456 "__set" => "language.oop5.overloading", 457 "__isset" => "language.oop5.overloading", 458 "__unset" => "language.oop5.overloading", 459 "__sleep" => "language.oop5.magic", 460 "__wakeup" => "language.oop5.magic", 461 "__tostring" => "language.oop5.magic", 462 "__invoke" => "language.oop5.magic", 463 "__set_state" => "language.oop5.magic", 464 "__debuginfo" => "language.oop5.magic", 465 "__clone" => "language.oop5.cloning", 466 467 "throw" => "language.exceptions", 468 "try" => "language.exceptions", 469 "catch" => "language.exceptions", 470 "lsb" => "language.oop5.late-static-bindings", 471 "namespace" => "language.namespaces", 472 "use" => "language.namespaces.using", 473 474 "factory" => "language.oop5.patterns", 475 "singleton" => "language.oop5.patterns", 476 477 "trait" => "language.oop5.traits", 478 "traits" => "language.oop5.traits", 479 480 "news.php" => "archive/index", // BC 481 "readme.mirror" => "mirroring", // BC 482 483 "php5" => "language.oop5", 484 "zend_changes.txt" => "language.oop5", // BC 485 "zend2_example.phps" => "language.oop5", // BC 486 "zend_changes_php_5_0_0b2.txt" => "language.oop5", // BC 487 "zend-engine-2" => "language.oop5", // BC 488 "zend-engine-2.php" => "language.oop5", // BC 489 490 "news_php_5_0_0b2.txt" => "ChangeLog-5", // BC 491 "news_php_5_0_0b3.txt" => "ChangeLog-5", // BC 492 493 "manual/about-notes.php" => "manual/add-note", // BC 494 "software/index.php" => "software", // BC 495 "releases.php" => "releases/index", // BC 496 497 "migration7" => "migration70", // Consistent with migration5 498 "update_5_2.txt" => "migration52", // BC 499 "readme_upgrade_51.php" => "migration51", // BC 500 "internals" => "internals2", // BC 501 "configuration.directives" => "ini.core", // BC 502 503 # regexp. BC 504 "regexp.reference.backslash" => "regexp.reference.escape", 505 "regexp.reference.circudollar" => "regexp.reference.anchors", 506 "regexp.reference.squarebrackets" => "regexp.reference.character-classes", 507 "regexp.reference.verticalbar" => "regexp.reference.alternation", 508 509 # external shortcut aliases ;) 510 "dochowto" => "phpdochowto", 511 512 # CVS -> SVN 513 "anoncvs.php" => "git", 514 "cvs-php.php" => "git-php", 515 516 # SVN -> Git 517 "svn" => "git", 518 "svn.php" => "git", 519 "svn-php" => "git-php", 520 "svn-php.php" => "git-php", 521 522 # CVSUp -> Nada 523 "cvsup" => "mirroring", 524 525 # Other items 526 "security/crypt" => "security/crypt_blowfish", 527 528 # Bugfixes 529 "array_sort" => "sort", // #64743 530 "array-sort" => "sort", // #64743 531 532 # Removed pages 533 "tips.php" => "urlhowto", 534 "tips" => "urlhowto", 535]; 536 537$external_redirects = [ 538 "php4news" => "https://github.com/php/php-src/raw/PHP-4.4/NEWS", 539 "php5news" => "https://github.com/php/php-src/raw/PHP-5.6/NEWS", 540 "php53news" => "https://github.com/php/php-src/raw/PHP-5.3/NEWS", 541 "php54news" => "https://github.com/php/php-src/raw/PHP-5.4/NEWS", 542 "php55news" => "https://github.com/php/php-src/raw/PHP-5.5/NEWS", 543 "php56news" => "https://github.com/php/php-src/raw/PHP-5.6/NEWS", 544 "php70news" => "https://github.com/php/php-src/raw/PHP-7.0/NEWS", 545 "php71news" => "https://github.com/php/php-src/raw/PHP-7.1/NEWS", 546 "php72news" => "https://github.com/php/php-src/raw/PHP-7.2/NEWS", 547 "php73news" => "https://github.com/php/php-src/raw/PHP-7.3/NEWS", 548 "php74news" => "https://github.com/php/php-src/raw/PHP-7.4/NEWS", 549 "php80news" => "https://github.com/php/php-src/raw/PHP-8.0/NEWS", 550 "phptrunknews" => "https://github.com/php/php-src/raw/master/NEWS", 551 "pear" => "http://pear.php.net/", 552 "bugs" => "https://bugs.php.net/", 553 "bugstats" => "https://bugs.php.net/stats.php", 554 "phpdochowto" => "https://doc.php.net/guide/", 555 "rev" => "https://doc.php.net/revcheck.php?p=graph&lang=$LANG", 556 "release/5_3_0.php" => "/releases/5_3_0.php", // PHP 5.3.0 release announcement had a typo 557 "ideas.php" => "http://wiki.php.net/ideas", // BC 558 "releases.atom" => "/releases/feed.php", // BC, No need to pre-generate it 559 "spec" => "https://github.com/php/php-langspec", 560 "sunglasses" => "https://www.youtube.com/watch?v=dQw4w9WgXcQ", // Temporary easter egg for bug#66144 561]; 562 563// Temporary hack to fix bug #49956 for mysqli -- Please don't hate me for this. Data taken from mysqli/summary.xml 564$mysqli_redirects = [ 565 "mysqli_affected_rows" => "mysqli.affected-rows", 566 "mysqli_get_client_version" => "mysqli.client-version", 567 "mysqli_connect_errno" => "mysqli.connect-errno", 568 "mysqli_connect_error" => "mysqli.connect-error", 569 "mysqli_errno" => "mysqli.errno", 570 "mysqli_error" => "mysqli.error", 571 "mysqli_field_count" => "mysqli.field-count", 572 "mysqli_get_host_info" => "mysqli.host-info", 573 "mysqli_get_proto_info" => "mysqli.protocol-version", 574 "mysqli_get_server_version" => "mysqli.server-version", 575 "mysqli_info" => "mysqli.info", 576 "mysqli_insert_id" => "mysqli.insert-id", 577 "mysqli_sqlstate" => "mysqli.sqlstate", 578 "mysqli_warning_count" => "mysqli.warning-count", 579 "mysqli_autocommit" => "mysqli.autocommit", 580 "mysqli_change_user" => "mysqli.change-user", 581 "mysqli_character_set_name" => "mysqli.character-set-name", 582 "mysqli_close" => "mysqli.close", 583 "mysqli_commit" => "mysqli.commit", 584 "mysqli_connect" => "mysqli.construct", 585 "mysqli_debug" => "mysqli.debug", 586 "mysqli_dump_debug_info" => "mysqli.dump-debug-info", 587 "mysqli_get_charset" => "mysqli.get-charset", 588 "mysqli_get_connection_stats" => "mysqli.get-connection-stats", 589 "mysqli_get_client_info" => "mysqli.get-client-info", 590 "mysqli_get_client_stats" => "mysqli.get-client-stats", 591 "mysqli_get_cache_stats" => "mysqli.get-cache-stats", 592 "mysqli_get_server_info" => "mysqli.get-server-info", 593 "mysqli_get_warnings" => "mysqli.get-warnings", 594 "mysqli_init" => "mysqli.init", 595 "mysqli_kill" => "mysqli.kill", 596 "mysqli_more_results" => "mysqli.more-results", 597 "mysqli_multi_query" => "mysqli.multi-query", 598 "mysqli_next_result" => "mysqli.next-result", 599 "mysqli_options" => "mysqli.options", 600 "mysqli_ping" => "mysqli.ping", 601 "mysqli_prepare" => "mysqli.prepare", 602 "mysqli_query" => "mysqli.query", 603 "mysqli_real_connect" => "mysqli.real-connect", 604 "mysqli_real_escape_string" => "mysqli.real-escape-string", 605 "mysqli_real_query" => "mysqli.real-query", 606 "mysqli_refresh" => "mysqli.refresh", 607 "mysqli_rollback" => "mysqli.rollback", 608 "mysqli_select_db" => "mysqli.select-db", 609 "mysqli_set_charset" => "mysqli.set-charset", 610 "mysqli_set_local_infile_default" => "mysqli.set-local-infile-default", 611 "mysqli_set_local_infile_handler" => "mysqli.set-local-infile-handler", 612 "mysqli_ssl_set" => "mysqli.ssl-set", 613 "mysqli_stat" => "mysqli.stat", 614 "mysqli_stmt_init" => "mysqli.stmt-init", 615 "mysqli_store_result" => "mysqli.store-result", 616 "mysqli_thread_id" => "mysqli.thread-id", 617 "mysqli_thread_safe" => "mysqli.thread-safe", 618 "mysqli_use_result" => "mysqli.use-result", 619 "mysqli_stmt_affected_rows" => "mysqli-stmt.affected-rows", 620 "mysqli_stmt_errno" => "mysqli-stmt.errno", 621 "mysqli_stmt_error" => "mysqli-stmt.error", 622 "mysqli_stmt_field_count" => "mysqli-stmt.field-count", 623 "mysqli_stmt_insert_id" => "mysqli-stmt.insert-id", 624 "mysqli_stmt_param_count" => "mysqli-stmt.param-count", 625 "mysqli_stmt_sqlstate" => "mysqli-stmt.sqlstate", 626 "mysqli_stmt_attr_get" => "mysqli-stmt.attr-get", 627 "mysqli_stmt_attr_set" => "mysqli-stmt.attr-set", 628 "mysqli_stmt_bind_param" => "mysqli-stmt.bind-param", 629 "mysqli_stmt_bind_result" => "mysqli-stmt.bind-result", 630 "mysqli_stmt_close" => "mysqli-stmt.close", 631 "mysqli_stmt_data_seek" => "mysqli-stmt.data-seek", 632 "mysqli_stmt_execute" => "mysqli-stmt.execute", 633 "mysqli_stmt_fetch" => "mysqli-stmt.fetch", 634 "mysqli_stmt_free_result" => "mysqli-stmt.free-result", 635 "mysqli_stmt_get_result" => "mysqli-stmt.get-result", 636 "mysqli_stmt_get_warnings" => "mysqli-stmt.get-warnings", 637 "mysqli_stmt_more_results" => "mysqli-stmt.more-results", 638 "mysqli_stmt_next_result" => "mysqli-stmt.next-result", 639 "mysqli_stmt_num_rows" => "mysqli-stmt.num-rows", 640 "mysqli_stmt_prepare" => "mysqli-stmt.prepare", 641 "mysqli_stmt_reset" => "mysqli-stmt.reset", 642 "mysqli_stmt_result_metadata" => "mysqli-stmt.result-metadata", 643 "mysqli_stmt_send_long_data" => "mysqli-stmt.send-long-data", 644 "mysqli_stmt_store_result" => "mysqli-stmt.store-result", 645 "mysqli_field_tell" => "mysqli-result.current-field", 646 "mysqli_num_fields" => "mysqli-result.field-count", 647 "mysqli_fetch_lengths" => "mysqli-result.lengths", 648 "mysqli_num_rows" => "mysqli-result.num-rows", 649 "mysqli_data_seek" => "mysqli-result.data-seek", 650 "mysqli_fetch_all" => "mysqli-result.fetch-all", 651 "mysqli_fetch_array" => "mysqli-result.fetch-array", 652 "mysqli_fetch_assoc" => "mysqli-result.fetch-assoc", 653 "mysqli_fetch_field_direct" => "mysqli-result.fetch-field-direct", 654 "mysqli_fetch_field" => "mysqli-result.fetch-field", 655 "mysqli_fetch_fields" => "mysqli-result.fetch-fields", 656 "mysqli_fetch_object" => "mysqli-result.fetch-object", 657 "mysqli_fetch_row" => "mysqli-result.fetch-row", 658 "mysqli_field_seek" => "mysqli-result.field-seek", 659 "mysqli_free_result" => "mysqli-result.free", 660 "mysqli_embedded_server_end" => "mysqli-driver.embedded-server-end", 661 "mysqli_embedded_server_start" => "mysqli-driver.embedded-server-start", 662]; 663 664// Merge this temporary hack with $uri_aliases so it'll be treated as such 665$uri_aliases = array_merge($uri_aliases, $mysqli_redirects); 666 667// ============================================================================ 668// "Rewrite" the URL, if it was a shortcut 669 670if (isset($uri_aliases[$URI])) { 671 $URI = $uri_aliases[$URI]; 672 /* If it was a page alias, redirect right away */ 673 if (file_exists($_SERVER['DOCUMENT_ROOT'] . "/$URI.php")) { 674 mirror_redirect("/$URI.php"); 675 } 676} 677 678// ============================================================================ 679// Execute external redirect if a rule exists for the URI 680if (isset($external_redirects[$URI])) { 681 mirror_redirect($external_redirects[$URI]); 682} 683 684// Temporary hack for mirror-info, until all the pages 685// will be capable of being included from anywhere 686if ($URI == 'mirror-info') { 687 status_header(200); 688 include_once __DIR__ . "/$URI.php"; 689 exit; 690} 691 692// ============================================================================ 693// Try to find the page using the preferred language as a manual page 694include_once __DIR__ . "/include/manual-lookup.inc"; 695$try = find_manual_page($LANG, $URI); 696if ($try) { 697 status_header(200); 698 include_once __DIR__ . $try; 699 exit; 700} 701// BC. The class methods are now classname.methodname 702if (preg_match("!^manual/(.+)/function\.(.+)-(.+).php$!", $URI, $array)) { 703 $try = find_manual_page($array[1], $array[2] . "." . $array[3]); 704 if ($try) { 705 status_header(301); 706 mirror_redirect($try); 707 exit; 708 } 709} 710 711// ============================================================================ 712// For manual pages for inactive languages, point visitors to the English page 713if (preg_match("!^manual/([^/]+)/([^/]+).php$!", $URI, $match) && 714 isset(Languages::INACTIVE_ONLINE_LANGUAGES[$match[1]])) { 715 $try = find_manual_page("en", $match[2]); 716 if ($try) { 717 error_inactive_manual_page(Languages::INACTIVE_ONLINE_LANGUAGES[$match[1]], $try); 718 } 719} 720 721// ============================================================================ 722// 404 page for manual pages (eg. not built language) 723if (strpos($URI, "manual/") === 0) { 724 $legacy_manual_urls = get_legacy_manual_urls($URI); 725 if (count($legacy_manual_urls) > 0) { 726 fallback_to_legacy_manuals($legacy_manual_urls); 727 } 728 error_404_manual(); 729} 730 731// ============================================================================ 732// If no match was found till this point, the last action is to start a 733// search with the URI the user typed in 734$fallback = ($userPreferences->searchType === UserPreferences::URL_MANUAL ? "404manual" : "404quickref"); 735mirror_redirect( 736 '/search.php?show=' . $fallback . '&lang=' . urlencode($LANG) . 737 '&pattern=' . substr($_SERVER['REQUEST_URI'], 1), 738); 739