has moved to

The registration for the domain name expired, the credit card number had changed, and the most cost-effective solution is to run this blog as a subdomain.

Web Development - Horizontal and Vertical Markets


  • Web sites
  • Intranets
  • ecommerce
  • Live support
  • Social networking / web 2.0
  • Blogs
  • Flash
  • RSS / aggregation
  • SEO
  • Internet Marketing


  • Application development, including RIAs
  • email management
  • Server management
  • Licensing
  • Toolkit / Framework development
  • Technical support
  • Product support
  • Open source customization
  • Content Delivery Networks

Quick Scan of /etc/httpd/logs/access_log to Identify Visitors

If you don’t have web stats running on your server, but you’d like to see who is visiting the pages, the following lines can be used.

cut -f1 -d' ' /etc/httpd/logs/access_log* | sort | uniq 


The first line extracts the requesting IP addresses, sorts them, and then removes any duplicates. The second can be used to get the hostname for the IP address, if it is available.

PHP File Upload Example

This example shows the HTML and PHP to upload a file.

Browsers handle the MAX_FILE_SIZE input and accept attribute differently. Some will filter the files offered through the dialog box to only list those identified by the accept attribute. Some will allow you to select a file that is too large, and submit it to the server, without any content. In this case, the tmp_name is empty, error is 2, and size is 0.

In all cases you must validate the file on the server side.

HTML to upload a file:

<?php define('FILE_UPLOAD_MAX',min(str_replace('M','000000',ini_get('upload_max_filesize')),str_replace('M','000000',ini_get('post_max_size'))));
<!doctype html>
<html lang="en">
		<meta charset="utf-8">
		<title>upload demo</title>
		<link href="upload.css" rel="stylesheet">
		<h1>upload demo</h1>
		<form method="post" enctype="multipart/form-data" action="upload-file.php">
			<input type="hidden" name="MAX_FILE_SIZE" value="<?= FILE_UPLOAD_MAX ?> " >
			<div class="block">
				<label for="file">File</label>
				<input type="file" name="file" id="file" value="" accept="image/*">
			<button type="submit">Go</button>

PHP to accept it:

header('Content-Type: text/plain');

function is_accepted($sAccept,$sFiletype) {
        return in_array($sFiletype,$aAccept,TRUE);

function size_ok($iMaxSize,$iSize) {
        return $iSize <= $iMaxSize;

function upload(&$files,$sAccept='*/*',$iMaxSize=MAX_FILE_SIZE) {
        foreach ($_FILES as $k => $v) {
                if ($v['tmp_name']==='') {
                // More robust type checking:
                if (!is_accepted($sAccept,$v['type'])) {
                        throw new Exception($v['type'].' files cannot be sent');
                if (!size_ok($iMaxSize,$v['size'])) {
                        throw new Exception('File cannot be larger than '.$iMaxSize);

               // do antivirus scan here
               $vname = $v['tmp_name'];
               system('clamscan '.escapeshellarg($vname),$result);
               echo $result;
               if ($result !== 0) {
              echo 'Scanned okay';
                // Thanks to:
                // strip out anything other than letters, digits, underscores, periods and dashes
                $name = preg_replace('/[^\w.-]/','',$v['name']);
                if ($name === '') {
                        throw new Exception('Invalid filename');
                if (!move_uploaded_file($v['tmp_name'], $name)) {
                        throw new Exception('Upload failed');
                $element = [
                        'filename' => $name,
                        'file' => $v['tmp_name'],
                        'content_type' => $v['type'] ];
                $files[] = $element;
        return true;

$uploadFiles = [];
try {
        if (upload($uploadFiles, 'image/png,image/jpg,image/jpeg,image/gif', MAX_FILE_SIZE)) {
        } else {
                echo 'Upload failed';
} catch (Exception $e) {
        echo $e->getMessage().PHP_EOL;
        error_log('File upload failed '.$e->getMessage());

dijit ContentPane Demo - With Refresh and Terminate

The link above demonstrates the use of a dijit ContentPane to request content from the server with a client-side request refresh, and error detection that allows the server to indicate when the requests should be stopped.

The intended use is to allow graceful monitoring of background scripts on a server.

Basic approach:

  • Use the ContentPane to display the content. A quote script is used to illustrate the content change.
  • Use a javascript timer to request a refresh every 5 seconds
  • Have the server-side code count and issue a 303 See Other when processing has completed.
  • Have the client-side code catch the 303 and act accordingly. In this case, it changes the displayed text to reflect the status, puts up an alert box, and clears the timer.

Use View Source to view the client-side code, server-side code is listed at the bottom of the page.

This is a nice way to implement a refreshing iframe with dojo.