Wednesday, August 1, 2007

Drupal PHP Pages

Last year, I created a large Drupal website with many custom extensions. I thought of a good way to add custom pages. It wasn't finished in 30 minutes per se, but it's somewhat of a quick hack, and is very convenient and efficient (if you happen to use Drupal 5).

At the time, I loved Drupal, but slowly I became aware of its disadvantages. The whole system is built for ease of administration; efficiency is secondary. This means that even though it looks and works perfectly on a local test machine, in a real environment the number of database queries and heavy RAM usage will hit the server hard.

When a Drupal page loads it makes an extreme amount of database queries to retrieve configuration, layouts, and even the page you are viewing. To me, it doesn't make sense to hold all of this in a database - it is a needless query. Sure, this way makes it easier to edit your pages as an admin, but it introduces needless inefficiency querying the database and transferring data. Static pages should be files on the server.

My site had several custom pages that had a static structure. The pages had PHP that would look into the Drupal database information manually. At first, I made these Drupal "Pages," which can contain PHP code, but it is very inconvinient to edit PHP code in that little textarea. So, I told Drupal to redirect from certain urls to open a php file on the server. This way I would have the convenience of a nice URL, an easy-to-edit file, and one less database call.

I made the change to index.php, the page that serves all page requests. It should be clear where to merge this.
// Menu status constants are integers; page content is a string.
if (is_int($return)) {
  switch ($return) {
    case MENU_NOT_FOUND:
  
    if ( substr($_GET['q'],0,2) == 'p/')
    {
    //This is a modification by Ben.
    //The idea behind this was to simplify creating normal PHP pages. The URL looks more natural
    //Another benefit is that less database calls are required.
  global $pageargs,$user, $myuserrole;
  $pageurl = substr($_GET['q'], 2);
  $pageargs = explode('/', $pageurl);
  
  $myuserrole = theme_getuser_role($user->roles);
  $purl = '';
  switch ($pageargs[0])
  {
    case 'home': $purl = 'home.inc'; break;
    
    case '_page1': $purl = 'my/page1.inc'; break;
    case '_page2': $purl = 'my/page2.inc'; break;
  }
  if ($purl)
  {
    $content = file_get_contents('pages/'.$purl);
    print theme('page', drupal_eval($content));
   }
   else
   {
    drupal_not_found();
   }
   
   } 
    else
      drupal_not_found();
      break;
    case MENU_ACCESS_DENIED:
      drupal_access_denied();
      break;
    case MENU_SITE_OFFLINE:
      drupal_site_offline();
      break;
  }
}
I didn't have the pretty-urls option enabled, but this should work if is on. In this example, I'm mapping ?q=p/home to the file pages/home.inc. Note that I am not letting any file be opened - only the ones in the switch are accessible. Also, I used the .inc extension because I don't want the file to be accessed individually as a .php file. Nonetheless, any php code will be executed normally, thanks to the drupal_eval function. I store the $myuserrole and $pageargs variables in a global var because they will be useful in those pages.

2 comments:

jitendra said...

ya its nice idea for nonupgrading drupal sites.....but if u try to hack or modify the drupal core index or code files it will loose all impact on next upgradation and site will got crashed .....

Bilal Khan said...

how to hack drupal
how to hack drupal,drupal exploiter,drupal exploiter,how to hack drupal website,drupal website hacking

http://bicombusiness.blogspot.com/2016/01/drupal-auto-3xploiter-for-drupal-hacking.html