Things I Can’t Remember – PHP Cookies

This is a simple example of setting a cookie and then using it to display a different splash page each time someone visits the site.

PHP cookies are described at the PHP manual site. Two things to remember about PHP cookies. They must be set before any <html> or <head> tags. And they are read before the page is loaded—so you can’t read the cookie value the first time someone visits your site.

I put the following code into the definitions section of my header. I like to use variables for each of the parameters so that it’s easier to see what I’m changing. $c_name is the name of the cookie. Once it is set it can be accessed from any page on the site. $c_time is expiration time in seconds. In this case 30 days.

$c_path = ”; and $c_domain = ”; mean that this cookie is available everywhere on the site. This cookie doesn’t contain any sensitive information, it’s just a counter, so I don’t need to use https for transmitting and retrieving it. Setting $c_httponly to ‘true’ makes the cookie inaccessible to scripting languages and guards against XSS attacks.

The if statement checks to see if the cookie is already set. If not, it sets the value of $_COOKIE[“spalsh_page”] to 0. Then it uses the parameters to set the cookie.

If there is a cookie already set, then I read the value, add one to it and update the cookie.


$c_name = "splash_page"; 
$c_time = time()+60*60*24*30;
$c_path = '';
$c_domain = '';
$c_secure = 'false';
$c_httponly = 'true';

if( !isset($_COOKIE[$c_name]) ) {
    $_COOKIE[$c_name] = 0;
    setcookie($c_name,0,$c_time, $c_path,$c_domain,$secure, $c_httponly);
} else {
  $c_value = $_COOKIE[$c_name] + 1;
  setcookie($c_name,$c_value,$c_time,$c_path,$c_domain,$secure,$c_httponly);
}

Next I’m going to access the counter and decide which page to display. $splashPage is an array of pages to include. The if statement checks to see if there is a cookie set. Cookie values start at 0 and go on forever. I use the modulus operator % to restrict the value of $whichPage to a value between 0 and $numPages. The require statement just looks in the array and serves up the appropriate page.


$splashPage = array (
      "Deceiving",
      "WellGolly",
      "Combos",
      "SlipIntoView",
      "Checklists",
      "Coartic",
      "Crossword",
      "Artic",
);
$numPages = count($mainPage);

if (isset($_COOKIE['splash_page'])) {
  $whichPage = $_COOKIE['splash_page'] % $numPages;
} else {
  $whichPage = rand(0,$numPages);
}
require_once("./splashPage/$splashPage[$whichPage].inc");

Things I Can’t Remember – REGEX

When using BBEdit I often want to see just the first part of a line. This REGEX expression has two parts. The first part looks for the first 75 characters and the second part looks for all the rest. Then I just replace the found string with the first part.


Search String:       ^(.{75})(.*)
Replacement String:   \1

The ^ says to start at the beginning of the line ($ is for the end). Then there are two patterns to look for. Each pattern is enclosed in parentheses. The first pattern looks for any single character (the dot). The number in between the braces {} says to look for the previous pattern 75 times. The second pattern looks for any single character repeated any number of times.

The replacement string is just the first pattern i.e. the first 75 characters of each line.

SQL Injection

This is what I do for every field that I read from a form or from the URL if I am going to use it in a database query.
The mysql_real_escape_string looks for things that could be used to subvert a query and escapes them.
When I create my SQL query statement they can’t be treated as part of the command.

This is a part of a file that reads and validates a form

  // Look to see if the checkbox has a value, then update the database
  if ($id != '') {
    $NickName = mysql_real_escape_string($_POST["NickName$i"]);
    $Address = mysql_real_escape_string($_POST["Address$i"]);
    $Method = mysql_real_escape_string($_POST["Method$i"]);
    
    $Name = mysql_real_escape_string($_POST["Name$i"]);      
    $Code = mysql_real_escape_string($_POST["Code$i"]);
    $TimeZone = mysql_real_escape_string($_POST["TimeZone$i"]);
  }

I have Javascript that validates the data in user forms but I always validate again on my end before I put it into the database.
    $numToUpdate++;  
    $data_is_valid = TRUE;
    if (!$DeleteRecipients) {
      include('address_book_validation.php');
    }

This is what the escape string looks like for URLs e.g.
http://wellgolly.com/index.php?p=Reminder&m=Pricing

  
  $page  = mysql_real_escape_string($_GET['p']);
  if ($page == '') { $page = 'Main'; }

  $menuChoice = mysql_real_escape_string($_GET['m']);
  if ($menuChoice == '') { $menuChoice = 'New'; }

Important note:
mysql_real_escape_string() calls MySQL’s library function mysql_real_escape_string, which prepends backslashes to the following characters: \x00, \n, \r, \, ‘, ” and \x1a.

Since mysql_real_escape_string is a mysql command, not a php command it requires an active database in order to run. If a database session is not running, it will create one. From the manual, The MySQL connection. If the link identifier is not specified, the last link opened by mysql_connect() is assumed. If no such link is found, it will try to create one as if mysql_connect() was called with no arguments. If no connection is found or established, an E_WARNING level error is generated.

If you escape every get command, you can actually cause your server to be inaccessible because the number of database connections will be exceeded. This happened to us when being scanned by Bing recently. The bot made so many requests to a file with multiple escape strings, that it blocked all other connections.

Update: This post uses mysql_real_escape_string but they now recommend using mysqli_real_escape_string. I haven’t looked into what is required to make the update.

What languages do you know?

One of the ‘How to tell if someone is a programmer’ jokes is to ask someone what languages they know. These would be popular answers.

Languages

I’m not really a programmer, but I know a fair number of these.

I went to a C class in 1988 but never had a reason to use it. I really learned C one summer a few years ago when I had some kids to help me, but I’ve never used it. It’s pretty good at making you think.

I can read and debug Java but can’t write it.
No reason to use C++.

I use PHP all the time and I’m at the point where I think I need to start using classes.

Absolutely no reason to go anywhere near C# or Visual Basic.

Python and Perl seem like they would be useful, especially for some of the string manipulations I do with sed.
I’ve played with Python a bit and it looks like something I’d like if I had the time to learn it. Perl is {$}}@##}}

Learning JavaScript.
Spent an hour today figuring out that <> is not used in JavaScript—it’s !=

Upgrading to the latest ActionScript.

Haven’t used SAS for 20 years but liked it a lot when I used it.

Of course I use SQL all the time—how else do you get to your data?

Update: Spring 2014
I learned Objective-C—so I can convert some programs to the iPad. It’s a really nice language and Apple has lots of API that make it easy to develop apps.

Not on the list, but I just spent a while learning Bash shell scripting. It comes in handy when maintaining Linux boxen.

Update: Winter 2016
I’ve heard all of the jokes about Perl being an unreadable mess, but I have been updating a site that is built with Perl and I must say that it isn’t bad. The language has some quirks but I have been able to read the code without much trouble and make changes to the web pages without spending a whole lot of time learning a completely new language. I even wrote a couple of new scripts that worked the first time.

Update: Fall 2016
I just read The Swift Programming Language and have started watching CS193P with Paul Hegarty. The language is completely different from anything I’ve used before. It is a shining example of what a talented group of programmers can do when they do not have to maintain backward compatibility with previous languages (e.g. Objective C and C) or fit into an existing paradigm of how object oriented languages must behave. I really like working with it in the Playground and can’t wait to make real apps with it.