Codeigniter: ini_set(): A session is active. You cannot change the session module's ini settings at this time

Created on 26 Feb 2019  路  31Comments  路  Source: bcit-ci/CodeIgniter

I'm using the session database driver on a MariaDB database and getting the error message ini_set(): A session is active. You cannot change the session module's ini settings at this time emanating from this line of code. I'm yet to fathom why the session write is failing in the first place, but I'm guessing the ini_set message is the result of a bug?

CI version: 3.1.9
OS: CentOS 7.5
Apache/PHP-FPM
PHP 7.2.14 (cli) (built: Jan 11 2019 10:01:17) ( NTS )
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
    with Zend OPcache v7.2.14, Copyright (c) 1999-2018, by Zend Technologies
Bug

Most helpful comment

Just change constant variable called ENVIRONMENT to production located on index.php. Problem solved LOL

All 31 comments

Yes, this is a bug. But that line is actually intended to aid with better error reporting; do you know if the same thing happens on lower PHP versions?

I'm sorry I don't; I only have CI 3 on a PHP 7.2 environment to test with

I'm sorry I don't; I only have CI 3 on a PHP 7.2 environment to test with

Is session.auto_start false or true? If true, change it to false.

I'm sorry I don't; I only have CI 3 on a PHP 7.2 environment to test with

Is session.auto_start false or true? If true, change it to false.

It is false.

@Paradinight If that was the case, a different error would occur, saying a session can't be started in the first place. Pay attention. :)

@jamieburchell Someone opened another issue, which contradicts this one; see #5715 - write() fails, but there's no warning about ini_set() during an active session, and it's also on PHP 7.2.

It's a bit of a leap that the other issue contradicts this one. Maybe they have a different error reporting level or omitted the warning from their issue post.

... they're all E_WARNINGs.

Right, well obviously I don't know anything about the application of the other issue nor can I explain why this happens, hence the opening of this issue. Clearly it shouldn't be assumed that a session is not already active because in some cases one already is.

Happy to troubleshoot the issue with you further as time permits. The cause of the write failure was the result of a timeout.

Clearly it shouldn't be assumed that a session is not already active because in some cases one already is.

I don't know what prompted you to say this, but no - that's far from clear and in fact it makes very little sense as there's no point in attempting to use CI_Session if you've already started a session otherwise. This isn't the problem here, as _fail() is always supposed to be triggered from inside an active session ...
The question is why would a session handler be forbidden to alter its own INI settings, regardless of state, and why you're the first one to encounter such a problem. If other users aren't getting this warning under the same conditions and on the same PHP version, then something doesn't add up.
I notice you've shown your PHP CLI version, but does that actually match the one behind your web server? Those can differ, and even if they don't they do have separate configurations.

That is, unless @Paradinight is on the money and you have started a different session prior to loading CI_Session; not by having it auto_start, but by a manual session_start() call (and haven't shown other error messages).

Before I look in to this further, can you clarify your statement: "Yes, this is a bug"?

I'm using PHP 7.2.14 via PHP-FPM.

session_start() doesn't appear anywhere in my application codebase.

session_start appears in the constructor for the CI_Session library. As the error message suggests, you cannot change the session handler once a session has been opened and at the point the ini_set is called the session is open. I guessed you either assumed a session wouldn't be open (hence my comment) or didn't realise this was forbidden.

To clarify also the failure function is triggered because of a failure to write here: https://github.com/bcit-ci/CodeIgniter/blob/3.1-stable/system/libraries/Session/drivers/Session_database_driver.php#L226

Could you move the ini_set to before the session_start perhaps?

I also encountered this situation.
CI version: 3.1.9
OS: CentOS Apache
PHP 7.2.13

I wrote an API, the single request will not have this error, but the call to the API from the web page will have this error [fast multiple calls]

Before I look in to this further, can you clarify your statement: "Yes, this is a bug"?

Well, as I said, that ini_set() call is supposed to improve error reporting (i.e. actually show the possibly erroneous save_path in the error message generated by PHP, because it's otherwise just an internal property of CI_Session and PHP has no knowledge of it). This is explained by _fail()'s docblock.
If it generates an extra E_WARNING, that's a bug because it's not what was intended.

I guessed you either assumed a session wouldn't be open (hence my comment) or didn't realise this was forbidden.

That would be the latter, but it's not as simple as that ...

Obviously, there's people for whom the E_WARNING doesn't appear; you're the first one to report it. Then also, that line was added way before PHP 7.2 was released (probably before it entered development at all), so it may be a new thing. And finally, #5715 shows that even on 7.2 it may not appear, so it may be the case that only a very specific set of conditions trigger the error.

To clarify also the failure function is triggered because of a failure to write here: https://github.com/bcit-ci/CodeIgniter/blob/3.1-stable/system/libraries/Session/drivers/Session_database_driver.php#L226

Could you move the ini_set to before the session_start perhaps?

I could and that's the obvious fix that I'm thinking about, but with all the strangeness around this issue, I want to know the cause first. Otherwise, we might simply hide another error that would continue to lurk somewhere and cause other problems in the future.

And we may've just found it - the line you pointed to is a "failure to obtain lock" condition, which is more of a refuse-to-write than a straight write failure. It's a decent safeguard, but not meant to be triggered - a lock is supposed to be obtained in read() and I just now notice that CI_Session_database_driver::read() never triggers a failure to lock error.

Can you test what happens if you change https://github.com/bcit-ci/CodeIgniter/blob/0e59db6c207b3108565ef4ab6c18b81353478d91/system/libraries/Session/drivers/Session_database_driver.php#L191 to this:

} else { return $this->_failure; }

@hyxj1220 Are you using the database driver? And how sure are you that you have the exact same error? Excuse my doubting you, but a lot of the short "I have the same problem" replies we get are false, by people who see a similar but different error message, under different conditions.

Also, that a single request doesn't trigger the error is irrelevant. The point of interest is only the one which does.

Well, as I said, that ini_set() call is supposed to improve error reporting (i.e. actually show the possibly erroneous save_path in the error message generated by PHP, because it's otherwise just an internal property of CI_Session and PHP has no knowledge of it). This is explained by _fail()'s docblock.

No need to explain; I'm aware of what this is supposed to be doing.

} else { return $this->_failure; }

Is that supposed to be } else { return $this->_fail(); } ?

