@madpilot makes

Cookie-less sessions in PHP

There is a fairly good chance that all but the most trivial dynamic sites will use sessions to emulate a stateful environment. Before the creation of sessions, the developer would have to manually pass all of the variables the next page needed via hidden input fields or cookies. As you can imagine, this is a bit of a security risk. Not to mention that cookies are limited to 4k each – if you have a large number of variables, this can quickly run out.

PHP, like most server languages can handle your sessions for you – but how does PHP keep track of sessions? There are two ways – using cookies and hidden fields. The former is the preferred way as it is easiest and is more secure (But not with out it’s risks. Check out the PHP session documentation for more info on the safe use of session variables). PHP writes a cookie which holds the PHPSESSID variable. It looks for this value when start_session() is called and if it exists, matches it to the stored session. But what happens when cookies aren’t available or are turned off? PHP is smart enough to work this out and will re-write all links and forms on the fly to ensure that the PHPSESSID is passed on every action that will refresh the page.

Well, almost. When I code, I prefer to postback to the same page, do some processing (such as error validation and storing of required session variables) and then use header(“Location: “) to re-direct the user. This makes coding much easier because all of the business logic for that page is kept in one file. Unfortunately, PHP isn’t smart enough to re-write these redirect, so we will have to help it out a bit.

append_sid

The following function will look at a URL (Whether it be relative or absolute) and append the SID if and only if PHP is in cookieless mode. I couldn’t find a PHP function that will tell you whether cookies are working, however after a bit of thought it was quite easy. PHP has a super-global called $_COOKIES. In this super-global, the PHPSESSID variable is referrenced. By checking whether it exists (After a call to session_start) we can work out whether we are in cookie or cookie-less mode:

function append_sid($link) {
    if(session_id() !== NULL && !isset($_COOKIE['PHPSESSID'])) {
        if(strpos($link, "?") === FALSE) {
            return $link . "?PHPSESSID=" . session_id();
        } else {
            return $link . "&PHPSESSID=" . session_id();
        }
    } else {
        return $link;
    }
}

Basically what happens, if the function checks to see if the session has been started – if it has, it then checks if the cookie entry exists. If it does, it just returns the link unchanged, otherwise it appends the session id. The inner most if statement checks for a ‘?’. If it exists, we can assume that the link already has some get parameters, so we will append the PHPSESSID using an ‘&’. Otherwise, just append it with a ‘?’.

JavaScript

Don’t forget that if you are re-directing client using javascript or using sessions when making AJAX calls you need to pass the session id as well. The best way to do that is client side, especically if you are generating parameters on the fly. The same theory applies, except we will use JavaScript this time:

function append_sid(link) {
    <?php if(session_id() !== NULL &#038;&#038; !isset($_COOKIE['PHPSESSID'])) { ?>
        var session_id = '<?php echo session_id ?>';
        if(link.indexOf('?') == -1) {
            return link + '?PHPSESSID=' + session_id;
        } else {
            return link + '&PHPSESSID=' + session_id;
        }
    <?php } else { ?>
        return link;
    <?php } ?>
}

The reason there is PHP code interleaved (I know. I hate it too) is because we need to work out whether the session has actually been started and we need the session_id. However, we don’t want to display the session id UNLESS there is a requirement for it as it can be a security risk.

A caveat – passing session id by URL requires the session.session.use_trans_sid tio be set to 1. Most shared hosts turn this off, but you can usually override it by putting:

php_value session.use_trans_sid = 1

in the .htaccess file. You can also try the function:

ini_set('session.use_trans_sid', '1')

On every PHP page.

Now, hopefully, you won’t be cutting off those users that don’t use cookies!

Ruby on Rails highlighting in Dreamweaver

I found this site that outlines how to setup code highlighting and hinting in Dreamweaver MX.

