Good day, I would like to read a PHP executed file (with a session) from my server with PHP, but once I call file_get_contents by passing the session ID, it doesnt works:
To check, I made a small test on my server, here is the test_reader.php
file:
session_start();
// if no test session, creating it & refreshing
if( !isset( $_SESSION['mysession'] ) ) {
$_SESSION['mysession'] = 'hello world';
header( 'Location: test_reader.php' );
}
// reading "test_readable.php"
$url = 'https://example.com/test_readable.php?';
$parameters = http_build_query( array(
'session' => session_id()
) );
$options = array( 'http' => array(
'method' => 'GET',
'content' => $parameters
) );
$context = stream_context_create( $options );
echo ( $url.$parameters ).': <br>'.file_get_contents( ( $url.$parameters ), false, $context );
And here is the test_readable.php
file:
// if session ID is sent, opening the session
if( isset( $_GET['session'] ) ) {
session_id( $_GET['session'] );
}
session_start();
// checking result
if( isset( $_SESSION['mysession'] ) ) {
echo 'yes';
} else {
echo 'no (id: '.session_id().')';
}
if( isset( $_GET['session'] ) ) {
echo ' but session ID found';
}
First of all it takes a minute to load the test_reader.php
when visiting it.
But in addition to this, there is no results at all:
https://example.com/test_readable.php?session=x75277c2a8fccfcc4d446ec7c93d84006:
Indeed, nothing from test_readable.php
has been printed.
So I made a var_dump
on the file_get_contents result to check the response:
bool(false)
And I don't understand why do my file is not read?
Do you know if it's coming from a session or a file_get_contents set up? Or do you know where it can come from?
Thank you in advance for your reply.
EDIT - TEST PRIVATE MODE FROM SCRATCH
test_reset.php
session_start();
$_SESSION['mysession'] = null;
unset( $_SESSION['mysession'] );
session_destroy();
test_readable.php
// if session ID is sent, opening the session
if( isset( $_GET['session'] ) ) {
session_id( $_GET['session'] );
}
session_start();
// checking result
if( isset( $_SESSION['mysession'] ) ) {
echo 'yes (id: '.session_id().')';
} else {
echo 'no (id: '.session_id().')';
}
if( isset( $_GET['session'] ) ) {
echo ' and session ID found';
}
test_reader.php
session_id( 'session'.rand( 1, 9 ).rand( 1, 9 ).rand( 1, 9 ) );
session_start();
echo '<div>'.session_id().' </div>';
$_SESSION['mysession'] = 'hello world';
$parameters = http_build_query( array(
'session' => session_id()
) );
$options = array( 'http' => array(
'method' => 'GET',
'content' => $parameters
) );
$context = stream_context_create( $options );
$url = 'https://example.com/test_readable.php?';
$read = file_get_contents( ( $url.$parameters ), false, $context );
// $read = file_get_contents( ( $url.$parameters ) );
echo '<div>'.( $url.$parameters ).' </div>';
echo '<div>'.$read.' </div>';
var_dump( $read );
Test trace:
https://example.com/test_reset.php
>> <empty page>
https://example.com/test_readable.php
>> no (id: 59081a4dfd8ea3acd10ebaafd432daaf)
https://example.com/test_reader.php
>> session432
>> https://example.com/test_readable.php?session=session432
>>
>> bool(false)
(Same result if I do not use the file_get_content with a context).
EDIT 2 - TEST WITHOUT CONTEXT / SOLVED
I didn't change other files, only the following-one:
test_reader.php
session_id( 'session'.rand( 1, 9 ).rand( 1, 9 ).rand( 1, 9 ) );
session_start();
$sessionID = session_id();
echo '<div>'.$sessionID.' </div>';
$_SESSION['mysession'] = 'hello world';
session_write_close();
$parameters = http_build_query( array(
'session' => $sessionID
) );
$url = 'https://example.com/test_readable.php?';
$read = file_get_contents( ( $url.$parameters ) );
echo '<div>'.( $url.$parameters ).' </div>';
echo '<div>'.$read.' </div>';
var_dump( $read );
Result was:
https://example.com/test_readable.php
>> no (id: 2d3b1d3e9d2975134bf3141d3c49c3d8)
https://example.com/test_reader.php
>> session849
>> https://example.com/test_readable.php?
>> no (id: ce844dd021a0e1d167a316a2e4cd08a0)
>> string(41) "no (id: ce844dd021a0e1d167a316a2e4cd08a0)"
CodePudding user response:
make sure that you destroyed the first session use this:
session_abort(); // add this line
// set the new session
session_id( $_GET['session'] );
session_start();
// checking result
if( isset( $_SESSION['mysession'] ) ) {
echo 'yes';
} else {
echo 'no (id: '.session_id().')';
}
if( isset( $_GET['session'] ) ) {
echo ' but session ID found';
}
CodePudding user response:
The usage of the stream context makes little sense there. content
specifies what is to be send as the request body - but GET requests don't send their data in the body. You should completely remove the stream context, and then simply append your parameter to the URL.
And when using file-based session storage, PHP puts a lock on the session file, as long as one script instance is still "using" it. So trying to set the session value here in the same script that makes the request to the other one that is supposed to use the same session, will only properly work, if you call session_write_close
, before you make the request. That writes all session changes out to the disk, and then releases the lock on the session file.