Archive for the ‘Programming’ Category
All You Need to Know to Master The Vim Editor
I use Vim Editor every single day and really like it. Few years ago when I started learning Vim editor, I found it very daunting to learn all those commands and tricks, and then remember those commands, and most importantly – apply those commands for day-to-day tasks. Over the past years, I learned a lot, step by step. But I’m still not there yet. I’m not master yet. I’ve seen few my colleagues doing magic with Vim, which I can just appreciate but not understand and apply. I always wanted to learn more tricks and tips and master the editing with Vim. Finally I found some great articles compiled together to master Vim editor on this blog post – Vim is a great text editor.
Following are the useful links that you can peruse to master the Vim Editor -
- Find the appropriate version of Vim for your OS and install.
- Start learning the ropes with these tutorials:
- Vim is very customizable, the settings are stored in the vimrc file which resides in the install’s directory:
I found these links very useful, and I hope you’ll find them useful too. You may not be able to digest this all information at once. You’ll have to learn few things, and then practice it, and then master it. But now you have all the resources to master Vim at one place!
Automating Your MySQL Database Backup On Media Temple’s Grid-Server
Let me admit this – I did not backup the Tweeght‘s database until today. Somehow I kept procrastinating it for no reason. Since Tweeght is growing consistently, it was crucial for me to backup its database on daily basis and prepare myself from loosing all the crucial data in some sort of catastrophic event.
I use Media Temple’s Grid-Server for Tweeght. MT has good knowledge base article on – How can I Backup and Restore a MySQL database?.
But this article just mentions about how to backup your database for once. I wanted to automate this backup process on daily basis. So I Googled a little-bit, and came across this wonderful script. So I took that script, updated it for MT’s Grid-Server infrastructure, and now I’m all set within 20 minutes to take daily backups of my crucial databases.
Here are the steps I followed:
1. Go to /data directory in your account. I preferred this over /domains directory because this is accessible only by you and not by public. You don’t want the public to accidentally access dump of your database.
2. Create /db_backup directory. Go to /db_backup directory and create three new directories – /scripts , /daily and /recent.
3. Go to /scripts directory and open up your favorite editor. Copy and paste following code -
#!/bin/bash
# Set a value that we can use for a datestamp
DATE=`date +%Y-%m-%d`
# Our Base backup directory
BASEBACKUP="/home/XXXXX/data/db_backup/daily"
for DATABASE in `cat /home/XXXXX/data/db_backup/scripts/db_list.txt`
do
# This is where we throw our backups.
FILEDIR="$BASEBACKUP/$DATABASE"
# Test to see if our backup directory exists.
# If not, create it.
if [ ! -d $FILEDIR ]
then
mkdir -p $FILEDIR
fi
echo -n "Exporting database: $DATABASE"
mysqldump --add-drop-table -h internal-db.sXXXXX.gridserver.com -udbXXXXX -pPASSWORD $DATABASE | gzip -c -9 > $FILEDIR/$DATABASE-$DATE.sql.gz
echo " ......[ Done Exporting to local backup, now exporting for remote backup] "
cp $FILEDIR/$DATABASE-$DATE.sql.gz /home/XXXXX/data/db_backup/recent/$DATABASE.sql.gz
echo " .......[Done]"
done
# AutoPrune our backups. This will find all files
# that are "MaxFileAge" days old and delete them.
MaxFileAge=4
find $BASEBACKUP -name '*.gz' -type f -mtime +$MaxFileAge -exec rm -f {} \;
4. Change few things in above code -
- Replace all the instances of ‘XXXXX’ with your gridserver account number.
- Replace ‘PASSWORD’ with your SSH password
5. Now save this file as something like ‘db_backup.sh’
6. Open up your editor one more time, and write the names of databases you want to back up on each single line -
dbXXXXX_proj1 dbXXXXX_proj2
7. Now save this file as something like ‘db_list.txt’
8. Basically, the script pulls a list of databases to be backed up from a file called db_list.txt, this file takes 1 database name per line. It then exports the database and compresses, then saves it with a date-stamped filename to a directory called ../daily/<db_name>/.
Then, the script copies a non-date-stamped filename to a directory called ../recent/, thus overwriting the previous file stored there.
Finally it goes through the daily directory structure and deletes any files older than 4 days.
9. Now you can test your backup script by running following command -
./db_backup.sh
10. The script will echo out some progress messages. If no error message, then hopefully your databases should be backed up.
To see if it was successful execution, go to ../daily directory. You will see directories created with <db_name> names. Under these directories, you’ll see compressed version of sql dumps. Similarly, go to ../recent directory, and you’ll see the similar compressed version of sql dump.
To automate this backup process, go to your MediaTemple’s admin section of your primary domain and click the “Cron Jobs” link.
11. Click on the ‘Add a new cron job’ button.
12. Add your email address in the “Notification Email” field. This will send you emails whenever the cron job runs and will let you know if it was successful or not.
13. Also add path of your script in the “Command or script to execute” field. Enter: /home/XXXXX/data/db_backup/scripts/db_backup.sh. Again, replace ‘XXXXX’ with your gridserver account number.
14. On the same page, you can specify how often you’d like your script to run. This entire section is up to you requirements. I’ve set mine to run daily at 3:00 AM when traffic on my site is slower.
15. Click Save and you’re all set to backup your databases on daily basis!
I hope this will be useful to you. If you see any issues, please let me know in the comment section.
The PHP Benchmark
I just stumbled upon a website called PHP Benchmark. It’s a great resource to learn PHP tips for improving performance and speed. These are not advanced tips, but rather very simple tips that we generally don’t pay attention to in our day-to-day programming.
Here is one example -
Is it worth the effort to calculate the length of the loop in advance?
E.g. Should we use
for ($i = 0; $i < $size; $i++)
instead of
for ($i = 0; $i < sizeof($arr); $i++)
The performance result for a loop with 1000 keys with 1 byte values is as below -
With pre calc – count(): Total time: 229 µs
Without pre calc – count(): Total time: 99702 µs
With pre calc – sizeof(): Total time: 235 µs
Without pre calc – sizeof(): Total time: 99610 µs
So it’s very clear that calculating the length of array in advance is way faster than calculating it in the loop.
I hope you’ll find other tips from PHP Benchmark website very useful too.
Verifying Twitter account credentials using Symfony validator in PHP
If you’re using Symfony – a PHP’s MVC framework to develop your web application, and if your application interacts with Twitter, and if you need Twitter user’s credentials to access his or her data from Twitter, then this might be useful to you.
Here is a simple Twitter class -
<?php
class Twitter {
private $credentials;
function Twitter($username, $password) {
$this->credentials = sprintf("%s:%s", $username, $password);
}
function verifyCredentials($format = NULL) {
$api_call = sprintf("http://twitter.com/account/verify_credentials%s", ($format != NULL) ? sprintf(".%s", $format) : NULL);
return $this->APICall($api_call, true);
}
private function APICall($api_url, $require_credentials = false, $http_post = false) {
$curl_handle = curl_init();
curl_setopt($curl_handle, CURLOPT_URL, $api_url);
if ($require_credentials) {
curl_setopt($curl_handle, CURLOPT_USERPWD, $this->credentials);
}
if ($http_post) {
curl_setopt($curl_handle, CURLOPT_POST, true);
}
curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, TRUE);
$twitter_data = curl_exec($curl_handle);
curl_close($curl_handle);
return $twitter_data;
}
}
?>
Then here is the simple action to handle form –
public function executeTwitterLogin()
{
if ($this->getRequest()->getMethod() == sfRequest::POST)
{
$username = $this->getRequestParameter('username');
$password = $this->getRequestParameter('password');
// Your business logic here...
}
}
Here is the action to handle error for TwitterLogin action –
public function handleTwitterLogin()
{
return sfView::SUCCESS;
}
Here is a simple template with the form asking for the Twitter login credentials -
<?php use_helper('Validation', 'Form') ?>
<?php echo form_tag('@twitter_login') ?>
<p>Please enter your Twitter account's login credentials below.</p>
<?php echo form_error('username') ?>
<label for="username">Twitter Username:</label>
<?php echo input_tag('username', $sf_params->get('username')) ?>
<?php echo form_error('password') ?>
<label for="password">Twitter Password:</label>
<?php echo input_password_tag('password') ?>
<?php echo submit_tag('Login') ?>
</form>
Here is the twitterLogin.yml validator file –
methods: post: [username, password] names: username: required: true required_msg: Your Twitter Username is required. validators: userValidator password: required: true required_msg: Your Twitter Password is required. userValidator: class: twitterLoginValidator param: password: password
And finally, here is the custom class which is extended from sfvalidator for authenticating Twitter login details.
<?php
class myTwitterLoginValidator extends sfValidator
{
public function initialize($context, $parameters = null)
{
// initialize parent
parent::initialize($context);
// set defaults
$this->setParameter('error', 'Your Twitter account credentials are incorrect.');
$this->getParameterHolder()->add($parameters);
return true;
}
public function execute(&$value, &$error)
{
$password_param = $this->getParameter('password');
$password = $this->getContext()->getRequest()->getParameter($password_param);
$username = $value;
// Verify Twitter Credentials
$twitter = new Twitter($username, $password);
$resp_xml = $twitter->verifyCredentials('xml');
$resp_xml = simplexml_load_string($resp_xml);
$resp_username = $resp_xml->screen_name;
$verified = strcasecmp($username, $resp_username); // returns 0 if they are equal
if ($verified === 0)
return true;
$error = $this->getParameter('error');
return false;
}
}
?>
I hope you’ll find this useful. Let me know in the comments section if you see any issue while using it.
Generate sequential strings for URL addresses using PHP
I’m working on an interesting project right now, and for this project, I wanted to generate URLs with sequential alphabetic sequence as opposed to using numeric IDs. Using alphabetic string allows me to use short URL addresses with many URL combinations. E.g. If I use numeric indexes, then I can only have 10 possibilities to represent http://abc.com/N, where N= 0 to 9. But instead, if I use alphabetic character, I have 26 possibilities where N= a, b, c to z. I don’t want to add usability issues by using both upper and lower cases of alphabets, so I’ll stick to lower case addresses only.
So I needed a function which will generate sequential alphabetic strings for URL address based on incremental numbers. So I coded up following function:
function getAlphaString($num)
{
$alpha = '';
while($num >= 1) {
$num = $num - 1;
$alpha = chr(($num % 26)+97) . $alpha;
$num = $num / 26;
}
return $alpha;
}
Use this in a for{} loop, and it will give you sequential strings. Or call with individual numbers as shown below, and it will return you appropriate alphabetic string.
echo getAlphaString(5) . "\n"; echo getAlphaString(500) . "\n"; echo getAlphaString(500000) . "\n"; echo getAlphaString(50000000) . "\n";
And it produced following output:
e sf abkpt dejtlx
Hope you’ll find this function useful in one of your applications.
Splitting strings in PHP using explode Vs split functions
Splitting strings into an array is nothing new and is pretty easy using the explode function if your input string pattern is consistent. But if your input string pattern is a little less consistent, then using the split function makes it a lot easier than doing some post-processing on array elements produced by the explode function.
Here is an example:
I have an input field where I ask user to enter her friends’ email addresses to invite them. I instruct user to use commas to separate multiple email addresses. But user will not necessarily enter all email addresses with consistent pattern. The input string may not contain any spaces, or may contain optional spaces before or after actual email addresses. For example:
$recipient_email_list = "abc@example.com, def@example.com,ghi@example.com , jkl@example.com , mno@example.com";
$recipient_emails = explode(',', $recipient_email_list);
//Echo with '|' delimiter to see the spaces before and after email address:
foreach ($recipient_emails as $recipient_email)
{
echo $recipient_email.'|';
}
The output is as below:
abc@example.com| def@example.com|ghi@example.com | jkl@example.com | mno@example.com|
In above example, few exploded strings have additional spaces. So you need to do post-processing on the exploded array as below:
$i=0;
foreach ($recipient_emails as $recipient_email)
{
$found = preg_match('/ /', $recipient_email);
if($found)
{
$recipient_emails[$i]= trim($recipient_email);
}
$i++;
}
foreach ($recipient_emails as $recipient_email)
{
echo $recipient_email.'|';
}
Then the output is as below:
abc@example.com|def@example.com|ghi@example.com|jkl@example.com|mno@example.com|
But there is another easy way to avoid this extra lines of post-processing code. Use split function as below:
$recipient_emails = split(' *, *', $recipient_email_list);
foreach ($recipient_emails as $recipient_email)
{
echo $recipient_email.'|';
}
Then the output is as below:
abc@example.com|def@example.com|ghi@example.com|jkl@example.com|mno@example.com|
In above example, split function actually splits an input string into an array by regular expression ‘ *, *’ i.e. split by zero or more spaces after or before the comma character.
I hope you will find this useful. If you have more inputs or questions, then please share in comments section.