| [ Index ] |
PHP Cross Reference of WordPress Trunk (Updated Daily) |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * Retrieves and creates the wp-config.php file. 4 * 5 * The permissions for the base directory must allow for writing files in order 6 * for the wp-config.php to be created using this page. 7 * 8 * @package WordPress 9 * @subpackage Administration 10 */ 11 12 /** 13 * We are installing. 14 */ 15 define( 'WP_INSTALLING', true ); 16 17 if ( ! defined( 'ABSPATH' ) ) { 18 define( 'ABSPATH', dirname( __DIR__ ) . '/' ); 19 } 20 21 /* 22 * Check whether a wp-config.php file already exists, either in the WordPress root 23 * or one level above it (but not as part of another installation). 24 * This mirrors the lookup in wp-load.php. 25 */ 26 if ( file_exists( ABSPATH . 'wp-config.php' ) ) { 27 $existing_config_location = 'root'; 28 } elseif ( @file_exists( dirname( ABSPATH ) . '/wp-config.php' ) && ! @file_exists( dirname( ABSPATH ) . '/wp-settings.php' ) ) { 29 $existing_config_location = 'parent'; 30 } else { 31 $existing_config_location = ''; 32 } 33 34 if ( $existing_config_location ) { 35 /* 36 * A configuration file already exists, so there is nothing to set up here. 37 * Load WordPress through that file, like any other request would, so that the 38 * site's locale is known and the message below can be translated. 39 */ 40 require_once ABSPATH . 'wp-load.php'; 41 42 nocache_headers(); 43 44 if ( 'root' === $existing_config_location ) { 45 $message = sprintf( 46 /* translators: 1: wp-config.php, 2: install.php */ 47 __( 'The file %1$s already exists. If you need to reset any of the configuration items in this file, please delete it first. You may try <a href="%2$s">installing now</a>.' ), 48 '<code>wp-config.php</code>', 49 'install.php' 50 ); 51 } else { 52 $message = sprintf( 53 /* translators: 1: wp-config.php, 2: install.php */ 54 __( 'The file %1$s already exists one level above your WordPress installation. If you need to reset any of the configuration items in this file, please delete it first. You may try <a href="%2$s">installing now</a>.' ), 55 '<code>wp-config.php</code>', 56 'install.php' 57 ); 58 } 59 60 wp_die( '<p>' . $message . '</p>', 409 ); 61 } 62 63 /** 64 * We are blissfully unaware of anything. 65 */ 66 define( 'WP_SETUP_CONFIG', true ); 67 68 /** 69 * Disable error reporting 70 * 71 * Set this to error_reporting( -1 ) for debugging 72 */ 73 error_reporting( 0 ); 74 75 require ABSPATH . 'wp-settings.php'; 76 77 /** Load WordPress Administration Upgrade API */ 78 require_once ABSPATH . 'wp-admin/includes/upgrade.php'; 79 80 /** Load WordPress Translation Installation API */ 81 require_once ABSPATH . 'wp-admin/includes/translation-install.php'; 82 83 nocache_headers(); 84 85 // Support wp-config-sample.php one level up, for the develop repo. 86 if ( file_exists( ABSPATH . 'wp-config-sample.php' ) ) { 87 $config_file = file( ABSPATH . 'wp-config-sample.php' ); 88 } elseif ( file_exists( dirname( ABSPATH ) . '/wp-config-sample.php' ) ) { 89 $config_file = file( dirname( ABSPATH ) . '/wp-config-sample.php' ); 90 } else { 91 wp_die( 92 sprintf( 93 /* translators: %s: wp-config-sample.php */ 94 __( 'Sorry, I need a %s file to work from. Please re-upload this file to your WordPress installation.' ), 95 '<code>wp-config-sample.php</code>' 96 ) 97 ); 98 } 99 100 $step = isset( $_GET['step'] ) ? (int) $_GET['step'] : -1; 101 102 /** 103 * Display setup wp-config.php file header. 104 * 105 * @ignore 106 * @since 2.3.0 107 * 108 * @param string|string[] $body_classes Class attribute values for the body tag. 109 */ 110 function setup_config_display_header( $body_classes = array() ) { 111 $body_classes = (array) $body_classes; 112 $body_classes[] = 'wp-core-ui'; 113 $body_classes[] = 'admin-color-modern'; 114 115 if ( is_rtl() ) { 116 $body_classes[] = 'rtl'; 117 } 118 119 header( 'Content-Type: text/html; charset=utf-8' ); 120 ?> 121 <!DOCTYPE html> 122 <html <?php language_attributes(); ?>> 123 <head> 124 <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 125 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 126 <meta name="robots" content="noindex,nofollow" /> 127 <title><?php _e( 'WordPress › Setup Configuration File' ); ?></title> 128 <?php wp_admin_css( 'install', true ); ?> 129 </head> 130 <body class="<?php echo implode( ' ', $body_classes ); ?>"> 131 <p id="logo"><?php _e( 'WordPress' ); ?></p> 132 <?php 133 } // End function setup_config_display_header(); 134 135 /** 136 * @global string $wp_local_package Locale code of the package. 137 * @global WP_Locale $wp_locale WordPress date and time locale object. 138 */ 139 $language = ''; 140 if ( ! empty( $_REQUEST['language'] ) ) { 141 $language = preg_replace( '/[^a-zA-Z0-9_]/', '', $_REQUEST['language'] ); 142 } elseif ( isset( $GLOBALS['wp_local_package'] ) ) { 143 $language = $GLOBALS['wp_local_package']; 144 } 145 146 switch ( $step ) { 147 case -1: 148 if ( wp_can_install_language_pack() && empty( $language ) ) { 149 $languages = wp_get_available_translations(); 150 if ( $languages ) { 151 setup_config_display_header( 'language-chooser' ); 152 echo '<h1 class="screen-reader-text">Welcome to WordPress</h1>'; 153 echo '<form id="setup" method="post" action="?step=0">'; 154 wp_install_language_form( $languages ); 155 echo '</form>'; 156 break; 157 } 158 } 159 160 // Deliberately fall through if we can't reach the translations API. 161 162 case 0: 163 if ( ! empty( $language ) ) { 164 $loaded_language = wp_download_language_pack( $language ); 165 if ( $loaded_language ) { 166 load_default_textdomain( $loaded_language ); 167 $GLOBALS['wp_locale'] = new WP_Locale(); 168 } 169 } 170 171 setup_config_display_header(); 172 $step_1 = 'setup-config.php?step=1'; 173 if ( isset( $_REQUEST['noapi'] ) ) { 174 $step_1 .= '&noapi'; 175 } 176 if ( ! empty( $loaded_language ) ) { 177 $step_1 .= '&language=' . $loaded_language; 178 } 179 ?> 180 <h1 class="screen-reader-text"> 181 <?php 182 /* translators: Hidden accessibility text. */ 183 _e( 'Before getting started' ); 184 ?> 185 </h1> 186 <p><?php _e( 'Welcome to WordPress. Before getting started, you will need to know the following items.' ); ?></p> 187 <ol> 188 <li><?php _e( 'Database name' ); ?></li> 189 <li><?php _e( 'Database username' ); ?></li> 190 <li><?php _e( 'Database password' ); ?></li> 191 <li><?php _e( 'Database host' ); ?></li> 192 <li><?php _e( 'Table prefix (if you want to run more than one WordPress in a single database)' ); ?></li> 193 </ol> 194 <p> 195 <?php 196 printf( 197 /* translators: %s: wp-config.php */ 198 __( 'This information is being used to create a %s file.' ), 199 '<code>wp-config.php</code>' 200 ); 201 ?> 202 <strong> 203 <?php 204 printf( 205 /* translators: 1: wp-config-sample.php, 2: wp-config.php */ 206 __( 'If for any reason this automatic file creation does not work, do not worry. All this does is fill in the database information to a configuration file. You may also simply open %1$s in a text editor, fill in your information, and save it as %2$s.' ), 207 '<code>wp-config-sample.php</code>', 208 '<code>wp-config.php</code>' 209 ); 210 ?> 211 </strong> 212 <?php 213 printf( 214 /* translators: 1: Documentation URL, 2: wp-config.php */ 215 __( 'Need more help? <a href="%1$s">Read the support article on %2$s</a>.' ), 216 __( 'https://developer.wordpress.org/advanced-administration/wordpress/wp-config/' ), 217 '<code>wp-config.php</code>' 218 ); 219 ?> 220 </p> 221 <p><?php _e( 'In all likelihood, these items were supplied to you by your web host. If you do not have this information, then you will need to contact them before you can continue. If you are ready…' ); ?></p> 222 223 <p class="step"><a href="<?php echo $step_1; ?>" class="button button-large"><?php _e( 'Let’s go!' ); ?></a></p> 224 <?php 225 break; 226 227 case 1: 228 load_default_textdomain( $language ); 229 $GLOBALS['wp_locale'] = new WP_Locale(); 230 231 setup_config_display_header(); 232 233 $autofocus = wp_is_mobile() ? '' : ' autofocus'; 234 ?> 235 <h1 class="screen-reader-text"> 236 <?php 237 /* translators: Hidden accessibility text. */ 238 _e( 'Set up your database connection' ); 239 ?> 240 </h1> 241 <form method="post" action="setup-config.php?step=2"> 242 <p><?php _e( 'Below you should enter your database connection details. If you are not sure about these, contact your host.' ); ?></p> 243 <table class="form-table" role="presentation"> 244 <tr> 245 <th scope="row"><label for="dbname"><?php _e( 'Database Name' ); ?></label></th> 246 <td><input name="dbname" id="dbname" type="text" aria-describedby="dbname-desc" size="25" placeholder="wordpress"<?php echo $autofocus; ?> /> 247 <p id="dbname-desc"><?php _e( 'The name of the database you want to use with WordPress.' ); ?></p></td> 248 </tr> 249 <tr> 250 <th scope="row"><label for="uname"><?php _e( 'Username' ); ?></label></th> 251 <td><input name="uname" id="uname" type="text" aria-describedby="uname-desc" size="25" placeholder="<?php echo htmlspecialchars( _x( 'username', 'example username' ), ENT_QUOTES ); ?>" /> 252 <p id="uname-desc"><?php _e( 'Your database username.' ); ?></p></td> 253 </tr> 254 <tr> 255 <th scope="row"><label for="pwd"><?php _e( 'Password' ); ?></label></th> 256 <td> 257 <div class="wp-pwd"> 258 <input name="pwd" id="pwd" type="password" class="regular-text" data-reveal="1" aria-describedby="pwd-desc" size="25" placeholder="<?php echo htmlspecialchars( _x( 'password', 'example password' ), ENT_QUOTES ); ?>" autocomplete="off" spellcheck="false" /> 259 <button type="button" class="button wp-hide-pw user-new-password-toggle pwd-toggle hide-if-no-js" data-toggle="0" data-start-masked="1" aria-label="<?php esc_attr_e( 'Show password' ); ?>"> 260 <span class="dashicons dashicons-visibility"></span> 261 <span class="text"><?php _e( 'Show' ); ?></span> 262 </button> 263 </div> 264 <p id="pwd-desc"><?php _e( 'Your database password.' ); ?></p> 265 </td> 266 </tr> 267 <tr> 268 <th scope="row"><label for="dbhost"><?php _e( 'Database Host' ); ?></label></th> 269 <td><input name="dbhost" id="dbhost" type="text" aria-describedby="dbhost-desc" size="25" value="localhost" /> 270 <p id="dbhost-desc"> 271 <?php 272 /* translators: %s: localhost */ 273 printf( __( 'You should be able to get this info from your web host, if %s does not work.' ), '<code>localhost</code>' ); 274 ?> 275 </p></td> 276 </tr> 277 <tr> 278 <th scope="row"><label for="prefix"><?php _e( 'Table Prefix' ); ?></label></th> 279 <td><input name="prefix" id="prefix" type="text" aria-describedby="prefix-desc" value="wp_" size="25" /> 280 <p id="prefix-desc"><?php _e( 'If you want to run multiple WordPress installations in a single database, change this.' ); ?></p></td> 281 </tr> 282 </table> 283 <?php 284 if ( isset( $_GET['noapi'] ) ) { 285 ?> 286 <input name="noapi" type="hidden" value="1" /><?php } ?> 287 <input type="hidden" name="language" value="<?php echo esc_attr( $language ); ?>" /> 288 <p class="step"><input name="submit" type="submit" value="<?php echo htmlspecialchars( __( 'Submit' ), ENT_QUOTES ); ?>" class="button button-large" /></p> 289 </form> 290 <?php 291 wp_print_scripts( 'password-toggle' ); 292 break; 293 294 case 2: 295 load_default_textdomain( $language ); 296 $GLOBALS['wp_locale'] = new WP_Locale(); 297 298 $dbname = trim( wp_unslash( $_POST['dbname'] ) ); 299 $uname = trim( wp_unslash( $_POST['uname'] ) ); 300 $pwd = trim( wp_unslash( $_POST['pwd'] ) ); 301 $dbhost = trim( wp_unslash( $_POST['dbhost'] ) ); 302 $prefix = trim( wp_unslash( $_POST['prefix'] ) ); 303 304 $step_1 = 'setup-config.php?step=1'; 305 $install = 'install.php'; 306 if ( isset( $_REQUEST['noapi'] ) ) { 307 $step_1 .= '&noapi'; 308 } 309 310 if ( ! empty( $language ) ) { 311 $step_1 .= '&language=' . $language; 312 $install .= '?language=' . $language; 313 } else { 314 $install .= '?language=en_US'; 315 } 316 317 $tryagain_link = '</p><p class="step"><a href="' . $step_1 . '" onclick="javascript:history.go(-1);return false;" class="button button-large">' . __( 'Try Again' ) . '</a>'; 318 319 if ( empty( $prefix ) ) { 320 wp_die( __( '<strong>Error:</strong> "Table Prefix" must not be empty.' ) . $tryagain_link ); 321 } 322 323 // Validate $prefix: it can only contain letters, numbers and underscores. 324 if ( preg_match( '|[^a-z0-9_]|i', $prefix ) ) { 325 wp_die( __( '<strong>Error:</strong> "Table Prefix" can only contain numbers, letters, and underscores.' ) . $tryagain_link ); 326 } 327 328 // Test the DB connection. 329 /**#@+ 330 * 331 * @ignore 332 */ 333 define( 'DB_NAME', $dbname ); 334 define( 'DB_USER', $uname ); 335 define( 'DB_PASSWORD', $pwd ); 336 define( 'DB_HOST', $dbhost ); 337 /**#@-*/ 338 339 // Re-construct $wpdb with these new values. 340 unset( $wpdb ); 341 require_wp_db(); 342 343 /* 344 * The wpdb constructor bails when WP_SETUP_CONFIG is set, so we must 345 * fire this manually. We'll fail here if the values are no good. 346 */ 347 $wpdb->db_connect(); 348 349 if ( ! empty( $wpdb->error ) ) { 350 wp_die( $wpdb->error->get_error_message() . $tryagain_link ); 351 } 352 353 $errors = $wpdb->suppress_errors(); 354 $wpdb->query( "SELECT $prefix" ); 355 $wpdb->suppress_errors( $errors ); 356 357 if ( ! $wpdb->last_error ) { 358 // MySQL was able to parse the prefix as a value, which we don't want. Bail. 359 wp_die( __( '<strong>Error:</strong> "Table Prefix" is invalid.' ) ); 360 } 361 362 // Generate keys and salts using secure CSPRNG; fallback to API if enabled; further fallback to original wp_generate_password(). 363 try { 364 $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_ []{}<>~`+=,.;:/?|'; 365 $max = strlen( $chars ) - 1; 366 for ( $i = 0; $i < 8; $i++ ) { 367 $key = ''; 368 for ( $j = 0; $j < 64; $j++ ) { 369 $key .= substr( $chars, random_int( 0, $max ), 1 ); 370 } 371 $secret_keys[] = $key; 372 } 373 } catch ( Exception $ex ) { 374 $no_api = isset( $_POST['noapi'] ); 375 376 if ( ! $no_api ) { 377 $secret_keys = wp_remote_get( 'https://api.wordpress.org/secret-key/1.1/salt/' ); 378 } 379 380 if ( $no_api || is_wp_error( $secret_keys ) ) { 381 $secret_keys = array(); 382 for ( $i = 0; $i < 8; $i++ ) { 383 $secret_keys[] = wp_generate_password( 64, true, true ); 384 } 385 } else { 386 $secret_keys = explode( "\n", wp_remote_retrieve_body( $secret_keys ) ); 387 foreach ( $secret_keys as $k => $v ) { 388 $secret_keys[ $k ] = substr( $v, 28, 64 ); 389 } 390 } 391 } 392 393 $key = 0; 394 foreach ( $config_file as $line_num => $line ) { 395 if ( str_starts_with( $line, '$table_prefix =' ) ) { 396 $config_file[ $line_num ] = '$table_prefix = \'' . addcslashes( $prefix, "\\'" ) . "';\r\n"; 397 continue; 398 } 399 400 if ( ! preg_match( '/^define\(\s*\'([A-Z_]+)\',([ ]+)/', $line, $match ) ) { 401 continue; 402 } 403 404 $constant = $match[1]; 405 $padding = $match[2]; 406 407 switch ( $constant ) { 408 case 'DB_NAME': 409 case 'DB_USER': 410 case 'DB_PASSWORD': 411 case 'DB_HOST': 412 $config_file[ $line_num ] = "define( '" . $constant . "'," . $padding . "'" . addcslashes( constant( $constant ), "\\'" ) . "' );\r\n"; 413 break; 414 case 'DB_CHARSET': 415 if ( 'utf8mb4' === $wpdb->charset || ( ! $wpdb->charset ) ) { 416 $config_file[ $line_num ] = "define( '" . $constant . "'," . $padding . "'utf8mb4' );\r\n"; 417 } 418 break; 419 case 'AUTH_KEY': 420 case 'SECURE_AUTH_KEY': 421 case 'LOGGED_IN_KEY': 422 case 'NONCE_KEY': 423 case 'AUTH_SALT': 424 case 'SECURE_AUTH_SALT': 425 case 'LOGGED_IN_SALT': 426 case 'NONCE_SALT': 427 $config_file[ $line_num ] = "define( '" . $constant . "'," . $padding . "'" . $secret_keys[ $key++ ] . "' );\r\n"; 428 break; 429 } 430 } 431 unset( $line ); 432 433 if ( ! is_writable( ABSPATH ) ) : 434 setup_config_display_header(); 435 ?> 436 <p> 437 <?php 438 /* translators: %s: wp-config.php */ 439 printf( __( 'Unable to write to %s file.' ), '<code>wp-config.php</code>' ); 440 ?> 441 </p> 442 <p id="wp-config-description"> 443 <?php 444 /* translators: %s: wp-config.php */ 445 printf( __( 'You can create the %s file manually and paste the following text into it.' ), '<code>wp-config.php</code>' ); 446 447 $config_text = ''; 448 449 foreach ( $config_file as $line ) { 450 $config_text .= htmlentities( $line, ENT_COMPAT, 'UTF-8' ); 451 } 452 ?> 453 </p> 454 <p class="configuration-rules-label"><label for="wp-config"> 455 <?php 456 /* translators: %s: wp-config.php */ 457 printf( __( 'Configuration rules for %s:' ), '<code>wp-config.php</code>' ); 458 ?> 459 </label></p> 460 <textarea id="wp-config" cols="98" rows="15" class="code" readonly="readonly" aria-describedby="wp-config-description"><?php echo $config_text; ?></textarea> 461 <p><?php _e( 'After you’ve done that, click “Run the installation”.' ); ?></p> 462 <p class="step"><a href="<?php echo $install; ?>" class="button button-large"><?php _e( 'Run the installation' ); ?></a></p> 463 <script> 464 (function(){ 465 if ( ! /iPad|iPod|iPhone/.test( navigator.userAgent ) ) { 466 var el = document.getElementById('wp-config'); 467 el.focus(); 468 el.select(); 469 } 470 })(); 471 </script> 472 <?php 473 else : 474 /* 475 * If this file doesn't exist, then we are using the wp-config-sample.php 476 * file one level up, which is for the develop repo. 477 */ 478 if ( file_exists( ABSPATH . 'wp-config-sample.php' ) ) { 479 $path_to_wp_config = ABSPATH . 'wp-config.php'; 480 } else { 481 $path_to_wp_config = dirname( ABSPATH ) . '/wp-config.php'; 482 } 483 484 $error_message = ''; 485 $handle = fopen( $path_to_wp_config, 'w' ); 486 /* 487 * Why check for the absence of false instead of checking for resource with is_resource()? 488 * To future-proof the check for when fopen returns object instead of resource, i.e. a known 489 * change coming in PHP. 490 */ 491 if ( false !== $handle ) { 492 foreach ( $config_file as $line ) { 493 fwrite( $handle, $line ); 494 } 495 fclose( $handle ); 496 } else { 497 $wp_config_perms = fileperms( $path_to_wp_config ); 498 if ( ! empty( $wp_config_perms ) && ! is_writable( $path_to_wp_config ) ) { 499 $error_message = sprintf( 500 /* translators: 1: wp-config.php, 2: Documentation URL. */ 501 __( 'You need to make the file %1$s writable before you can save your changes. See <a href="%2$s">Changing File Permissions</a> for more information.' ), 502 '<code>wp-config.php</code>', 503 __( 'https://developer.wordpress.org/advanced-administration/server/file-permissions/' ) 504 ); 505 } else { 506 $error_message = sprintf( 507 /* translators: %s: wp-config.php */ 508 __( 'Unable to write to %s file.' ), 509 '<code>wp-config.php</code>' 510 ); 511 } 512 } 513 514 chmod( $path_to_wp_config, 0666 ); 515 setup_config_display_header(); 516 517 if ( false !== $handle ) : 518 ?> 519 <h1 class="screen-reader-text"> 520 <?php 521 /* translators: Hidden accessibility text. */ 522 _e( 'Successful database connection' ); 523 ?> 524 </h1> 525 <p><?php _e( 'All right, sparky! You’ve made it through this part of the installation. WordPress can now communicate with your database. If you are ready, time now to…' ); ?></p> 526 527 <p class="step"><a href="<?php echo $install; ?>" class="button button-large"><?php _e( 'Run the installation' ); ?></a></p> 528 <?php 529 else : 530 printf( '<p>%s</p>', $error_message ); 531 endif; 532 endif; 533 break; 534 } // End of the steps switch. 535 ?> 536 <?php wp_print_scripts( 'language-chooser' ); ?> 537 </body> 538 </html>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated : Thu Oct 1 08:20:30 2026 | Cross-referenced by PHPXref |