I should be able to make a change and test - but at the moment the error condition (the failure to write) is only happening on an application which is suffering timeout issues with cURL requests, so I don't know what sort of window of opportunity I have. I suspect it could be reproduced outside of a production environment though.

No, it's $this->_failure, although either should work. You could test both if you wish, but the point here is just to see if read() doesn't break with it for some reason.

Apologies for the delayed reply. I tried out the above code change and no longer had the error but I can't be sure that was a result of the code change or if the issue just didn't present itself. As it stands the underlying timeout issue has now been resolved so I probably won't encounter this naturally now. If I get a chance, I'll try and setup a test to force it.

Well, if you changed it to return $this->_failure, you wouldn't get the warning about being unable to change ini settings, but you should still get one to tell you that reading session data has failed - that's how you'd know the same conditions were encountered.

In the event that it doesn't work as intended, you'd have empty session data (well, technically -1 will be read and then deserialized to empty because that's not valid session data). That shouldn't be possible though ... we're looking for the other clue.

Is it solved? I have the same problem
env:
Windows 10
Apache 2.4
Php 7.3.3
Mysql 8.0
CI 3.1.10

Severity: Warning
Message: ini_set(): A session is active. You cannot change the session module's ini settings at this time
Filename: Session/Session.php
Line Number: 282


Severity: Warning
Message: ini_set(): A session is active. You cannot change the session module's ini settings at this time
Filename: Session/Session.php
Line Number: 282

That should do it. @jamieburchell Thanks for all, I wish everybody was both that patient and willing to help.

Thank you. I'm sorry I didn't get around to setting up a test environment to invoke the issue. I still plan on doing just that and hopefully, if I can reproduce the issue, I'll be able to confirm it's now fixed with your commit.

Ok, that's great. I was really only asking you to do a "just in case" test, but if you do manage to find an issue with it before we release 3.1.11, we'd be able to prevent it from creeping in there.

Just change constant variable called ENVIRONMENT to production located on index.php. Problem solved LOL

It already is

I tried to reproduce the issue today on a staging site by simulating a slow cURL request but sadly was unable to do so. Still, I plan to update and test CI on this site soon so if I run into it again I'll be sure to revisit this.

@amkaub That would be sweeping it under the rug, not solving the underlying problem.

@jamieburchell Cool, thanks in advance for any potential further feedback. I do consider this to be solved already though.

I had this issue with CI version 3.1.10 and 3.1.11 on PHP 7.1 or 7.2 using files or database driver. I later found out that the issue was to do with having a blank line spacing before the starting tag in my controller files. When I removed that space, everything is working fine now. Phew, had to research and troubleshoot for almost 6 hours ...:-)

if use php extension 5.0.0+, ping function will return true not '+PONG';that will cause these errors in CI 3.1.5

Thanks @sutherlandnele , you saved those 6 hours of my time

Ran Into This Issue On Mac OS (Runs fine on windows and digital ocean server on cloudways [linux based]) removing blank space before " its a bug.

Just change constant variable called ENVIRONMENT to production located on index.php. Problem solved LOL

Alhamdulillah found this answer, big thanks bro SOLVED lol

Just change constant variable called ENVIRONMENT to production located on index.php. Problem solved LOL

this helped me great.. but still got one issue "text/x-generic database.php ( PHP script, ASCII text )". how do I fix this?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

monski picture monski  路  4Comments

rmdhfz picture rmdhfz  路  3Comments

al-ramadhan picture al-ramadhan  路  6Comments

huehnerhose picture huehnerhose  路  6Comments

rjdjohnston picture rjdjohnston  路  4Comments