I’ve been working on a new SWiK feature, and it included some functionality to show stuff over the month, with the option to go back months and view them in more detail.
In coding up this feature, I thought I would take a shortcut around actually calculating the dates and use the strtotime function in PHP, which can take a string like ‘-1 month’ and turn it into last month’s Epoch time.
That’s what I thought at least.
Turns out, today I discover you should never actually depend on this functionality. PHP interprets ‘-1 month’ to mean ‘-30 days’. This means that on July 31st, strtotime will think that -1 month was July 1st. This of course plays havok on July 31st, and slowly but subtley over time previous to that.
Needless to say, a frustrating bug, which I’ve read on php.net is actually by design; go figure :/
If you want to do a HTTP Post in PHP, you can use this nifty function that doesn’t require cURL:
/* sendToHost
* ~~~~~~~~~~
* Params:
* $host - Just the hostname. No http:// or
/path/to/file.html portions
* $method - GET or POST, case-sensitive
* $path - The /path/to/file.html part
* $data - The query string, without initial question mark
* $useragent - If true, 'MSIE' will be sent as
the User-Agent (optional)
*
* Examples:
* sendToHost('www.google.com','GET','/search','q=php_imlib');
* sendToHost('www.example.com','POST','/some_script.cgi',
* 'param=First+Param&second=Second+param');
*/
function sendToHost($host,$method,$path,$data,$useragent=0)
{
// Supply a default method of GET if the one passed was empty
if (empty($method)) {
$method = 'GET';
}
$method = strtoupper($method);
$fp = fsockopen($host, 80);
if ($method == 'GET') {
$path .= '?' . $data;
}
fputs($fp, "$method $path HTTP/1.1
");
fputs($fp, "Host: $host
");
fputs($fp,"Content-type: application/x-www-form- urlencoded
");
fputs($fp, "Content-length: " . strlen($data) . "
");
if ($useragent) {
fputs($fp, "User-Agent: MSIE
");
}
fputs($fp, "Connection: close
");
if ($method == 'POST') {
fputs($fp, $data);
}
while (!feof($fp)) {
$buf .= fgets($fp,128);
}
fclose($fp);
return $buf;
}
Joerg Battermann posted a side by side graph of php mailing list traffic to rubyonrails traffic.
By the appearance of these graphs, it seems as if RubyOnRails is growing by leaps and bounds while PHP’s pattern is the inverse.
But here’s another data point, RubyOnRails.org vs PHP.net:
(Alexa)
From Alexa, it appears as if RubyOnRails growth has, if anything, halted.
It’s hard to know these things, but superficially there doesn’t seem to have been as many new websites run on Rails, other than 37Signals’ own sites.
Has there been a new Odeo, 43Things, or even YubNub lately?
I like Rails, but the lack of new projects suggests RubyOnRails may in all likelyhood be a fad with a cool and useful center but no potential to fundamentally disrupt the way web applications are built.
I like this function in PHP:
function multi_sort($array, $akey)
{
function compare($a, $b)
{
global $key;
if ($a[$key]>$b[$key]){
$varcmp = "1";
return $varcmp;
}
elseif ($a[$key]<$b[$key]){
$varcmp = "-1";
return $varcmp;
}
elseif ($a[$key]==$b[$key]){
$varcmp = "0";
return $varcmp;
}
}
usort($array, "compare");
return $array;
}
You call this function like this:
$array = multi_sort($array, $key = ‘keyName’);
this will set the array to a sorted version sorted by key ascending
boz is a private web bookmarking application written in php and javascript.
It offers encrypted bookmarks,: bookmarks encrypted in the web browser that are encrypted using AES/Rijndael 128 bit encryption, creating bookmarks that are encrypted even from the server. They’re really encrypted! No one can see them but you.
AES 128 bit encryption is acceptable for regular secrecy use and approved by the NSA for use in protecting “secret” level classified documents:
“The design and strength of all key lengths of the AES algorithm (i.e., 128, 192 and 256) are sufficient to protect classified information up to the SECRET level.
boz is the successor to priv.at, which has been disabled by del.icio.us moderation. If you have had saved bookmarks on priv.at and you would like to import them to Boz, please email me to import and encrypt your bookmarks.
Tough luck :( The server doesn’t know your password or what you’ve bookmarked, that’s the whole point of encrypting things – no one else can know what they are. So anyways, there’s no way to recover your password or bookmarks if you forget the encryption key you used.
boz is almost all JavaScript, and relies on various other projects to provide functionality that are not quite compatible with all browsers. IE and Firefox should work; Safari and Opera, not so much. This is mostly due to dojo.
Due to the nature of encrypted bookmarks, most code needs to live in the browser; the server cannot be trusted with very much information and is used as more of a simple store.
Communication between the two is done mostly through JSON, and only limited information is sent in the clear, such as a hash of the password to be used for access privileges to the account and the private key for the bookmarks. Also sent in the clear is numerical identifiers for tag metadata: date, starred status, tag id: these are sent in the clear for necessity’s sake and because they don’t compromise the text of the bookmarks.
Want to help with the project? If you know how I can get Safari or Opera to work with boz (more specifically dojo), please let me know.
There are 3 components to doing a lightweight PHP presence script:
I think the easiest way to do this is in MySQL or another database you are using with your script.
Here’s a simple mysql table that can store visitor state:
CREATE TABLE `visitors` (
`ip` int(4) unsigned NOT NULL default '0',
`visited` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
PRIMARY KEY (`ip`),
KEY `visited` (`visited`)
)
note: this uses Arjen Lentz’s method of storing IPs in ints. technique.
$sql = "
SELECT COUNT(*) as numVisitors FROM visitors
WHERE ip = INET_ATON('".$_SERVER['REMOTE_ADDR']."')";
$result = mysql_query($sql) or die($sql.mysql_error());
$row = mysql_fetch_assoc($result);
if ($row['numVisitors'] == 0)
{
$sql = "
INSERT INTO visitors
SET ip = INET_ATON('".$_SERVER['REMOTE_ADDR']."')";
}
else
{
$sql = "
UPDATE visitors SET visited = NOW() WHERE ip = INET_ATON('".$_SERVER['REMOTE_ADDR']."')";
}
mysql_query($sql) or die($sql.mysql_error());
This one’s easy:
$sql = "
SELECT COUNT(*) as numVisitors
FROM visitors
WHERE UNIX_TIMESTAMP(visited) > ".(time() - 60 * 10); //or whatever you consider recent
$result = mysql_query($sql) or die($sql.mysql_error());
$visitors = mysql_fetch_assoc($result);
echo $visitors['numVisitors'];
This script is used in LiveMarks to show the number of visitors currently on the page.
Referendum is a project to allow for community initiatives, allowing people to raise issues and vote on them. 
Referendum is written in PHP and requires Ajax capable web browser for voting.
Referendum uses the Microformats concept of ‘vote-links’. For more information on this, see the Microformats Wiki.
To activate a new vote – you must create and follow a link to your issue, preferrably on a page where people might discuss the issue at length, for example on your blog.
Ajax
Referendum
Ballots
Voting
License:GPL
user:alex
php5
community
PHP
Microformats