Access Drupal functions and session from a PHP script in a site subdirectory
If you want to use Drupal sessions and the logged in user object from a straight PHP script not at Drupal root but somewhere in subdirectories in a site, you will probably need to do something like I endend up doing in profiles/scf/switch.php to impersonate the Drupal site root directory.
In fact, I think the partial installation profile idea might need something like this.
(Skip down to resolution.)
Some test output code used to figure out what the domains and sessions were doing:
<?php
// global $user;
// print var_export($user,TRUE);
global $cookie_domain;
// print $cookie_domain;
print '?' . $session_name . '!!';
print session_name();
print 'cookie!!!' . $_COOKIE[session_name()]; // $cookie_domain;
?>
We started out trying minimal... it didn't stay that way.
<?php
/*
// Minimum load of components.
drupal_bootstrap(DRUPAL_BOOTSTRAP_DATABASE);
// require_once './includes/file.inc';
include_once './includes/module.inc';
drupal_load('module', 'system');
*/
/*
require_once './includes/install.inc';
require_once './includes/file.inc';
require_once './modules/system/system.install';
// Load module basics.
include_once './includes/module.inc';
$module_list['system']['filename'] = 'modules/system/system.module';
$module_list['filter']['filename'] = 'modules/filter/filter.module';
module_list(TRUE, FALSE, FALSE, $module_list);
drupal_load('module', 'system');
drupal_load('module', 'filter');
*/
?>
Resolution
<?php
/**
* In which we jump through some hoops to make Drupal treat
* profiles/scf/switch.php just like the root-level index.php or update.php
*/
// remove '/profiles/scf' from current working directory and set our directory
$base_dir = substr(getcwd(), 0, -13);
chdir($base_dir);
// ini_set('include_path', '.:' . $base_dir); - use of ./ makes this not work
global $base_url;
// duplicated from bootstrap.inc conf_init().
// Create base URL
$base_root = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') ? 'https' : 'http';
// As $_SERVER['HTTP_HOST'] is user input, ensure it only contains
// characters allowed in hostnames.
$base_url = $base_root .= '://'. preg_replace('/[^a-z0-9-:._]/i', '', $_SERVER['HTTP_HOST']);
// $_SERVER['SCRIPT_NAME'] can, in contrast to $_SERVER['PHP_SELF'], not
// be modified by a visitor.
if ($dir = trim(dirname($_SERVER['SCRIPT_NAME']), '\,/')) {
$base_path = "/$dir";
$base_url .= $base_path;
}
$base_url = substr($base_url, 0, -13);
require_once
'./includes/bootstrap.inc';
// we need the $user variable, theming... i think we have to go all the way
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL); // DRUPAL_BOOTSTRAP_CONFIGURATION
drupal_maintenance_theme();
?>
Comments
Perfect solution for amfphp
I was breaking my head over how to initiate Drupal with amfphp, which is located in amfphp/services/myservice/myservice.php. I only had to adjust a couple of lines (the ones relating to your specific switch.php case) and it works perfectly now. Thanks a lot!
Cool!
I love it when solving problems solves other problems...
Job well Done
Thanks Benjamin,
i was working on it for such long time. great work
Regards
Very Awesome
Thanks!
I was dealing with this problem for only about 15 minutes before I decided to look online and found your tutorial, but after I gave it a shot, everything was up and working in 5 minutes. This was a great little code snippet for sure. Thanks for posting it online!
Thanks!
John Murray
Thank you for this post; it
Thank you for this post; it saved me quite a bit of headache.
Thanks so much, I have been
Thanks so much, I have been wracking my brain trying to figure out how to do this for a few hours now...
Great post
I spent about an hour trying to figure this out before I found your post. Thanks!
Drupal 7
For drupal 7 you should add
define('DRUPAL_ROOT', getcwd());
Right above the require bootstrap function. It was introduced in D7, and the snippet will fail without it.
Thanks for the snippet !
Post new comment