1 | 2

1 - 5   [7]

CVS Tutorial

Relates to Peregrinations

After several previously unsuccessful attempts to start using CVS to manage my workflow, this lucid learn by example tutorial from the latest issue of PHP|Architect has pointed me in the right direction. Using the command shell version in Cygwin, I now have two repositories set up - the one for development projects, and the other for client websites. No more sticky and scribbled notes scattered around my office, and all those old (and somewhat mangled) README log files have been discarded for recycling. Of course once the basics were mastered it was time to move onto the Cederqvist!

Posted on Nov 18, 2003 at 18:04:44. [Comments for CVS Tutorial- 0]

IE5.0 Versus IE5.5

Relates to Accessibility and Exploder

I am a strong advocate of accessibility, and make every effort to sell and build website for clients that are conforming to the WCAG, while maintaining Web Standards and page validity. For all the hard work, sometimes those ever so standards-friendly browsers from Micro$oft put a spanner in the works!

On completion of a recent website, with all the usual set of validity and accessibility tests, I was perturbed to hear from the client that the display on screen was total chaos! As it turned out, they had just had MS 2000 Pro installed, accompanied by IE5.0 as the default browser. While I urged them to upgrade their browsers, it was conceivable that a portion of the target audience would also be using IE5.0, and so the pages were not accessible. A few weeks ago, this would have been a real issue with no way for me to test where the problems were arising, but fortunately recent discoveries allow testing over the full range of IE browsers.

So I got to testing, and soon traced down the glitches to a couple of CSS incompatibility issues for IE5.0. The major cause of so much destruction was the use of relative for container positioning, and IE5.0's reluctance to acknowledge the height attributes in these containers. I knew declaring position:relative was a cause for disappearing elements across IE5.x and had formulated personal guidelines for using this declaration, but did not know it could eat appart the display in IE5.0.

Most CSS hacks for hiding code seem to classify IE5.x as a single entity, but in this case I needed to write different code for IE5.0 and IE5.5, otherwise one of them would fail to display correctly. The best solution I found in the archives is the following snippet:


div#id {
  position: static;               [1]
  position/* */:/**/:relative;    [2]
  position:relative;              [3]
}

  1. Line [1] is read by all browsers - final value for IE5.0
  2. Line [2] is ignored by IE5.0 and IE5.5 but read by all other browsers
  3. Line [3] is also ignored by IE5.0 but is read by IE5.5 - final value for IE5.5

It is a great shame when so much work is put into accessibility for all browser mediums and users, yet making a site accessible for the client rests on a bunch of ugly hacks! I suppose a better long term solution to this would be to separate this bunch of IE CSS hacks using Tantek's Mid Pass Filter. Then, once these legacy browsers have finally been put down, the hacked files could just be discarded.

Posted on Nov 18, 2003 at 18:03:00. [Comments for IE5.0 Versus IE5.5- 0]

MySQL Summarizing

Relates to MySQL and Databases

Another little SQL snippet here for MySQL. This one is useful when summarizing <select> data from an HTML form (perhaps stored as an ENUM datatype).


SELECT @total := COUNT(*),
       @offices := COUNT(IF(type='offices',1,NULL)),
       @units := COUNT(IF(type='units',1,NULL))
       FROM `tblunits`;                   
SELECT CONCAT(@total, ' [', 
              @offices, ' office', 
              IF(@offices != 1,'s',''), ', ', 
              @units, ' unit', 
              IF(@units != 1, 's',''), 
              ']');                    

Once again these two queries utilise variables, and make use of conditional testing within a COUNT function to calculate the summaries. The CONCAT could just as easily have been done in PHP, but I chose to use the PEAR::Package::DB getOne() call. Short and simple!

Posted on Nov 14, 2003 at 03:42:03. [Comments for MySQL Summarizing- 0]

Using MySQL Variables

Relates to MySQL and Databases

Here is a code snippet demonstrating the use of MySQL variables in a set of queries. The problem was to find the longest standing entry in a table for a custom CMS I am building. The date added is a timestamp datatype.


SELECT @min := MIN(added) FROM tbldirectory;
SELECT @interval := UNIX_TIMESTAMP(NOW()) - UNIX_TIMESTAMP(added),
       @name := name 
       FROM tbldirectory WHERE added = @min;
SELECT @weeks := MOD(FLOOR(@interval / (7 * 24 * 60 * 60)),52) as weeks,
       @years:= FLOOR(@interval / (7 * 24 * 60 * 60 * 52)) as years,
       CONCAT(@years, ' year', IF (@years!=1,'s',''), ' and ',
              @weeks, ' week', IF (@weeks!=1,'s','')) as duration,
       @name as name;

