barbushin / php-console

Handle PHP errors, dump variables, execute PHP code remotely in Google Chrome
https://chrome.google.com/webstore/detail/php-console/nfhmhhlpfleoednkpnnnkolmclajemef
MIT License
1.34k stars 283 forks source link

"Cannot send session cache limiter - headers already sent" when using PhpConsole in WordPress #88

Closed unfulvio closed 9 years ago

unfulvio commented 9 years ago

Hi Sergey,

I had some people reporting an error with my WordPress implementation of PhpConsole I'm trying to solve: https://github.com/nekojira/wp-php-console/issues/11 Cannot send session cache limiter - headers already sent

the error is triggered by PhpConsole/Storage/Session.php but it's related to a WordPress core file (https://github.com/nekojira/wp-php-console/issues/11#issuecomment-119005216)

It's a bit difficult for me to replicate the error as it doesn't happen in every installation but only when some other plugins are installed, without a reference in the stack trace.

Do you think there's something I can change in my PhpConsole implementation to avoid this kind of error?

thank you!

barbushin commented 9 years ago

Hi Fulvio!

There are two things you can try:

  1. Call PhpConsole\Connector::setPostponeStorage(new PhpConsole\Storage\Session()) in WP_PHP_Console::__construct() before PhpConsole\Connector::getInstance() so it will force session_start() as soon as possible.
  2. Call PhpConsole\Connector::setPostponeStorage() with any other PhpConsole\Storage implementation (see https://github.com/barbushin/php-console/tree/master/src/PhpConsole/Storage).

Hope it helps.

unfulvio commented 9 years ago

Hey, I was just looking into that but the error persists

https://github.com/nekojira/wp-php-console/blob/master/lib/class-wp-php-console.php#L68

I tried to add it later too but no change https://github.com/nekojira/wp-php-console/blob/master/lib/class-wp-php-console.php#L411

barbushin commented 9 years ago

And did you tried to use https://github.com/barbushin/php-console/blob/master/src/PhpConsole/Storage/File.php as postpone storage?

unfulvio commented 9 years ago

oh yes actually I might have fixed it, I will report as soon as the other users confirm this, many thanks!

unfulvio commented 9 years ago

Hi Sergey, I have one last issue

when PHP Console is used as a WordPress plugin and when I use a File Storage to circumvent the Session issue, the suggested code you have posted will write pc.data in a subdir where the PHP Console library is. In WordPress, if the PHP Console is embedded in a plugin, this will be inside the /wp-content/plugins path. However, it seems that this path is not writeable by some users or maybe they can't chmod on a remote server.

I was thinking to place the temporary pc.data file in /wp-content/uploads dir which is generally writeable in all installations. To get the path to wp-content/uploads I can use this WordPress function: https://codex.wordpress.org/Function_Reference/wp_upload_dir

However, when I use it with PHP Console like so:

$upload_dir = wp_upload_dir();
PhpConsole\Connector::setPostponeStorage( new PhpConsole\Storage\File( $upload_dir['basedir'] . '/pc.data' ) );

I trigger the error on L:32 of File.php:

throw new \Exception('Path ' . $this->filePath . ' is under DOCUMENT_ROOT. It\'s insecure!');

But it's not the document root.

I'm trying to see if I can get it saved inside the plugin directory in the meanwhile.

barbushin commented 9 years ago

I think the most efficient way is just to try

  1. Call PhpConsole\Connector::setPostponeStorage(new PhpConsole\Storage\Session()) in WP_PHP_Console::__construct() before PhpConsole\Connector::getInstance() so it will force session_start() as soon as possible.

If it will be impossible to set session cookie in this way, so anyway php-console will not work because WP_PHP_Console::__construct() also require to set header.

unfulvio commented 9 years ago

No already tried, in that way PHP Console won't work at all :/

writing to file works for me, but not for some users if they can't write

I'm trying this:

$upload_dir = wp_upload_dir();
$phpcdir = $upload_dir['basedir'] . '/php-console/';
$make_dir = wp_mkdir_p( $phpcdir );
if ( $make_dir === true ) {
  PhpConsole\Connector::setPostponeStorage( new PhpConsole\Storage\File( $phpcdir . 'pc.data' ) );
}

But PHP Console will still trigger the exception telling me it's in document root - but it's not - I'm creating a directory in /wp-content-uploads/php-console/ and I want to write pc.data there, but PHP Console doesn't let me.

barbushin commented 9 years ago

Also you can store postponed data in MySQL. Just implement https://github.com/barbushin/php-console/blob/master/src/PhpConsole/Storage/AllKeysList.php for MySQL.

unfulvio commented 9 years ago

well sure I could, but seems a bit overkill - but why PHP Console doesn't let me write to that directory? it's not in the root

barbushin commented 9 years ago

Because it's unsecure. Because in this way everyone can read this file. There is solution http://i.imgur.com/OhvBuHL.png But in this way you should use file name like $phpcdir = $upload_dir['basedir'] . '/php-console/' . md5(__FILE__).'_pc.dat'; So it will be not so easy to grab it.

It's very strange that there is no something like tmp dir in WP for writing logs and etc.

unfulvio commented 9 years ago

I don't know maybe I'm missing out something too.

Logs are either stored in a dir under root or in uploads.

If I pass $upload_dir['basedir'] . '/php-console/' . md5(FILE).'_pc.dat'; as you suggest I will still get:

Fatal error: Uncaught exception 'Exception' with message 'Path /srv/www/geobench/htdocs/wp-content/uploads/php-console/9fc5887c030f7a3e19821ebec457e719_pc.data is under DOCUMENT_ROOT. It's insecure!'

I don't think people would use PHP Console in production though and one could still automatically delete the file on plugin deactivation.

barbushin commented 9 years ago

Did you call PhpConsole\Connector::setPostponeStorage( new PhpConsole\Storage\File($filePath, false)); I mean don't you forgot to pass false as second argument?

unfulvio commented 9 years ago

Hi @barbushin sorry for the late reply - it appears we have fixed the issue :)

thanks!

barbushin commented 9 years ago

:+1: