Posted on Tuesday, August 31st, 2010 under php, strange stuff, tips and tricks
Over the years, I’ve encountered a lot of strange things in PHP, but this one is off the scale:
$value = 'zero';
switch ($value) {
case 0:
echo 'value is zero';
break;
default:
echo 'value is not zero';
break;
}
echo PHP_EOL;
What do you think that the code above will print? Well…I’ll spare you the hassle and give you the answer:
% php test.php
value is zero
This weird behavior originates in the fact that PHP uses the equality operator (==) instead of the identity (===) one when evaluating expressions inside a switch statement. It’s basically the same as:
if ('foo' == 0) {
echo 'bar';
}
…which also yields unexpected results. I hate this type of casting!!!
2 comments
Posted on Wednesday, April 14th, 2010 under google, google apps, tips and tricks
Several days ago, I decided to start using Google Apps for my email. I’m not a Google fanboy, but in some areas they’re the best. And Gmail is one of those areas. To have virtually unlimited storage space and access to your emails is *very* important. And I also love the way Google groups emails into conversations. The process was painless, just some minor DNS modifications, filling some forms on Google’s site and that’s it.
A problem arose when I wanted to import my existing emails from Evolution to Gmail. Although Google provides extensive documentation and even a migration API, I was unable to find something tailored for Evolution. After some Googling and asking around, I decided to use the – kind of lame, but nevertheless, effective – IMAP approach.
It’s quite simple:
- enable IMAP support in your Gmail CP
- add the newly created IMAP account to your Evolution
- in Evolution, copy all the emails from your regular account to your Gmail one
- wait for the IMAP account to synchronize with the server (it might take a while, depending on the number of emails/attachments)
All your current folders will be imported as labels in Gmail. For some unknown reason, it was unable to group all conversations, although I uploaded the “Sent” folder. Anyways, if you have a better idea, feel free to post a comment.
1 comment
Posted on Friday, February 19th, 2010 under python, tips and tricks
Few days ago I was working on some python scripts that needed to iterate back and forth through calendar dates. Working with dates in python is pretty easy, due to its datetime package.
Basically is like this:
#!/usr/bin/env python
import datetime
start_date = datetime.date( year = 2010, month = 2, day = 1 )
end_date = datetime.date( year = 2010, month = 1, day = 1 )
list = []
if start_date <= end_date:
for n in range( ( end_date - start_date ).days + 1 ):
list.append( start_date + datetime.timedelta( n ) )
else:
for n in range( ( start_date - end_date ).days + 1 ):
list.append( start_date - datetime.timedelta( n ) )
for d in list:
print d
This works, but is somewhat lame and not quite reusable. The most “python-ish” way to do it is to create a generator function that will yield the current date and can be used in a for loop. So I did it:
#!/usr/bin/env python
import datetime
def daterange( start_date, end_date ):
if start_date <= end_date:
for n in range( ( end_date - start_date ).days + 1 ):
yield start_date + datetime.timedelta( n )
else:
for n in range( ( start_date - end_date ).days + 1 ):
yield start_date - datetime.timedelta( n )
start = datetime.date( year = 2010, month = 2, day = 1 )
end = datetime.date( year = 2010, month = 1, day = 1 )
for date in daterange( start, end ):
print date
Much more elegant
1 comment
Posted on Tuesday, February 16th, 2010 under php, tips and tricks
Last week, while programming, I needed to insert an array at the beginning of another. So, since basically I was just merging 2 arrays, I tried to do it like this:
$originalArray = array(
1 => 'First item',
4 => 'Forth item',
5 => 'Fift item',
10 => 'Tenth item', // and so on
);
$insertAtBegining = array(
0 => 'None',
);
$newArray = array_merge($insertAtBegining, $originalArray);
But it didn’t work.
It was displaying something like:
Array
(
[0] => None
[1] => First item
[2] => Forth item
[3] => Fifth item
[4] => Tenth item
)
Not a good result, because the arrays’ keys were actually primary keys used by the RDBMS so it was very important for me to keep the original keys. I didn’t want to take the lame approach and do a foreach loop:
$newArray = $insertAtBegining;
foreach($originalArray as $key => $value) {
$newArray[$key] = $value;
}
…because it was too obvious, so I did something less obvious, and much more complicated:
$newArray = array_combine(
array_merge(array_keys($insertAtBegining), array_keys($originalArray)),
array_merge(array_values($insertAtBegining), array_values($originalArray))
);
But in the end, Chris, one of my colleagues who also has a blog at SegmentationFault.es pointed out the most simple and elegant solution:
$newArray = $insertAtBegining + $originalArray;
This reminds me of the saying “Keep It Simple Stupid”
Which Chris uses as a wallpaper…
2 comments
Posted on Tuesday, January 26th, 2010 under efficiency, tips and tricks, vim
Vim is the editor of the Gods. The Elder Gods. It’s by far the best text editor I’ve ever encountered. Although I’m not a “vim purist” (no hjkl
), I’m fascinated with its power. And there are always new things one can learn about it. It never gets old.
For instance, today the head of my company’s IT department showed me the following cool trick: if you have an XML file loaded in a buffer and you want to have it properly indented, you just hit Escape in your Vim editor and type
… and…Magic!
Anyway, lately I’ve spent some time puting together a list of very useful plugins for PHP/Zend Framework and python/django development in order to speed things up and become more productive. My (g)Vim configuration currently uses:
And a custom gvimrc file. If you want to give it a try, check out my GitHub repository at http://github.com/motanelu/GVim-configuration. Installation is very simple, just follow the instructions below (PS: I’m using GVim. If you’re using Vim replace gvimrc with vimrc):
cd ~/
mv .vim .vim.bak
mv .gvimrc .gvimrc.bak
git clone git://github.com/motanelu/GVim-configuration.git
mv GVim-configuration .vim
ln -s ~/.vim/gvimrc ~/.gvimrc
Post a comment and tell me if you find it useful. If you’re a Zend Framework user, have a look over the snippets.
6 comments
Posted on Monday, January 4th, 2010 under linux, tips and tricks, ubuntu
This one is from the “d’oh” category. As recently I’ve moved to Barcelona and since Bucharest and Barcelona are in different time zones, I wanted to set my system’s time an hour back, in order to display the correct time.
I went the easy way: right clicked on the clock in the upper right, selected “Adjust date and time” and made the modifications. After a few minutes the clock was showing Bucharest’s time and my changes were overwritten. I though I must have imagined setting the clock right in the first place – since I “tasted” Moritz thoroughly – and did it again.
I’ve ignored the clock for a while and, later on, when I looked at it, it was displaying Bucharest’s time again
D’oh! Ubuntu queries it’s time servers from time to time and sets the hour according to the information retrieved from these servers. And since my timezone was still set to Europe/Bucharest, on each update my system was receiving the time for that area. I’ve changed the timezone accordingly and everything started working. Magic!
To change the timezone of on you Ubuntu system go to System > Administration > Time and date. Or, if you’re a console freak, just punch in:
sudo dpkg-reconfigure tzdata
in order to set the correct time zone.
no comments
Posted on Monday, December 28th, 2009 under django, python, tips and tricks
I’ve been using Django for quite some time now and I kind of like it. It provides a fast – really fast – and clean way of doing things. When I first started with Django, I’ve used it mainly for simpler projects and kept the larger, more complicated ones on Zend Framework. That’s because I feel much more comfortable with PHP and Zend Framework rather than python and Django.
But, lately, I’ve used django for more ambitious projects and some obvious flaws began to annoy me. The first thing – the one this entry’s about – is the configuration file. Django comes with a settings.py file in which all the settings are being held, without any regard to their purpose.
Environment settings like database connection strings, file system paths and debuging are mixed together with application settings like what middleware classes are used, context processors and so on. So I’ve decided to split the configuration file in two, like in the following example:
local.py
This file holds the host related configuration and each instance of the application should have its own local.py file. One for development, one for testing, one for staging, one for production and so on. This file should not be included in the source control repository, so add a svn/git/whatever ignore on it.
# debug settings
DEBUG = True
TEMPLATE_DEBUG = DEBUG
# database configuration
DATABASE_ENGINE = ''
DATABASE_NAME = ''
DATABASE_USER = ''
DATABASE_PASSWORD = ''
DATABASE_HOST = ''
DATABASE_PORT = ''
# media root ex: /var/www/my-project/media
MEDIA_ROOT = ''
# media url ex: media.my-project.tld
MEDIA_URL = ''
# admin media url ex: /media
ADMIN_MEDIA_PREFIX = '/media/'
# application's secret key
SECRET_KEY = 'mY-S3Cr3t-K3y-m|_|st-b3-un1QuE-4nD-h4rD-t0-GueSs'
settings.py
This file holds the application related configurations and should be included in the version control system.
import os
# root directory for the project
ROOT_DIR = os.path.realpath( os.path.dirname( __file__ ) )
ADMINS = (
( 'root', 'root@project.tld' ),
)
# import all the local settings
from local import *
MANAGERS = ADMINS
TIME_ZONE = 'Europe/Bucharest'
LANGUAGE_CODE = 'en-us'
SITE_ID = 1
USE_I18N = True
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.load_template_source',
'django.template.loaders.app_directories.load_template_source',
)
MIDDLEWARE_CLASSES = (
'django.middleware.cache.UpdateCacheMiddleware',
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.middleware.cache.FetchFromCacheMiddleware',
)
ROOT_URLCONF = 'my-project.urls'
TEMPLATE_CONTEXT_PROCESSORS = (
'django.core.context_processors.auth',
'django.core.context_processors.debug',
'django.core.context_processors.i18n',
'django.core.context_processors.media',
)
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
)
# template directories
TEMPLATE_DIRS = (
os.path.join( ROOT_DIR, 'templates' ),
os.path.join( ROOT_DIR, 'other', 'template', 'path' ),
)
# django debug toolbar configuration
INTERNAL_IPS = ( '127.0.0.1' )
if DEBUG:
MIDDLEWARE_CLASSES += 'debug_toolbar.middleware.DebugToolbarMiddleware',
INSTALLED_APPS += 'debug_toolbar',
The last bit is because I usually use in development the incredibly useful Django debug_toolbar, and of course, I want it turned off on the live environment.
4 comments
Posted on Thursday, November 26th, 2009 under php, regular expressions, tips, tips and tricks
How do you write a regular expression that will match \\test – two backslashes followed by some text in PHP? Well, obviously you’ll try something like this:
echo preg_match('/^\\([a-z]+)/', $word) ? 'match' : 'no match';
…but it won’t work. Furthermore, it will yield an error saying something like:
Compilation failed: unmatched parentheses at offset …
And it makes sense, since the backslash has a special meaning, as it’s the escape character, to give it a literal meaning you have to escape it. Like such:
echo preg_match('/^\\\\([a-z]+)/', $word) ? 'match' : 'no match';
…each of the two backslashes is escaped by another backslash placed in front of it. But this also doesn’t work
The correct way to do it is:
echo preg_match('/^\\\\\\\\([a-z]+)/', $word) ? 'match' : 'no match';
Yeap. That’s right! With 8 backslashes. For each backslash you wanted matched, you need to add 4 in the regular expression. That’s because the backslash is considered to be an escape character by both PHP’s parser and its regexp engine. So, if you type a backslash in PHP, it’s considered and escape character by PHP’s parser.
If you write two backslashes in PHP, this construct will be interpreted as a literal backslash by PHP’s paser and sent to the regexp engine as an escape character. That’s right: ‘\\’ in PHP means a ‘\’ for the regexp engine. So, in order to pass a literal backslash to the regexp engine, you need to add 4 backslashes in PHP.
This is what I call backslash hell
3 comments
Posted on Friday, April 3rd, 2009 under extreme php, php, tips and tricks
Early in his career, every PHP programmer writes code like:
mysql_query( $sql ) or die( mysql_error() );
Come on! We’ve all been there. Of course, now we all agree that that’s lame and stupid and we use PDO or even ActiveRecord, but back in the days, that was widely used. What does that mean, actually? or die()?
It’s an optimization originally implemented in – I think – gone wild.
For instance, if you have a condition like:
if ( ( $a == $b ) || ( $c == $d ) ) { /* whatever */}
…if the the result in the first set of parenthesis evaluates to true, the second one isn’t evaluated because its result is irrelevant in this context. The parser already knows the answer, as “true or anything” always equals true.
The mysql_query() function returns a value that can be evaluated from a boolean point of view. If that result is evaluated to true (the query was okay), then the die() part gets left out. If the query fails and mysql_query() returns something that evaluates as false, then the die() call gets executed. That’s all, in a nutshell.
The above code could have been rewritten as:
if ( ! mysql_query( $sql ) ) {
die( mysql_error() );
}
Still lame, but with improved readability.
Of course, you can do nifty tricks with this kind of constructs:
is_numeric ( $_GET['id'] ) || redirect( '/my/error/url' );
Cool!
6 comments
Posted on Friday, March 27th, 2009 under css, tips and tricks
Although I’m not a designer and I only know about 10 colors, I’m a great fan of the client side disciplines. I like nifty pieces of CSS, I enjoy coding in Javascript and I advocate semantic web. Unfortunately, my job focuses more on the server-side these days, but that doesn’t mean that I can’t have a look from time to time over some CSS tutorials.
This time, I’ve tried this tutorial, written by Eric Meyer. Pretty nifty! I’ve decided to give it a try myself, and I drew a house. And made a CSS love declaration to my girlfriend, here.
Pretty cool, isn’t it? And, perhaps, web 2.0 will mean another transition, from ASCII art to CSS art
1 comment