In short – the instructions for code highlighting is here and the xml for code completion is here. (I would duplicate it here, but my version of wordpress doesn’t allow xml :( )

The only thing I did different was to create a file called Ruby.xml in the CodeColoring directory with and cut and paste the code colouring xml inbetween codeColouring tags (Have a look at one of the other XML files to get what I mean).

Unfortunately, I still haven’t gotten the .rhtml files highlighting correctly. I’ll keep you posted.

Sub-directories on rails

I haven’t been able to find this anywhere in literature (I’m sure it is somewhere, I just haven’t figured a good enough google search string to find it), but I wanted to be able to use sub directories to partition different areas in Ruby on Rails.

e.g /admin /admin/articles etc

Ruby on rails uses the following mappings between the URL and the controller:

http://www.url.com/application/controller/action/id

which maps to a AcitonController class called controller which has a method called action

I wanted to have multiple a controller directories:

http://www.url.com/application/controller/subcontroller/action/id

You do this by creating a sub directory under the controller directory (in this case called controller) and creating file called subcontroller_controller.rb – The class declaration of this file should be Controller::SubControllerController < ApplicationController.

 

So, if you wanted to create a controller called articles in the sub directory admin you would create:

  1. The subdirectory “admin” under the controllers directory
  2. The file articles_controller.rb in the controllers/admin directory
  3. Declare the class as: Admin::ArticlesController < ApplicationController

You also need to create the corresponding .rhtml files in a sub directory in the views folder…

Developing for Accessibility

Accessibility, as the name suggests is about making websites accessible to as many users as possible. Unfortunately, not everyone on the planet has 20/20 vision, or full use of their hands, which can make using traditional web sites difficult – why should they be disadvantaged by not being able to harness the plethora of information out in cyberspace? Even beyond that, there are many able-body web users that are using non-standard browsers and software to access websites. PDAs, mobile phones and hand held game machines (such as the Sony PSP) are examples of systems that have restricted screen sizes and memory footprints which makes packing a full blown web browser impossible. Another benefit of an accessible website is it makes the search engine robots’ job much easier.

Different ways of using the web

The web is no longer confined to the walls on universities, or geeky tech type people – 14 million people in Australia have access to the internet [Nielsen/NetRatings]. Even if you ignored 5% of that audience, that is potentially 700,000 people that cannot access your website. This is especially relevent to government websites who theoretically should be targeting everyone.

There is no way of guaranteeing that all of these users are using standard desktop setups either: some variations include:

  • Screen readers: These programs are used by sight-impaired users. They read in the HTML markup and read it out using a synthesised voice. These system tend not to understand JavaScript or Flash.
  • Braille readers: Again used by sight-imparied users. Very much like a screen reader, except they output the page in Braille
  • PDA/Mobile phone: very handy for those who are out on the road a lot. These usually have a reduced screen size, and limited memory. They also have different method of inputting data, so things like JavaScript menus will probably not work.
  • Slow internet connections: People out in the bush (Or even the suburbs) may not be able to get broadband, or reliable modem connections. So there may still be a number of people that try to reduce bandwith by switching off images.
  • Text-only browsers: Not really sure why you would still use these other than because you can – although, they can provide a good indication of what your site looks like to a search engine spider.

Accessibility and Standards

The basics of accessibility can be acheived by following the World Wide Web Consortium (W3C) standards documents. These standards are about creating semantic, structured layout that can easily be intepreted by any system that understands the standards. The standards break up the structure layer and the presentation layer, by usingl Cascading Style Sheets (CSS), which effectively gives the designer control over how an element looks without destroying the document structure. The names of HTML tags have been carefully selected to decribe document elements. Unfortunately, in the old days, many designers abused the default display properties of some elements, misusing them to present information in a certain style.

For example, an old trick to indent text would be to wrap it in tags. It is hard to image how a screen reader would handle this – it comes across some text it expects to be an un-ordered list, only to find a block of text. The correct way of doing this would be to wrap it intags, and use the CSS property padding-left to indent the whole block.

Before CSS, it was common to mix up the order of items in the HTML to fit the presentation of the page. This means that a user running a screen reader would have the contents read out in the wrong order… Not very usable at all.

Don’t rely on colour

Colour blindness is a condition that stops the sufferer for perceiving certain colours. This can create two potential problems for the web designer – foreground-background contrast and colour for notification. Any user with normal vision knows how hard it is to read dark blue text on a black background – because the contract between the two colours in not enough. However, there are certain colour combinations that would be fine for non-colour blind people, but would work for those that did have the deficiency.

To be continued… [I’ve to go to my exam now – this will be interesting]

Final Exam Draft – Accessability

I’m about to sit the final exam of my university degree this afternoon. It is for a unit called Internet Technologies, and I have to write two essays – “Pretend you are writing two articles for a technical magazine. You cannot select the topic you covered in your talk or project”. The list of topics are:

  1. C#
  2. ASP.NET
  3. Advanced ASP.NET: UserControls
  4. SQL Server 2005 & ADO.NET
  5. Handling session information in a ASP.NET application
  6. Security. Authorization and authentication in ASP.NET, .NET Framework and C#
  7. Design Patterns
  8. Intro to source code control & Use of CVS
  9. Intro to issue and bug tracking. Use of Issue/Bug Tracking software
  10. Open Source: The impact on corporate development practices
  11. Introduction to SOAP & Web Services
  12. XHTML and CSS2
  13. XML and XSLT
  14. LDAP and DirectoryServices in .NET
  15. Refactoring
  16. Agile processes & Extreme Programming
  17. Advanced C#: New features
  18. Team Foundation Server: Collaborative Development Environments
  19. .NET Compact Framework: Developing for PDAs and Phones
  20. C# and MS.NET vs Java J2EE: Pros and Cons
  21. Developing for Accessibility
  22. HCI Issues in web applications

Since my talk was on Design Patterns and my project was on Web Services, I have selected Developing for Accessibility and XML and XSLT. Since I have a pretty bad case of the flu, I thought I might draft them here first to try and coerce my brain into a thinking mode again. Wish me luck :)