I wanted to display the length of time in years and weeks, so once a variable (@interval) was set to the duration in seconds, I used some basic arithmetic with the FLOOR and MOD functions to get the appropriate values. To keep the final select query readable I stored the week and year calculations in variables and then used the CONCAT function to build the required string.

Using the variables and functions in MySQL queries is a great way to reduce unnecessary formatting of the data within the API, and now the query result is ready to go straight into the template. The MySQL Control Centre has a useful SQL editor for building complex query strings step by step.

Posted on Nov 10, 2003 at 02:22:21. [Comments for Using MySQL Variables- 0]

PHP Session Management

Relates to PHP and Apache

I have rarely been content with session management in PHP. Since the web is stateless, a session must be maintained on a login site. The optimal way to achieve this is to place a session cookie, in the form of a session ID (a 32 byte alpha-numeric string), on the client. When the client has cookies disabled PHP appends the session ID to the end of each URI on the page. This latter practice comes with inherent complications. Server redirects must have the session ID hard coded into the source, which I sometimes find complicated to manage in complex validation and redirection scripts over multiple pages. Security Focus also highlights the major vulnerability of passing the session ID in the URI for PHP versions prior to 4.3.2.

When testing with cookies disabled I have also found browsing Back a number of pages can inadvertently destroy the session. If not coded carefully, the outcome can be a blank page, leaving the user confused and likely to just leave the site. My opinion is that the safest and most usable solution is to only allow the login process to proceed if cookies are enabled. If they are not a message is presented to the user with recommendations and advice on enabling session cookies and the implications of doing so.

So, the challenge is creating a user friendly process, where the user is informed immediately if they are unable to log in, and directions are given on enabling session cookies. The problem is that when a page first loads, the cookie is only passed to the client, so there is no way of knowing if the cookie has actually been set, and hence whether cookies are enabled. The following code snippet resolves this.


if (! isset($_COOKIE["PHPSESSID"]) && ! isset($_GET["PHPSESSID"]))
{  
  $sess_id = substr(SID,(strrpos(SID,"=")+1));
  $redirect_url = CMS . "init.session_" . $sess_id;
  header("Location: " . $redirect_url);
  exit;
}
elseif (! isset($_COOKIE["PHPSESSID"]) && isset($_GET["PHPSESSID"]))
{  
  $cookies_disabled = true;
}
else
{
  $cookie_disabled = false;
}

First the code tests for the cookie, and if it does not exists it looks for the PHPSESSID variable in the global $_GET array. If the tests fails, then the user has arrived at the page for the first time so it is not possible to tell if cookies are enabled or not. So, a server redirect is done to the same page (here defined by CMS in the initialisation file) with a custom string appended to the end. A custom string is used to enhance security, and the Apache mod_rewrite module is used to rebuild the URI as follows:


RewriteEngine On
RewriteRule init.session_([a-z0-9]{32})$ /cms/?PHPSESSID=$1

When the page reloads it runs the same test again. This time it passes the second condition and will only fail on the first condition if cookies are disabled. At this point a notice can be displayed to the user advising them that cookies must be enabled to actually log-in. To enhance the usability, if $cookies_enabled $cookies_disabled is true, a class is added to the login form, which overrides the normal CSS declarations, disabling the input fields and striking out corresponding labels. To aid users of assistive technologies, a title is also appended to each label stating that fields are disabled because cookies are required.

Perhaps this is common practice, but I recall in the past having trouble finding useful information for PHP session management best practices, and this seems to be an effective approach. The whole process is transparent to the user, and incorporating mod_rewrite to cloak the session id raises the level of security for the initial server redirect in which it is passed, as well as replacing the aesthetically displeasing URI string:

http://mysite/login/?PHPSESSID=sessionid

with the more comprehendable:

http://mysite/login/init.session,sessionid

If the initialisation variable session.name is changed to something other than PHPSESSID (or session_name(string) is called) then the URI becomes much harder to hack.

Posted on Nov 10, 2003 at 02:19:13. [Comments for PHP Session Management- 6]

Breadcrumbs Trail

[ Home ] -> TW Blog -> Archives for November 2003
Site Map

The Severn Solutions website achieves the following standards:

[ XHTML 1.0 ] [ CSS 2 ] [ WAI AA ] [ Bobby AA ]

Page compiled in 0.011 seconds