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// ============================================================================ 181// Redirect if the entered URI was a PHP page name (except some pages, 182// which we display in the mirror's language or the explicitly specified 183// language [see below]) 184if (!in_array($URI, ['mirror-info', 'error', 'mod'], true) && 185 file_exists($_SERVER['DOCUMENT_ROOT'] . "/$URI.php")) { 186 mirror_redirect("/$URI.php"); 187} 188 189// Work with lowercased URI from now 190$URI = strtolower($URI); 191 192// Redirection hack, see error.inc for detailed description 193// These expect -foo not _foo 194$term = str_replace('_', '-', $URI); 195 196if ($path = is_known_ini($term)) { 197 status_header(301); 198 mirror_redirect("/manual/$LANG/$path"); 199 exit; 200} 201if ($path = is_known_variable($term)) { 202 status_header(301); 203 mirror_redirect("/manual/$LANG/$path"); 204 exit; 205} 206if ($path = is_known_term($term)) { 207 status_header(301); 208 mirror_redirect("/manual/$LANG/$path"); 209 exit; 210} 211 212// ============================================================================ 213// Major manual page modifications (need to handle shortcuts and pages in all languages) 214// Used permanent HTTP redirects, so search engines will be able to pick up the correct 215// new URLs for these pages. 216$manual_page_moves = [ 217 // entry point changed 218 'installation' => 'install', 219 220 // was split among platforms (don't know where to redirect) 221 'install.apache' => 'install', 222 'install.apache2' => 'install', 223 'install.netscape-enterprise' => 'install', 224 'install.otherhttpd' => 'install', 225 226 // moved to platform sections 227 'install.caudium' => 'install.unix.caudium', 228 'install.commandline' => 'install.unix.commandline', 229 'install.fhttpd' => 'install.unix.fhttpd', 230 'install.hpux' => 'install.unix.hpux', 231 'install.iis' => 'install.windows.iis', 232 'install.linux' => 'install.unix', 233 'install.omnihttpd' => 'install.windows.omnihttpd', 234 'install.openbsd' => 'install.unix.openbsd', 235 'install.sambar' => 'install.windows.sambar', 236 'install.solaris' => 'install.unix.solaris', 237 'install.xitami' => 'install.windows.xitami', 238 'install.windows.installer.msi' => 'install.windows', 239 'install.windows.installer' => 'install.windows', 240 241 // Internals docs where moved 242 'zend' => 'internals2.ze1.zendapi', 243 'zend-api' => 'internals2.ze1.zendapi', 244 'internals.pdo' => 'internals2.pdo', 245 'phpdevel' => 'internals2.ze1.php3devel', 246 'tsrm' => 'internals2.ze1.tsrm', 247 248 // Replaced extensions 249 'aspell' => 'pspell', 250 251 // Refactored 252 'regexp.reference' => 'regexp.introduction', 253 "security" => "manual/security", 254 255 // MongoDB converted from set to book 256 'set.mongodb' => 'book.mongodb', 257 'mongodb.installation.homebrew' => 'mongodb.installation#mongodb.installation.homebrew', 258 'mongodb.installation.manual' => 'mongodb.installation#mongodb.installation.manual', 259 'mongodb.installation.pecl' => 'mongodb.installation#mongodb.installation.pecl', 260 'mongodb.installation.windows' => 'mongodb.installation#mongodb.installation.windows', 261 'mongodb.persistence.deserialization' => 'mongodb.persistence#mongodb.persistence.deserialization', 262 'mongodb.persistence.serialization' => 'mongodb.persistence#mongodb.persistence.serialization', 263]; 264 265if (isset($manual_page_moves[$URI])) { 266 status_header(301); 267 mirror_redirect("/" . $manual_page_moves[$URI]); 268} elseif (preg_match("!^manual/([^/]+)/([^/]+).php$!", $URI, $match) && 269 isset($manual_page_moves[$match[2]])) { 270 status_header(301); 271 272 $parts = explode('#', $manual_page_moves[$match[2]], 2); 273 if (count($parts) === 1) { 274 mirror_redirect("/manual/{$match[1]}/{$parts[0]}.php"); 275 } else { 276 mirror_redirect("/manual/{$match[1]}/{$parts[0]}.php#{$parts[1]}"); 277 } 278} 279 280$manual_redirections = [ 281 'class.oci-lob' => 'class.ocilob', 282 'oci-lob.append' => 'ocilob.append', 283 'oci-lob.close' => 'ocilob.close', 284 'oci-lob.eof' => 'ocilob.eof', 285 'oci-lob.erase' => 'ocilob.erase', 286 'oci-lob.export' => 'ocilob.export', 287 'oci-lob.flush' => 'ocilob.flush', 288 'oci-lob.free' => 'ocilob.free', 289 'oci-lob.getbuffering' => 'ocilob.getbuffering', 290 'oci-lob.import' => 'ocilob.import', 291 'oci-lob.load' => 'ocilob.load', 292 'oci-lob.read' => 'ocilob.read', 293 'oci-lob.rewind' => 'ocilob.rewind', 294 'oci-lob.save' => 'ocilob.save', 295 'oci-lob.seek' => 'ocilob.seek', 296 'oci-lob.setbuffering' => 'ocilob.setbuffering', 297 'oci-lob.size' => 'ocilob.size', 298 'oci-lob.tell' => 'ocilob.tell', 299 'oci-lob.truncate' => 'ocilob.truncate', 300 'oci-lob.write' => 'ocilob.write', 301 'oci-lob.writetemporary' => 'ocilob.writetemporary', 302 'class.oci-collection' => 'class.ocicollection', 303 'oci-collection.append' => 'ocicollection.append', 304 'oci-collection.assign' => 'ocicollection.assign', 305 'oci-collection.assignelem' => 'ocicollection.assignelem', 306 'oci-collection.free' => 'ocicollection.free', 307 'oci-collection.getelem' => 'ocicollection.getelem', 308 'oci-collection.max' => 'ocicollection.max', 309 'oci-collection.size' => 'ocicollection.size', 310 'oci-collection.trim' => 'ocicollection.trim', 311 'splstack.setiteratormode' => 'spldoublylinkedlist.setiteratormode', 312 'splqueue.setiteratormode' => 'spldoublylinkedlist.setiteratormode', 313 'class.allow-dynamic-properties' => 'class.allowdynamicproperties', 314 'class.return-type-will-change' => 'class.returntypewillchange', 315 'class.sensitive-parameter' => 'class.sensitiveparameter', 316 'function.curl-file-create' => 'curlfile.construct', 317 'simplexmliterator.current' => 'simplexmlelement.current', 318 'simplexmliterator.getchildren' => 'simplexmlelement.getchildren', 319 'simplexmliterator.haschildren' => 'simplexmlelement.haschildren', 320 'simplexmliterator.key' => 'simplexmlelement.key', 321 'simplexmliterator.next' => 'simplexmlelement.next', 322 'simplexmliterator.rewind' => 'simplexmlelement.rewind', 323 'simplexmliterator.valid' => 'simplexmlelement.valid', 324]; 325 326if (preg_match("!^manual/([^/]+)/([^/]+?)(?:\.php)?$!", $URI, $match) && isset($manual_redirections[$match[2]])) { 327 status_header(301); 328 mirror_redirect("/manual/$match[1]/" . $manual_redirections[$match[2]]); 329} 330 331// ============================================================================ 332// Define shortcuts for PHP files, manual pages and external redirects 333$uri_aliases = [ 334 335 # PHP page shortcuts 336 "download" => "downloads", 337 "getphp" => "downloads", 338 "getdocs" => "download-docs", 339 "documentation" => "docs", 340 "mailinglists" => "mailing-lists", 341 "mailinglist" => "mailing-lists", 342 "changelog" => "ChangeLog-8", 343 "gethelp" => "support", 344 "help" => "support", 345 "unsubscribe" => "unsub", 346 "subscribe" => "mailing-lists", 347 "logos" => "download-logos", 348 349 # manual shortcuts 350 "intro" => "introduction", 351 "whatis" => "introduction", 352 "whatisphp" => "introduction", 353 "what_is_php" => "introduction", 354 355 "windows" => "install.windows", 356 "win32" => "install.windows", 357 358 "globals" => "language.variables.predefined", 359 "register_globals" => "security.globals", 360 "registerglobals" => "security.globals", 361 "manual/en/security.registerglobals.php" => "security.globals", // fix for 4.3.8 configure 362 "magic_quotes" => "security.magicquotes", 363 "magicquotes" => "security.magicquotes", 364 "gd" => "image", 365 "bcmath" => "bc", 366 'streams' => 'book.stream', 367 "mongodb" => "book.mongodb", 368 "hrtime" => "function.hrtime", // Prefer function over PECL ext 369 370 "callback" => "language.pseudo-types", 371 "number" => "language.pseudo-types", 372 "mixed" => "language.pseudo-types", 373 "bool" => "language.types.boolean", 374 "boolean" => "language.types.boolean", 375 "int" => "language.types.integer", 376 "integer" => "language.types.integer", 377 "float" => "language.types.float", 378 "string" => "language.types.string", 379 "heredoc" => "language.types.string", 380 "<<<" => "language.types.string", 381 "object" => "language.types.object", 382 "null" => "language.types.null", 383 'callable' => 'language.types.callable', 384 385 "htaccess" => "configuration.changes", 386 "php_value" => "configuration.changes", 387 388 "ternary" => "language.operators.comparison", 389 "instanceof" => "language.operators.type", 390 "if" => "language.control-structures", 391 "static" => "language.variables.scope", 392 "global" => "language.variables.scope", 393 "@" => "language.operators.errorcontrol", 394 "&" => "language.references", 395 "**" => "language.operators.arithmetic", 396 "..." => "functions.arguments", 397 "splat" => "functions.arguments", 398 "arrow" => "functions.arrow", 399 "fn" => "functions.arrow", 400 // ?:, ??, ??= 401 // These shortcuts can not be captured here since they 402 // don't actually produce a 404 error. 403 // Instead, we have a small check in index.php directly. 404 405 "dowhile" => "control-structures.do.while", 406 407 "tut" => "tutorial", 408 "tut.php" => "tutorial", // BC 409 410 "faq.php" => "faq", // BC 411 "bugs.php" => "bugs", // BC 412 "bugstats.php" => "bugstats", // BC 413 "docs-echm.php" => "download-docs", // BC 414 415 "odbc" => "uodbc", // BC 416 417 "links" => "support", // BC 418 "links.php" => "support", // BC 419 "oracle" => "oci8", 420 "cli" => "features.commandline", 421 422 "oop" => "language.oop5", 423 "enum" => "language.enumerations", 424 "enums" => "language.enumerations", 425 426 "const" => "language.constants.syntax", 427 "class" => "language.oop5.basic", 428 "new" => "language.oop5.basic", 429 "extends" => "language.oop5.basic", 430 "clone" => "language.oop5.cloning", 431 "construct" => "language.oop5.decon", 432 "destruct" => "language.oop5.decon", 433 "public" => "language.oop5.visibility", 434 "private" => "language.oop5.visibility", 435 "protected" => "language.oop5.visibility", 436 "var" => "language.oop5.visibility", 437 "abstract" => "language.oop5.abstract", 438 "interface" => "language.oop5.interfaces", 439 "interfaces" => "language.oop5.interfaces", 440 "autoload" => "language.oop5.autoload", 441 "__autoload" => "language.oop5.autoload", 442 "language.oop5.reflection" => "book.reflection", // BC 443 "::" => "language.oop5.paamayim-nekudotayim", 444 445 "__construct" => "language.oop5.decon", 446 "__destruct" => "language.oop5.decon", 447 "__call" => "language.oop5.overloading", 448 "__callstatic" => "language.oop5.overloading", 449 "__get" => "language.oop5.overloading", 450 "__set" => "language.oop5.overloading", 451 "__isset" => "language.oop5.overloading", 452 "__unset" => "language.oop5.overloading", 453 "__sleep" => "language.oop5.magic", 454 "__wakeup" => "language.oop5.magic", 455 "__tostring" => "language.oop5.magic", 456 "__invoke" => "language.oop5.magic", 457 "__set_state" => "language.oop5.magic", 458 "__debuginfo" => "language.oop5.magic", 459 "__clone" => "language.oop5.cloning", 460 461 "throw" => "language.exceptions", 462 "try" => "language.exceptions", 463 "catch" => "language.exceptions", 464 "lsb" => "language.oop5.late-static-bindings", 465 "namespace" => "language.namespaces", 466 "use" => "language.namespaces.using", 467 468 "factory" => "language.oop5.patterns", 469 "singleton" => "language.oop5.patterns", 470 471 "trait" => "language.oop5.traits", 472 "traits" => "language.oop5.traits", 473 474 "news.php" => "archive/index", // BC 475 "readme.mirror" => "mirroring", // BC 476 477 "php5" => "language.oop5", 478 "zend_changes.txt" => "language.oop5", // BC 479 "zend2_example.phps" => "language.oop5", // BC 480 "zend_changes_php_5_0_0b2.txt" => "language.oop5", // BC 481 "zend-engine-2" => "language.oop5", // BC 482 "zend-engine-2.php" => "language.oop5", // BC 483 484 "news_php_5_0_0b2.txt" => "ChangeLog-5", // BC 485 "news_php_5_0_0b3.txt" => "ChangeLog-5", // BC 486 487 "manual/about-notes.php" => "manual/add-note", // BC 488 "software/index.php" => "software", // BC 489 "releases.php" => "releases/index", // BC 490 491 "migration7" => "migration70", // Consistent with migration5 492 "update_5_2.txt" => "migration52", // BC 493 "readme_upgrade_51.php" => "migration51", // BC 494 "internals" => "internals2", // BC 495 "configuration.directives" => "ini.core", // BC 496 497 # regexp. BC 498 "regexp.reference.backslash" => "regexp.reference.escape", 499 "regexp.reference.circudollar" => "regexp.reference.anchors", 500 "regexp.reference.squarebrackets" => "regexp.reference.character-classes", 501 "regexp.reference.verticalbar" => "regexp.reference.alternation", 502 503 # external shortcut aliases ;) 504 "dochowto" => "phpdochowto", 505 506 # CVS -> SVN 507 "anoncvs.php" => "git", 508 "cvs-php.php" => "git-php", 509 510 # SVN -> Git 511 "svn" => "git", 512 "svn.php" => "git", 513 "svn-php" => "git-php", 514 "svn-php.php" => "git-php", 515 516 # CVSUp -> Nada 517 "cvsup" => "mirroring", 518 519 # Other items 520 "security/crypt" => "security/crypt_blowfish", 521 522 # Bugfixes 523 "array_sort" => "sort", // #64743 524 "array-sort" => "sort", // #64743 525 526 # Removed pages 527 "tips.php" => "urlhowto", 528 "tips" => "urlhowto", 529]; 530 531$external_redirects = [ 532 "php4news" => "https://github.com/php/php-src/raw/PHP-4.4/NEWS", 533 "php5news" => "https://github.com/php/php-src/raw/PHP-5.6/NEWS", 534 "php53news" => "https://github.com/php/php-src/raw/PHP-5.3/NEWS", 535 "php54news" => "https://github.com/php/php-src/raw/PHP-5.4/NEWS", 536 "php55news" => "https://github.com/php/php-src/raw/PHP-5.5/NEWS", 537 "php56news" => "https://github.com/php/php-src/raw/PHP-5.6/NEWS", 538 "php70news" => "https://github.com/php/php-src/raw/PHP-7.0/NEWS", 539 "php71news" => "https://github.com/php/php-src/raw/PHP-7.1/NEWS", 540 "php72news" => "https://github.com/php/php-src/raw/PHP-7.2/NEWS", 541 "php73news" => "https://github.com/php/php-src/raw/PHP-7.3/NEWS", 542 "php74news" => "https://github.com/php/php-src/raw/PHP-7.4/NEWS", 543 "php80news" => "https://github.com/php/php-src/raw/PHP-8.0/NEWS", 544 "phptrunknews" => "https://github.com/php/php-src/raw/master/NEWS", 545 "pear" => "http://pear.php.net/", 546 "bugs" => "https://bugs.php.net/", 547 "bugstats" => "https://bugs.php.net/stats.php", 548 "phpdochowto" => "https://doc.php.net/guide/", 549 "rev" => "https://doc.php.net/revcheck.php?p=graph&lang=$LANG", 550 "release/5_3_0.php" => "/releases/5_3_0.php", // PHP 5.3.0 release announcement had a typo 551 "ideas.php" => "http://wiki.php.net/ideas", // BC 552 "releases.atom" => "/releases/feed.php", // BC, No need to pre-generate it 553 "spec" => "https://github.com/php/php-langspec", 554 "sunglasses" => "https://www.youtube.com/watch?v=dQw4w9WgXcQ", // Temporary easter egg for bug#66144 555]; 556 557// Temporary hack to fix bug #49956 for mysqli -- Please don't hate me for this. Data taken from mysqli/summary.xml 558$mysqli_redirects = [ 559 "mysqli_affected_rows" => "mysqli.affected-rows", 560 "mysqli_get_client_version" => "mysqli.client-version", 561 "mysqli_connect_errno" => "mysqli.connect-errno", 562 "mysqli_connect_error" => "mysqli.connect-error", 563 "mysqli_errno" => "mysqli.errno", 564 "mysqli_error" => "mysqli.error", 565 "mysqli_field_count" => "mysqli.field-count", 566 "mysqli_get_host_info" => "mysqli.host-info", 567 "mysqli_get_proto_info" => "mysqli.protocol-version", 568 "mysqli_get_server_version" => "mysqli.server-version", 569 "mysqli_info" => "mysqli.info", 570 "mysqli_insert_id" => "mysqli.insert-id", 571 "mysqli_sqlstate" => "mysqli.sqlstate", 572 "mysqli_warning_count" => "mysqli.warning-count", 573 "mysqli_autocommit" => "mysqli.autocommit", 574 "mysqli_change_user" => "mysqli.change-user", 575 "mysqli_character_set_name" => "mysqli.character-set-name", 576 "mysqli_close" => "mysqli.close", 577 "mysqli_commit" => "mysqli.commit", 578 "mysqli_connect" => "mysqli.construct", 579 "mysqli_debug" => "mysqli.debug", 580 "mysqli_dump_debug_info" => "mysqli.dump-debug-info", 581 "mysqli_get_charset" => "mysqli.get-charset", 582 "mysqli_get_connection_stats" => "mysqli.get-connection-stats", 583 "mysqli_get_client_info" => "mysqli.get-client-info", 584 "mysqli_get_client_stats" => "mysqli.get-client-stats", 585 "mysqli_get_cache_stats" => "mysqli.get-cache-stats", 586 "mysqli_get_server_info" => "mysqli.get-server-info", 587 "mysqli_get_warnings" => "mysqli.get-warnings", 588 "mysqli_init" => "mysqli.init", 589 "mysqli_kill" => "mysqli.kill", 590 "mysqli_more_results" => "mysqli.more-results", 591 "mysqli_multi_query" => "mysqli.multi-query", 592 "mysqli_next_result" => "mysqli.next-result", 593 "mysqli_options" => "mysqli.options", 594 "mysqli_ping" => "mysqli.ping", 595 "mysqli_prepare" => "mysqli.prepare", 596 "mysqli_query" => "mysqli.query", 597 "mysqli_real_connect" => "mysqli.real-connect", 598 "mysqli_real_escape_string" => "mysqli.real-escape-string", 599 "mysqli_real_query" => "mysqli.real-query", 600 "mysqli_refresh" => "mysqli.refresh", 601 "mysqli_rollback" => "mysqli.rollback", 602 "mysqli_select_db" => "mysqli.select-db", 603 "mysqli_set_charset" => "mysqli.set-charset", 604 "mysqli_set_local_infile_default" => "mysqli.set-local-infile-default", 605 "mysqli_set_local_infile_handler" => "mysqli.set-local-infile-handler", 606 "mysqli_ssl_set" => "mysqli.ssl-set", 607 "mysqli_stat" => "mysqli.stat", 608 "mysqli_stmt_init" => "mysqli.stmt-init", 609 "mysqli_store_result" => "mysqli.store-result", 610 "mysqli_thread_id" => "mysqli.thread-id", 611 "mysqli_thread_safe" => "mysqli.thread-safe", 612 "mysqli_use_result" => "mysqli.use-result", 613 "mysqli_stmt_affected_rows" => "mysqli-stmt.affected-rows", 614 "mysqli_stmt_errno" => "mysqli-stmt.errno", 615 "mysqli_stmt_error" => "mysqli-stmt.error", 616 "mysqli_stmt_field_count" => "mysqli-stmt.field-count", 617 "mysqli_stmt_insert_id" => "mysqli-stmt.insert-id", 618 "mysqli_stmt_param_count" => "mysqli-stmt.param-count", 619 "mysqli_stmt_sqlstate" => "mysqli-stmt.sqlstate", 620 "mysqli_stmt_attr_get" => "mysqli-stmt.attr-get", 621 "mysqli_stmt_attr_set" => "mysqli-stmt.attr-set", 622 "mysqli_stmt_bind_param" => "mysqli-stmt.bind-param", 623 "mysqli_stmt_bind_result" => "mysqli-stmt.bind-result", 624 "mysqli_stmt_close" => "mysqli-stmt.close", 625 "mysqli_stmt_data_seek" => "mysqli-stmt.data-seek", 626 "mysqli_stmt_execute" => "mysqli-stmt.execute", 627 "mysqli_stmt_fetch" => "mysqli-stmt.fetch", 628 "mysqli_stmt_free_result" => "mysqli-stmt.free-result", 629 "mysqli_stmt_get_result" => "mysqli-stmt.get-result", 630 "mysqli_stmt_get_warnings" => "mysqli-stmt.get-warnings", 631 "mysqli_stmt_more_results" => "mysqli-stmt.more-results", 632 "mysqli_stmt_next_result" => "mysqli-stmt.next-result", 633 "mysqli_stmt_num_rows" => "mysqli-stmt.num-rows", 634 "mysqli_stmt_prepare" => "mysqli-stmt.prepare", 635 "mysqli_stmt_reset" => "mysqli-stmt.reset", 636 "mysqli_stmt_result_metadata" => "mysqli-stmt.result-metadata", 637 "mysqli_stmt_send_long_data" => "mysqli-stmt.send-long-data", 638 "mysqli_stmt_store_result" => "mysqli-stmt.store-result", 639 "mysqli_field_tell" => "mysqli-result.current-field", 640 "mysqli_num_fields" => "mysqli-result.field-count", 641 "mysqli_fetch_lengths" => "mysqli-result.lengths", 642 "mysqli_num_rows" => "mysqli-result.num-rows", 643 "mysqli_data_seek" => "mysqli-result.data-seek", 644 "mysqli_fetch_all" => "mysqli-result.fetch-all", 645 "mysqli_fetch_array" => "mysqli-result.fetch-array", 646 "mysqli_fetch_assoc" => "mysqli-result.fetch-assoc", 647 "mysqli_fetch_field_direct" => "mysqli-result.fetch-field-direct", 648 "mysqli_fetch_field" => "mysqli-result.fetch-field", 649 "mysqli_fetch_fields" => "mysqli-result.fetch-fields", 650 "mysqli_fetch_object" => "mysqli-result.fetch-object", 651 "mysqli_fetch_row" => "mysqli-result.fetch-row", 652 "mysqli_field_seek" => "mysqli-result.field-seek", 653 "mysqli_free_result" => "mysqli-result.free", 654 "mysqli_embedded_server_end" => "mysqli-driver.embedded-server-end", 655 "mysqli_embedded_server_start" => "mysqli-driver.embedded-server-start", 656]; 657 658// Merge this temporary hack with $uri_aliases so it'll be treated as such 659$uri_aliases = array_merge($uri_aliases, $mysqli_redirects); 660 661// ============================================================================ 662// "Rewrite" the URL, if it was a shortcut 663 664if (isset($uri_aliases[$URI])) { 665 $URI = $uri_aliases[$URI]; 666 /* If it was a page alias, redirect right away */ 667 if (file_exists($_SERVER['DOCUMENT_ROOT'] . "/$URI.php")) { 668 mirror_redirect("/$URI.php"); 669 } 670} 671 672// ============================================================================ 673// Execute external redirect if a rule exists for the URI 674if (isset($external_redirects[$URI])) { 675 mirror_redirect($external_redirects[$URI]); 676} 677 678// Temporary hack for mirror-info, until all the pages 679// will be capable of being included from anywhere 680if ($URI == 'mirror-info') { 681 status_header(200); 682 include_once __DIR__ . "/$URI.php"; 683 exit; 684} 685 686// ============================================================================ 687// Try to find the page using the preferred language as a manual page 688include_once __DIR__ . "/include/manual-lookup.inc"; 689$try = find_manual_page($LANG, $URI); 690if ($try) { 691 status_header(200); 692 include_once __DIR__ . $try; 693 exit; 694} 695// BC. The class methods are now classname.methodname 696if (preg_match("!^manual/(.+)/function\.(.+)-(.+).php$!", $URI, $array)) { 697 $try = find_manual_page($array[1], $array[2] . "." . $array[3]); 698 if ($try) { 699 status_header(301); 700 mirror_redirect($try); 701 exit; 702 } 703} 704 705// ============================================================================ 706// For manual pages for inactive languages, point visitors to the English page 707if (preg_match("!^manual/([^/]+)/([^/]+).php$!", $URI, $match) && 708 isset(Languages::INACTIVE_ONLINE_LANGUAGES[$match[1]])) { 709 $try = find_manual_page("en", $match[2]); 710 if ($try) { 711 error_inactive_manual_page(Languages::INACTIVE_ONLINE_LANGUAGES[$match[1]], $try); 712 } 713} 714 715// ============================================================================ 716// 404 page for manual pages (eg. not built language) 717if (strpos($URI, "manual/") === 0) { 718 $legacy_manual_urls = get_legacy_manual_urls($URI); 719 if (count($legacy_manual_urls) > 0) { 720 fallback_to_legacy_manuals($legacy_manual_urls); 721 } 722 error_404_manual(); 723} 724 725// ============================================================================ 726// If no match was found till this point, the last action is to start a 727// search with the URI the user typed in 728$fallback = ($userPreferences->searchType === UserPreferences::URL_MANUAL ? "404manual" : "404quickref"); 729mirror_redirect( 730 '/search.php?show=' . $fallback . '&lang=' . urlencode($LANG) . 731 '&pattern=' . substr($_SERVER['REQUEST_URI'], 1), 732); 733