At the end of the settings file there is the note about settings.local.php file that could be loaded if it exists so administrators could alter the site configuration for local environments if needed without the need to alter the setting file itself.

Since many projects now work with VCS, uncommenting this would result in overwritten file the next time Drupal core will get updated.

I would personally welcome this to be uncommented by default since the file_exists() in the condition that encapsulates the inclusion of that file is very inexpensive so it would not impact performance.

Comments

joyceg’s picture

Assigned: Unassigned » joyceg
cilefen’s picture

Since many projects now work with VCS, uncommenting this would result in overwritten file the next time Drupal core will get updated.

No, it would overwrite only the settings.default.php not settings.php. I do not agree with this issue. Just as many (if not more) sites don't need this and it will be expensive for them.

joyceg’s picture

So,is this issue invalid?

cilefen’s picture

Version: 8.0.x-dev » 8.1.x-dev

I am just one opinion. Incidentally, it went in with #1118520: Add inclusion of a settings.local.php file in settings.php.

cilefen’s picture

cilefen’s picture

I feel this is an advanced configuration for those that know what they are doing so it should be commented out.

wim leers’s picture

Status: Active » Closed (works as designed)
  1. settings.php should never be committed to the VCS, so Since many projects now work with VCS, uncommenting this would result in overwritten file the next time Drupal core will get updated. is not a convincing reason I'm afraid :).
  2. file_exists() in the condition that encapsulates the inclusion of that file is very inexpensive so it would not impact performance. — this is not true, any file system hit (any I/O, really) is very expensive.

So I'm afraid all of these things are really done intentionally, after very careful consideration.

settings.php and settings.local.php are never intended to leave a specific machine. They're not intended to be shared. If you want to share a bunch of settings that aren't machine-specific, create a settings.something.php file and commit that, and have each machine's settings.php include that.

misc’s picture

Status: Closed (works as designed) » Needs review
StatusFileSize
new503 bytes

In our deploy process we build the site every time, and we also sometimes use the settings.local.php - therefor we need the lines to be uncommented. I don't really see the case here for having them commented at all - if the settings.local.php exists it should be included.

No need to have the lines commented out as I see it.

Anyway, I am re-opening this ticket, and adding a small patch.

deadbeef’s picture

This is a major issue on any non-trivial application which may be installed and tested across many different environments in a development lifecycle. Certain configuration will always be infrastructure-dependent , and having to manipulate settings.php in every instance is painful. Aegir, for example writes settings.php itself and includes a facility like this.

file_exists() is cached in the statcache, and has absolutely negligible performance impact.

dawehner’s picture

Let's quote https://secure.php.net/manual/en/function.clearstatcache.php

You should also note that PHP doesn't cache information about non-existent files. So, if you call file_exists() on a file that doesn't exist, it will return FALSE until you create the file. If you create the file, it will return TRUE even if you then delete the file. However unlink() clears the cache automatically.

The actual performance problem though would result into having less caching enabled by default.

fabianx’s picture

IIRC there is a possibility to run a hook after settings.php is written, so a distribution could decide to unconditionally load a settings.local.php file e.g.

This is a decision of fast-by-default. By default Drupal puts e.g. mysql data directly in settings.php, so a settings.local.php is not needed.

If you need it in your workflow, just commit a 'default-settings' settings.php to GIT or add a distribution specific hook.

However as 90% of sites will never need a settings.local.php, giving them an unnecessary I/O hit, would be good to avoid.

misc’s picture

If this should be a performance issue - could someone point out a test that shows that this really is a performance issue? I can not see how one file_exists could have any impact on the application as a whole.

A none existing file should not have any impact on caching - it's just a FALSE on a response.

And, there are a bunch of `file_exists()` in core already.

wim leers’s picture

The difference is that this file_exists() would run for every request (even for page cache hits).

I think @catch and others have nice linkable anecdotes of the problems of just one file_exists()?

misc’s picture

Off course it depends on what you have in the file you include if you use file_exists(). But a none existing file should have zero measurable impact on a application at the size of Drupal 8.

Testing locally (I know that not the best place to test, but better there than nowhere ;-)), I am getting no differences in performance if the file exists or not.

wim leers’s picture

That's because your local webserver is not a multi-head webserver. Once you use multiple webservers, you need them to be in sync. That means a shared file system. Try using NFS or Gluster. Then it will be very noticeable.

