Symptoms:

latest code from 8.x fails to install, throwing fatal PHP error Cannot use object of type stdClass as array in .../core/includes/install.inc on line 257

Steps to reproduce:

  1. Get the latest 8.x source code
  2. Copy sites/default/default.settings.php to sites/default/settings.php
  3. Launch installer
  4. Choose English. Press Save and Continue
  5. Choose Standard profile. Press Save and Continue
  6. Proceed to database connection details screen. Press Save and Continue
  7. Bingo. Error 500

Analysis

Error comes from line 257 in includes/install.inc:

if (isset($current[$index])) {

$current is a part of $settings array coming to drupal_rewrite_settings() from install_settings_form_submit():
(install.core.inc, lines 1109-1112)

  $settings['databases'] = (object) array(
    'value'    => array('default' => array('default' => $form_state['storage']['database'])),
    'required' => TRUE,
  );

$current (part of $settings parameter) is an object, while drupal_rewrite_settings() expects array

I set this to critical, because this leaves installation in unusable state.

Update

Clean install without any settings.php goes just fine
Dropping existing database, and trying to re-install with automatically generated settings.php fails.

Follow-up Issues

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

valthebald’s picture

Issue summary: View changes

Updated issue summary.

valthebald’s picture

Title: $databases definition is different in install_settings_form_submit() and drupal_rewrite_settings() » Existing settings.php makes installation impossible

Shorter title

swentel’s picture

I've tried every possible combination and all is fine here ..

valthebald’s picture

Can it be PHP-version specific? mine is 5.4.4

mgifford’s picture

I'm marking this issue I just posted a duplicate #1951866: Can't seem to install D8 this week

I'm using:
PHP 5.3.15 with Suhosin-Patch (cli) (built: Aug 24 2012 17:45:44) - on Mac.

As I mentioned in the other post, I'm also getting this with drush si using Drush 6:

Error: Cannot use object of type stdClass as array in
/Users/mike/shared/htdocs/dm8/core/includes/install.inc, line 257

Figured leaving a stack trace from my error log couldn't hurt either.

 [error] [client 127.0.0.1] PHP Fatal error:  Cannot use object of type stdClass as array in /DRUPAL8/core/includes/install.inc on line 257, referer: http://example.org/core/install.php?langcode=en&profile=standard
 [error] [client 127.0.0.1] PHP Stack trace:, referer: http://example.org/core/install.php?langcode=en&profile=standard
 [error] [client 127.0.0.1] PHP   1. {main}() /DRUPAL8/core/install.php:0, referer: http://example.org/core/install.php?langcode=en&profile=standard
 [error] [client 127.0.0.1] PHP   2. install_drupal() /DRUPAL8/core/install.php:31, referer: http://example.org/core/install.php?langcode=en&profile=standard
 [error] [client 127.0.0.1] PHP   3. install_run_tasks() /DRUPAL8/core/includes/install.core.inc:87, referer: http://example.org/core/install.php?langcode=en&profile=standard
 [error] [client 127.0.0.1] PHP   4. install_run_task() /DRUPAL8/core/includes/install.core.inc:460, referer: http://example.org/core/install.php?langcode=en&profile=standard
 [error] [client 127.0.0.1] PHP   5. drupal_build_form() /DRUPAL8/core/includes/install.core.inc:510, referer: http://example.org/core/install.php?langcode=en&profile=standard
 [error] [client 127.0.0.1] PHP   6. drupal_process_form() /DRUPAL8/core/includes/form.inc:410, referer: http://example.org/core/install.php?langcode=en&profile=standard
 [error] [client 127.0.0.1] PHP   7. form_execute_handlers() /DRUPAL8/core/includes/form.inc:917, referer: http://example.org/core/install.php?langcode=en&profile=standard
 [error] [client 127.0.0.1] PHP   8. call_user_func_array() /DRUPAL8/core/includes/form.inc:1544, referer: http://example.org/core/install.php?langcode=en&profile=standard
 [error] [client 127.0.0.1] PHP   9. install_settings_form_submit() /DRUPAL8/core/includes/form.inc:1544, referer: http://example.org/core/install.php?langcode=en&profile=standard
 [error] [client 127.0.0.1] PHP  10. drupal_rewrite_settings() /DRUPAL8/core/includes/install.core.inc:1118, referer: http://example.org/core/install.php?langcode=en&profile=standard
valthebald’s picture

I see this as a side-effect of #1921818: Modify drupal_rewrite_settings() to allow writing $settings values. $settings was converted from array to stdClass, causing PHP Fatal error in drupal_rewrite_settings().
I wonder what would be the best way to solve this

swentel’s picture

Wait, is this both with Drush ? If so, then this is a non issue, drush isn't always up to date ... (and even then, it works fine here)

valthebald’s picture

No, for me this happens both with drush and web-based install

valthebald’s picture

@swentel: To fully reproduce this in existing installation, I also deleted contents of sites/default/files/php and sites/default/config*
Without deleting sites/default/files/*, dropping site database leaves it in WSOD state (which, I believe, is also an issue, although not as critical as this one)

catch’s picture

Status: Active » Closed (won't fix)

There's no support for head to head upgrades yet. #1921822: Take account of drupal_hash_salt during migration path from 7.x will handle this for 7-8 upgrades, so I don't think there's anything to do here.

valthebald’s picture

HEAD generates settings.php that cannot be used by itself more than once, so it's not exactly upgrade

chx’s picture

Status: Closed (won't fix) » Needs review
FileSize
1.87 KB

While I can't reproduce the fail. Nonetheless, reinstalling is impossible because if you empty your database and your files directory and you load any installer page then:

  1. install_verify_requirements runs very early
  2. system_requirements is called from drupal_check_profile because install_profile_info adds drupal_required_modules() to the profile dependencies
  3. system_requirements runs file_prepare_directory on a number of directories including the config directory if the config directories global is set
  4. install_begin_request sees that the database settings are there, the config dir is there and mistakenly thinks that now all is rosy and uses the normal kernel
  5. kaboom.

The whole requirements for config directories is a farce because Drupal won't get far if the config directory doesn't exist. It most definitely won't get so far as to be able to display a page...

valthebald’s picture

Patch from #11 fixed the problem! It seems that part of it rolls back changes announced in #1921822: Take account of drupal_hash_salt during migration path from 7.x, I wonder if that's fine

chx’s picture

Not sure what do you mean, that issue is not yet in and has 0% common with my patch.

valthebald’s picture

chx’s picture

As for that, I wrote it and I am confident I am not turning anything back, quite to the contrary, that hunk is a sort of followup so that instead of overwriting the whole of $database we override only $database['default']]['default']. What do you see as rolling back?

valthebald’s picture

Status: Needs review » Reviewed & tested by the community

This move from array() to (object) array() and back confused me.
I saw that you are the author of mentioned patch, so if you're confident, so am I :)

webchick’s picture

Assigned: Unassigned » alexpott
Status: Reviewed & tested by the community » Needs review

It'd be great to get alexpott's sign-off on those changes to system.install, since he deliberately added them in #1741804-9: Implement a config import/staging directory.

mgifford’s picture

I've been struggling with this. Realized only now that if I just delete the settings.php file & recopy everything over from default.settings.php it might work. It did.

Anyways, would love this to be more straight forward. I was definitely running into object problems.

Thanks @valthebald & @chx for moving this ahead.

alexpott’s picture

I have followed the instructions in the issue summary and I just can not get the bug to occur.

The following occurs with or without this patch...

If I...

Scenario 1

  1. Install Drupal through frontend
  2. Remove the database
  3. Go to core/install.php complete all the preconfig... fill in db settings and press "Save and continue" i get
    Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[42S02]: Base table or view not found: 1146 Table 'drupal8alt.cache_config' doesn't exist' in /Users/alex/dev/sites/drupal8alt.dev/core/lib/Drupal/Core/Database/Connection.php on line 554

Scenario 2

  1. Install Drupal through frontend
  2. Remove the database
  3. Remove the database config from settings.php
  4. Go to core/install.php complete all the preconfig... fill in db settings and press "Save and continue" i get
    SQLSTATE[42S02]: Base table or view not found: 1146 Table 'drupal8alt.users' doesn't exist: SELECT u.*, s.* FROM {users} u INNER JOIN {sessions} s ON u.uid = s.uid WHERE s.sid = :sid; Array ( [:sid] => sXjNqBZGb-PMaixy57hmZiBU3xTUJIoYrrRtMJ0soU8 )

Scenario 3

  1. Install Drupal through frontend
  2. Empty the database of all tables
  3. Remove the database config from settings.php
  4. Go to core/install.php complete all the preconfig... fill in db settings and press "Save and continue" i get
    SQLSTATE[42S02]: Base table or view not found: 1146 Table 'drupal8alt.users' doesn't exist: SELECT u.*, s.* FROM {users} u INNER JOIN {sessions} s ON u.uid = s.uid WHERE s.sid = :sid; Array ( [:sid] => sXjNqBZGb-PMaixy57hmZiBU3xTUJIoYrrRtMJ0soU8 )

Scenario 4

  1. Install Drupal through frontend
  2. Empty the database of all tables
  3. Remove the database config from settings.php
  4. Remove the config_RANDOMHASH directory
  5. Go to core/install.php complete all the preconfig... fill in db settings and press "Save and continue" i get a successful install

Conclusions

  • We should check to see if the active config directory is empty before installing...
  • Drush site-install needs to empty the active config directory as well as dropping all the tables in the database
  • Not sure that the patch actually fixes anything - as @chx admitted in #13
  • Further investigate the validity of the requirements removed by the patch in #13...

EDIT: Improve the scenario instructions

alexpott’s picture

Found another interesting thing...

Scenario 5

  1. Install Drupal through frontend
  2. Go to core/install.php - immediately see
    Fatal error: __clone method called on non-object in /Users/alex/dev/sites/drupal8alt.dev/core/modules/user/user.module on line 722
    
chx’s picture

Neither of these are addressed, or, I am afraid, going to be addressed.

As long as there is a config directory and settings.php points to it, you can't reinstall. Either delete the config dir or remove the config directories variables from settings.php.

Edit: what this patch fixes is, if I remember correctly, is the one where you empty out the database and the config directory but leave settings.php untouched.

valthebald’s picture

Priority: Critical » Major
Status: Needs review » Active

If not addressing these issues is a (sad) given fact, it may be a good idea to document it somewhere (default.settings.php? )
Also, lowering level to major, since it affects only part of installations, and doesn't happen during "normal" install process

Berdir’s picture

Status: Active » Needs review

#11: 1951068_11.patch queued for re-testing.

Status: Needs review » Needs work

The last submitted patch, 1951068_11.patch, failed testing.

chx’s picture

Title: Existing settings.php makes installation impossible » Make it easier to reinstall
Category: bug » task
Priority: Major » Normal
valthebald’s picture

Yeah, I was thinking of better title :)

alexpott’s picture

Title: Make it easier to reinstall » Make it easier to reinstall by providing helpful information on core/install.php if Drupal is already installed.
Category: task » bug
Status: Needs work » Needs review
FileSize
4.26 KB

Wow this was fun...

Ok we have a problem with error reporting because that has a dependency of config so the real error gets hidden is config broken. We need to ensure that we don't call config before the system is ready or if we do then we catch the error.

Additionally if you go to core/install.php after a successful installation we expect a valid $user object in user_template_preprocess_default_variables_alter()

Also we are not checking that the active configuration directory is empty of config before attempting installation... all sorts of oddities would are possible here...

This does not fix:

scenario 1,2 or 3 (which was a duplicate of 2) - deleting the database is not enough... you have to remove the active config too... the error that's reported is correct ie. "missing cache_config table". In order to make these scenarios display the drupal is already installed page is going to be very tricky as essentially at this point Drupal is broken... config + no db is madness.

This does fix:

The real scenario 5 - which is actually a bug as currently it is impossible to view the Drupal is already installed page!

Plus for drush users see #1954898: site-install fails to install over an existing site because the format of $config_directories in settings.php has changed

Status: Needs review » Needs work

The last submitted patch, 1951068.drupal-reinstall.27.patch, failed testing.

alexpott’s picture

Status: Needs work » Needs review
FileSize
4.2 KB
1.35 KB

Ho hum broke the interactive installer :(

chx’s picture

Status: Needs review » Reviewed & tested by the community

That's good but I still think that we should remove that config directories requirements check -- in another issue, of course.

We all owe you a beer for making error reporting in install work again!

valthebald’s picture

Status: Reviewed & tested by the community » Needs work

With patch from #29, I dropped all tables, but left database itself
Result: WSOD for the frontpage, core/install.php displays PHP exception.
Which is, of course, big improvement - there is clear indication that problem with installation lays in DB.
Yet, there is still no indication that to reinstall, I have to delete sites/default/files/config_* folder - install_already_done_error() is not called at this stage.

alexpott’s picture

@valthebald... if you drop all the tables and don't delete your active config you've only done half the job... if you just drop cache_config you'll have the same issue. As stated in #27 I think this is the correct behaviour.

alexpott’s picture

In my opinion only dropping the database... is like in Drupal 7 terms... removing half of the tables in the database and expecting Drupal to still work...

valthebald’s picture

@alexpott: that may be obvious for those knowing internals of D8, and differences between D7 and D8, but not, for example, regular developer finding his dev DB corrupted

chx’s picture

Status: Needs work » Reviewed & tested by the community

This should go in and then we can try to do more following up. Recognizing the DB gone but the config directory is there situation is very tricky -- we need to recognize that while a connection can be made, there are no tables... and do this on-the-fly somehow because we most definitely won't want to connect to the DB just for this. Right now we detect that the databases global is not filled in at all and that's practically free. Also, if we do #1167144: Make cache backends responsible for their own storage which we totally should then the system will happily self correct the missing cache tables and then good luck figuring out where to figure out that this "DB dropped" situation happened.

valthebald’s picture

I don't suggest to handle every possible failure in code, but to provide site builders with complete information on how to react. This can reside in default.settings.php and/or d.o. documentation

chx’s picture

Title: Make it easier to reinstall by providing helpful information on core/install.php if Drupal is already installed. » install.php error reporting is broken

I retitled the issue to be more close to what gets fixed. It will help reinstall attempts and installer development by not needing a debugger any more with a breakpoint in drupal_exception_handler to figure out wtf broken.

To document the reinstall process, we can add to README/INSTALL/default.settings.php but any developer used to D7 will not read them. That's definitely a followup -- again, a very helpful and not too hard followup but the usefulness, alas, will be limited.

mgifford’s picture

I am having this problem, so was very eager to try the patch in #29.

I deleted the database, removed a wack of files that have given me grief in the past sudo rm -fr c sites/default/files/* and then went through the /core/install.php process and got:

Table variable already exists.

Repeated the whole process and got that again.

It was a nicer message though. Way better than the critical error I was getting before.

chx’s picture

Assigned: alexpott » Unassigned

This needs to be unassigned because I do not think it's proper for Alex to commit his own patch (no matter how much I'd love to see this in).

BTMash’s picture

Ran into the issue myself while trying to install D8 for the first time in a while. Here is a reroll of the patch since other changes made it in since March 27.

valthebald’s picture

Status: Reviewed & tested by the community » Needs work

Patch from #40 did not help.
After deleting DB tables - WSOD
After deleting DB tables and sites/default/files/* - installation starts, but WSOD after DB connection screen

BTMash’s picture

Hmm, does error.log provide any details on the reason for WSOD? chx explains the only deleting db tables portion in post 35 but the WSOD after db connection screen makes less sense since that is where I was having the problem myself and the patch fixed the issue for me.

valthebald’s picture

My bad, I didn't apply *any* patch after the last git pull (facepalm)
After applying, patch from #40 behaves much like #29 - WSOD after dropping tables, the following line in error.log:

[Tue Apr 02 19:35:30 2013] [error] [client 127.0.0.1] PHP Fatal error: Call to a member function get() on a non-object in /home/valeryl/work/d8/core/includes/config.inc on line 106, referer: http://d8.loc/core/install.php?langcode=en&profile=standard

After deleting files in sites/default/files, Exception text in browser screen:

Drupal\Core\Database\DatabaseExceptionWrapper: SQLSTATE[42S02]: Base table or view not found: 1146 Table 'd8.cache' doesn't exist: SELECT cid, data, created, expire, serialized, tags, checksum_invalidations, checksum_deletions FROM {cache} WHERE cid IN (:cids_0); Array ( [:cids_0] => theme_registry:build:modules ) in Drupal\Core\Database\Connection->query() (line 554 of /home/valeryl/work/d8/core/lib/Drupal/Core/Database/Connection.php).

BTMash’s picture

@valthebald, Can you try dropping all tables from the db and removing files in sites/default/files? It *seems* like some tables were created between first dropping the tables and later removing the files.

valthebald’s picture

@BTMash: just checked, no tables in DB

valthebald’s picture

I was able to track the problem down until theme.maintenance.inc, line 53:
$custom_theme = variable_get('maintenance_theme', config('system.theme')->get('default')) ?: 'bartik';
Before that, there is normally handled database exception. Since error is fatal and drupal cannot be started, maintenance theme is initialized by _drupal_maintenance_theme().
If we get back to line 53, it's a key to Pandora box:
config() calls drupal_container(), which returns current DC. Since failure is early, DC is empty, drupal_container() returns NULL, and config() fails with fatal PHP error "Call to a member function get() on a non-object"

I dare say it's a bug in drupal_container() (it's return value declared to be Drupal\Core\Config\Config, not mixed Drupal\Core\Config\Config or NULL). If it's so, it's possible to handle the case of missing DC and return some dumb config object. Does that make sense?

chx’s picture

Status: Needs work » Needs review
FileSize
2.42 KB
5.9 KB

Burdening config() with checking like that for the sake of this extreme case edge case, I do not think so.

Status: Needs review » Needs work

The last submitted patch, 1951068_47.patch, failed testing.

BTMash’s picture

Status: Needs work » Needs review

#40: 1951068.drupal-reinstall.40.patch queued for re-testing.

BTMash’s picture

#47: 1951068_47.patch queued for re-testing.

BTMash’s picture

I reviewed the patch and code/comments look good (the creation of _drupal_get_error_level is a nice touch - I'm assuming it is named the way it is so it could be used elsewhere?). I tested it locally and get the errors in appropriate places (tried without db but with config dir and after full purge) and so far, works as expected. I ran the simpletests again as the patch failing seemed off and turns out that was the case. This is a +1 towards RTBC from me.

chx’s picture

_drupal_get_error_level is a function because it's code used twice not because I'd want anyone else to call it.

mgifford’s picture

@chx's patch still isn't letting me install D8. It's been an annoying problem that's really slowed down what I can review. It's even worse now that SimplyTest.me doesn't work for D8.

chx’s picture

I do not know what to say / do . The error reporting patch is correct, it helps tremendously. I am sorry for those who can't reinstall but this is a first step towards that -- and that is not supported AFAIK anyways.

So, can we get this in so that I don't need to apply every time I want to develop anything?

chx’s picture

Note that I reinstall with mysql -u root -e 'drop database systemdrop;create database systemdrop' ; cp sites/default/default.settings.php sites/default/settings.php; sudo rm -r sites/default/files/*.

mgifford’s picture

I could install the code when I just copied the default.setting.php over the settings.php

Hadn't occurred to me to try that along with removing the other bits that D8 is adding and needs to be removed for a re-install.

alexpott’s picture

Priority: Normal » Major

Patch attached improves the doc block for _drupal_get_error_level() function, swaps out config() for Drupal::config() and does a minor optimisation in _drupal_maintenance_theme().

I've raised the priority of this patch to major because actually debugging changes to the installer or pre DRUPAL_BOOTSTRAP_KERNEL is really difficult without it.

alexpott’s picture

Now for the patch :) referred to in #57

Berdir’s picture

Status: Needs review » Reviewed & tested by the community

If you currently try to access core/install.php and the site is already installed then it explodes with a fatal error about not being able to call __clone().

Applying this patch fixes that and displays the previous and slightly adjusted error messages.

It also fixes a number of other issues, e.g. the error display configuration (which leads to another, misleading error when an error happens, see also https://twitter.com/beejeebus/status/315017933531279360 ;)) ) and the fatal error in theme.maintaince.inc, for which I've seen multiple bug reports already.

This might not be perfect yet, it for example doesn't yet track the situation where you have an existing settings.php that points to an empty database (see #55/56) but we can look into that in a follow-up issue. The only thing that we could maybe do is also mention it in the error message that we display. Basically put the commands in #55 in words. But with or without that, I think this ready to get in and important to do so asap.

alexpott’s picture

Status: Reviewed & tested by the community » Needs review
FileSize
6.27 KB
1.44 KB

On @berdir's suggestion in #59 and IRC improved the already installed message to cover steps outlined in #55

alexpott’s picture

Issue summary: View changes

Updated issue summary.

xjm’s picture

+++ b/core/includes/install.core.incundefined
@@ -1620,7 +1620,7 @@
-  return st('<ul><li>To start over, you must empty your existing database and delete your active configuration.</li><li>To install to a different database, edit the appropriate <em>settings.php</em> file in the <em>sites</em> folder.</li><li>To locate your active configuration, view the appropriate <em>settings.php</em> file in the <em>sites</em> folder.</em></li></li><li>To upgrade an existing installation, proceed to the <a href="@base-url/core/update.php">update script</a>.</li><li>View your <a href="@base-url">existing site</a>.</li></ul>', array('@base-url' => $base_url));
+  return st('<ul><li>To start over, you must empty your existing database, delete your active configuration, and copy default.settings.php over settings.php.</li><li>To install to a different database, edit the appropriate <em>settings.php</em> file in the <em>sites</em> folder.</li><li>To locate your active configuration, view the appropriate <em>settings.php</em> file in the <em>sites</em> folder.</em></li></li><li>To upgrade an existing installation, proceed to the <a href="@base-url/core/update.php">update script</a>.</li><li>View your <a href="@base-url">existing site</a>.</li></ul>', array('@base-url' => $base_url));

We should be consistent in how we format settings.php (looks like it's in an <em> tag in the next line).

alexpott’s picture

Good spot @xjm...

Status: Needs review » Needs work

The last submitted patch, 1951068.install-error-reporting.62.patch, failed testing.

YesCT’s picture

term test fail seems unrelated.

YesCT’s picture

Status: Needs work » Needs review
xjm’s picture

Status: Needs review » Reviewed & tested by the community
FileSize
49.58 KB

Looks good if the retest is good.
already_installed.png

valthebald’s picture

Patch looks great!
I would only add another item in the list of suggestions (between "To start over..." and "To install to a different...":

To start over using existing settings.php, you must empty your existing database, delete your active configuration, and delete active configuration variables from settings.php

xjm’s picture

For #67, instead of adding a whole new bullet, I'd add the bit about deleting active configuration and removing active configuration variables to the second point. If we put too much overwhelming information on this screen, users will not read it, and it's already up there.

valthebald’s picture

@xjm: amending second bullet instead of adding the new one sounds good, as far as it is clear that using existing settings.php is, in fact, possible.

xjm’s picture

#69 also isn't really in scope here, so let's address it in a followup issue. @valthebald, will you file it?

valthebald’s picture

xjm’s picture

Thanks @valthebald!

webchick’s picture

Status: Reviewed & tested by the community » Fixed

Well that definitely seems far preferable to spewing blood. :)

Committed and pushed to 8.x. Thanks!

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

Anonymous’s picture

Issue summary: View changes

added follow-up