Insipration

…is drinks with your peers and talking about what matters to you most.

…is like minded people throwing ideas around, making you think about things you haven’t thought about before

…is realising that your opinions do matter, and there is always someone that is interested.

Deployment Systems

I recently read about the deployment model that Flickr uses. After picking my self up from the floor, it made me think about my own deployment methods, and I have started implementing a new system, which I though I would share.

First off all, let me describe the types of projects that I have to deploy:

  1. Internal MadPilot or Personal projects – i.e. stuff hosted on the server at my house (which also doubles as my development server)
  2. External projects that I can take a local copy of to work on
  3. External projects that I am forced to work on “off-site” i.e on the clients server.

The deployment system I will describe here covers project type 1 and 2. Not much I can really do with 3, as I have no control over other people’s servers…

Most of the projects I work on, I’m the only developer, but the system described is designed to scale to multiple developers.

Step 1: Set up a subversion repository

I have my subversion repository structured as such: [svn_root]/MadPilot/Clients/[client_name]/[job_name]/

Because I do a lot of outsourced work, I use the job_name to denote different jobs for the same client. If the client is a one off (i.e. the client isn’t another web company) I will usually leave this off. The website code will be stored in the Website directory. This allows me to store documentation and other bits and bobs outside the development tree.

Step 2: Checkout the empty tree

Next I create development and test directories with in my webserver: usually of the form [web_root]/clients/[client_name]/[job_name]/dev/[developer_name] and /clients/[client_name]/[job_name]/test.

I then check out the empty subversion tree to all of the directories so that they become under source control.

Step 3: Setup the webserver

At this point I will set up a virtual host for the client of the form [developer].dev.[job_name].[client_name].clients.madpilot.com.au and test.[job_name].[client_name].clients.madpilot.com.au (Yes, this does end up with stupidly long URLS, but I prefer them to be descriptive. No one sees them other than the client anyway…)