It can also be a problem on a single server (think shared hosting) when the HDD/SSD is in heavy use and even doing that single file_exists() call can take many milliseconds.

misc’s picture

I know that it is different environments. But the function itself should have none measurable impact on a drupal 8 site. But for fairs sake, I will try to get some live-testing up just for fun, I will come back with some results. If we have not tested the case, it seems strange, from my point of view, to assume that this minor thing would have an overall impact.

wim leers’s picture

It has been measured, time and time again, and this is why Drupal 8 doesn't have any file_exists() calls in the critical path.

misc’s picture

Ok, could you point me to the testing on this for Drupal 8 - I must have missed it.

dawehner’s picture

Let's use tools for that: $ git log --all --grep="file_exists" points to #752730: Remove file_exists() during bootstrap which has an strace
and a blog entry: #752730-11: Remove file_exists() during bootstrap #752730-13: Remove file_exists() during bootstrap

misc’s picture

I can not see the relevancy here? We are talking about one file_exist() - that should not have the impact that is raised in #752730. Or am I missing something obvious?

richard.c.allen2386’s picture

I tend to agree with MiSc here. I think Wim Leers use case is much less represented than the use case of a small team working on projects trying manage configuration. I think it would be just as easy to say that a team dealing with NFS could just comment that line settings.php.

I'd prefer the flexibility of having it uncommented by default. Yes it would require changes and education but overall I would prefer it this way and I know others would as well.

As for performance, from what I can see on most sites we are talking very trival performance issues. It's not like we don't include an .htaccess though by default when apache very clearly states "You should avoid using .htaccess files completely if you have access to httpd main server config file. Using .htaccess files slows down your Apache http server. Any directive that you can include in a .htaccess file is better set in a Directory block, as it will have the same effect with better performance." Yeah it's slower but it's easier to work with and helps folks when learning.

Having it uncommented by default and having an install option to install to settings.php or local.settings.php should be included in my opinion.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.0-beta1 was released on March 2, 2016, which means new developments and disruptive changes should now be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.0-beta1 was released on August 3, 2016, which means new developments and disruptive changes should now be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

misc’s picture

Updated patch

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.0-alpha1 will be released the week of January 30, 2017, which means new developments and disruptive changes should now be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

kyvour’s picture

I'm agree with MiSc. For now settings.php contains two kinds of settings:
1) settings that can (and probably should) be same on different environments. For example CONFIG_SYNC_DIRECTORY, update_free_access, file_chmod_directory, file_chmod_file, public and private files path etc. Also different contrib modules like "fast 404" might require own settings in this file.
2) settings that can/should be different on different environments. Usually these are settings that are added to the file during the drupal installation: $databases array, hash_salt, install_profile.

On my opinion, drupal should have 2 fies with settings - settings.php and settings.local.php (or probably will be better to rename it to settings.env.php). In this case 1st kind of settings can be included to VCS. And new installation of site's instance will have all required configuration from the beginning. Also in this case result of file_exists() will be cached (or even this condition will be unnecessary)

But this solution requires some updates for installation process, because now settings always will be added to the settings.php file during the drupal installation.

Anonymous’s picture

Just FYI Drupal does a shitload of file operations on twig tempaltes alone, not even looking at the whole code base here. And one file_exists/is_readable is a laughable argument here.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.0-alpha1 will be released the week of July 31, 2017, which means new developments and disruptive changes should now be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.0-alpha1 will be released the week of January 17, 2018, which means new developments and disruptive changes should now be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.6.x-dev » 8.7.x-dev

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

misc’s picture

Updated patch - I still see no valid reasons raised here to have this commented out.

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

matthieuscarset’s picture

+1 for uncommenting the file_exists() too.

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

catch’s picture

Status: Needs review » Closed (works as designed)

If you run file_exists() against a non-existing file, there is no caching from PHP at all - the filesystem will check whether the file exists on every single request to Drupal, because it can never guarantee that it's not just been written. See the docs on https://www.php.net/manual/en/function.clearstatcache.php

How bad this is probably depends on the individual file system, but since settings.php is loaded for the internal page cache, even a small change can have a measurable impact on those pages.

Also since this issue was created, sites are built with composer which includes scaffolding for settings.php, so it's a lot easier to manage stuff like this in git.

Marking this works as designed.