When the “Python Vs PHP” war matters

February 21st, 2008

Yesterday I had a meet­ing with a cus­tomer about a new site I should develop for them. Since they’re a book pub­lisher, they wanted an online book store. Apart from the tech­ni­cal details (the site isn’t as simple as you may believe, they need a lot of not-so-easy-to-do stuff), the most impor­tant point we focused on is the fact that they have an inter­nal IT tech­ni­cian that han­dles all their com­puter needs. If you’re asking your­self why this mat­ters, keep reading:

  • me (to be precise, my company) stopped development of PHP sites about one year ago in favor of Python
  • we release the web site’s code to them
  • for this project, we haven’t been asked any kind of future support; this means that when the site is finished, we won’t touch the product anymore (unless they don’t pay us to do the modifies they need)
  • but they don’t want to pay us to these modifies, because they have their internal IT technician
  • their technician knows only PHP (and he never even known the Python’s existence until yesterday)

(Con­tinue reading…)

PHP, PATH_INFO and url-friendly site

April 9th, 2006

These days I had to redesign a company’s site layout, due to host­ing ser­vices upgrades. Before, they were simple static HTML pages: now, they are (not really, they are about to be…) dynamic gen­er­ated ones. I cannot use mod_rewrite since the hoster dis­abled it due to secu­rity issues (?).
So I had to look for other ways to get a URL-​friendly site. The answer came from the phpinfo(); func­tion. I looked at the gen­er­ated page if there were some para­me­ter that well fits to have a URL friendly site. So I dis­cov­ered PATH_INFO.
I’m using PHP since a long time but I never heard such a fea­ture, so I had to learn some­thing new.
We can have, in this way, a URL like this: http://​www.​site.​com/​p​a​g​e​.​p​h​p​/​s​e​c​t​i​o​n​/​s​u​b​s​e​c​t​i​o​n​/​s​u​b​s​u​b​s​e​ction that can easily become using apache .htaccess (if the hoster sup­ports it, obvi­ously) like this: http://​www.​site.​com/​p​a​g​e​/​s​e​c​t​i​o​n​/​s​u​b​s​e​c​t​i​o​n​/​s​u​b​s​u​b​s​e​ction, hence by remov­ing the .php exten­sion and by make the php page as another sub­di­rec­tory (I’ll describe how to do this later).

So let start look­ing at how PATH_INFO works.
First of all, let create a page called page.php that will handle the para­me­ter pass­ing. Now let sup­pose that we are pass­ing a URL like this: /page.php/section/subsection. We will found in PATH_INFO some­thing like this: /section/subsection. Hence, sup­pose we want to show the file named “section_subsection.php” in the pages/ direc­tory. Simply, a $array = explode('/', $_SERVER['PATH_INFO']); will give us “sec­tion” into $array[0] and “sub­sec­tion” into $array[1]. Now you just need to con­cate­nate the two array ele­ments and adding .php (or what­ever you want) exten­sion and, after check­ing the file exis­tance, you’ll have the work done.

Thats the code I used in order to achieve such effect (the code that’s in pro­duc­tion, I am still work­ing on it so it may have some error):

<?php
  require(dirname(__FILE__) . "/config.php");
  require(dirname(__FILE__) . "/functions.php");

  $exclude_list = array("img", "frontpage");

  if (!isset($_SERVER['PATH_INFO']))
    header("Location: {$_CONFIG['url']}{$_CONFIG['pager']}/home");
  else $tpath = $_SERVER['PATH_INFO'];

  $tpath = explode('/', $tpath);
  $path = $tpath[1];
  if (isset($tpath[2]))
    $subpath = $tpath[2];
  else $subpath = "";

  $exclude = FALSE;
  foreach($exclude_list as $exc)
    if ($exc == $path)
      $exclude = TRUE;

  if (!$exclude) {
    if ((count($tpath) > 3) || (!file_exists(dirname(__FILE__) . "/pages/" . $path . ".php")))
      $page = "/pages/404.php";
    else {
      // if $subpath exists, we have /path/subpath, traslated as path_subpath.php
      if ($subpath !== "")
        $page = "/pages/" . $path . "_" . $subpath . ".php";
      else $page = "/pages/$path.php";
    }

    ob_start("ob_gzhandler");
    require(dirname(__FILE__) . "/head.php");
    require(dirname(__FILE__) . "/title.php");
    require(dirname(__FILE__) . "/menu.php");
    echo "<div id="content">n";
    require(dirname(__FILE__) . $page);
    echo "</div> <!--/content -->n";
    require(dirname(__FILE__) . "/footer.php");
    ob_end_flush();
  } else {
    $fullpath = implode('/', $tpath);
    $fp = fopen(dirname(__FILE__) . $fullpath, "r");
    $contents = fread($fp, filesize(dirname(__FILE__) . $fullpath));
    echo $contents;
  }
?>

Let anal­ize it. Firstly, why do we have an $exclude_list? This is needed because with this way of URL han­dling, every file that we will request under the site path will pass from that script. So, since we want to dis­play images and other things, just take the file as they are and print them out if such path is in the exclude list.
I used a couple of $_CONFIG values (that I define in con​fig.php) to have a cen­tral­ized con­fig­u­ra­tion system. Specif­i­cally, $_CONFIG['url'] will con­tain the site’s URL, while $_CONFIG['pager'] will con­tain the file­name of the script that will handle the PATH_INFO data, in our case page.php.

Suc­ces­sively, there’s a check about the file exis­tence into the /pages direc­tory. The rest is just the use of the buffered output since I some­times use a header() call in the other pages both to redi­rect the user to some other page and to set the right error­code for a 404 page.

Of course there are some improve­ments that could be done. Prob­a­bly, the most impor­tant lim­i­ta­tion in the script now is that it has a limit of two sub­sec­tions (like /section/subsection). This limit could be expanded by doing some­thing like this: implode('_', explode('/', $tpath)); but will need more checks for consistency.

Another thing: as I said before, you could want to delete the .php suffix on the page.php. This can be done by putting this lines in the .htaccess:

<files page>
ForceType application/x-httpd-php
</files>

In this way we will force apache to call page.php if it is called as page only.

That’s all :) I have to make shorter posts, I know.

1 Comment, tagged with PHP

Microblogging

  1. January 28th

    1. Finally something to eat! http://t.co/FH3x3oGR [krat]

      1:10am via Twitter

  2. January 27th

    1. Finally some cleanup on my inbox. Feels cleaner now. [krat]

      5:13pm via Twitter

  3. January 26th

    1. panzerotti & peroni [krat]

      7:49pm via Twitter

  4. January 25th

    1. I lost count of how many times I wanted to expand the tweet stream and clicked "favorite" instead [krat]

      11:15am via Twitter

  5. January 23rd

    1. It's hateful when you have to chase people who owe you some money [krat]

      5:45pm via Twitter

    Powered by Lifestream.

Search