Step 4: Import the initial tree

It is at this point I download the existing site, or start a fresh if it is a from-scratch job. I then add all the files to the repository.

Step 5: Setup any databases

I try to make sure that every developer has a separate database, so does the test system. Usually named [client_name_[job_name]_[development_name]

Using the system

When you start working on a project, you make sure you login to your working directory on the server (usually via SSH) and do a subversion check out. When you finish, you check your work back in. When the system is at the point of testing by the client, you check everything out to the test site.

Using subversion means that you have a versioned backup of all the code, and you can manage multiple developers and a test system at the same time.

Going to production

This can be the tricky bit. For projects on my server, I usually just do an export into the production directory. If the system was tested well enough, if should just work. Gotchas include paths to local files and permissions, but this should be documented anyway.

On external systems, this can be a little more difficult. At the moment, I export the code into a temporary directory, and manually FTP the files up. I hope to be able to automate this in some way, even if it will just reduce me typing.

Next thing to do is to write a nice web front end to subversion so I can do “one-click” deployment… Ahhh :)

So that is my plan – what does everyone else do?

Oh happy days!

Just did my honours thesis seminar. Was pretty under-prepared, but I think I swung it. Now, I just need to hand in my poster (It’s at the printers) and all that is left of my university career is one exam. Woot!

Six years of toil has culminated to one anti-climatic week. Still a relief though – psychologically, it has been a huge weight lifted, although things that I’ve said I would do “after my thesis” have just moved up a notch on my todo list.

I really want to get some work done on Taste.net.au soon (Hurry up Ruby books!), but I’m enjoying the freelancing at the moment (That’s right kids, I’m back on the market!)

And I’m looking for to my day off on Wednesday, because my beautiful girl, Giovanna is back from Sydney (Longest week ever!) and we are going spend the day together.

Things are lookin’ up. :)

PHP 5 and MVC

I quick entry today, as I really should be working.

I came across a PHP MVC (Model/View/Controller) framework for PHP 5 – You can think of it as the Rails bit of Ruby on Rails. It is this sort of stuff that will continue to push PHP into the spotlight and allow it to compete with the big boys…

It is called Agavi PHP MVC Framework

Web 2.0 – The Ultimate Collaborative Development Environment?

Web 2.0 is about data exchange and classification. Taking a high-level look at software design process one of areas that is good in theory, that fails in practice is data exchange and classification.

Think about the last software project you worked on – would a new programmer be able to pick up the documentation and work out what is going on? Could they be able to find the documentation? Was there documentation at all?

Documentation is all about data exchange – I bet if you went through your email or project mailing lists you could piece together a decent amount of usable documentation (Implementation decisions, solutions, bug reports etc) – Can Web 2.0 provide the glue to ease the burden of documentation?

Imagine being able to tag bugs and design decisions so searching for a bug returns a link that points to the design documents and comments entered at check-in. This gives the developer background information quickly – and these docs are living and more easily maintainable. As a developer, you don’t have to change to documentation mode – it is already part of your work flow (Other than remembering to enter check-in comments – but you already do that don’t you?)

We don’t necessarly have to limit this to documentation either. Project managers could use it to gauge where the project is at, clients could actually report bugs with out having to learn an obscure bug reporting interface or software terminology. How about timesheets? Add an entry stating you started work at a particular time, and then enter another entry saying you finish at a particular time – tag it wit the project name, maybe what part of the project you were working on – Voila! Or meeting minutes – these often have action items interleaved – tag them and make them searchable. Tag them as completed when you are done.

But I think the best bit is that it wouldn’t require anything more than an email client or a blog-like web interface. EVERYTHING IN ONE PLACE! I know I personally hate having to log in to a different apps for bugs, and meeting minutes etc. We should be letting the software organise our data, and leveraging search.

I think I will be revisiting this one soon…

Previous Next