Archive

Archive for September, 2011

Writing flexible php cli scripts with environment variables

September 18, 2011 3 comments

For large projects it’s better to put configurations in a settings.php file and use require 'settings.php' in the main php file, but when it’s time to write some small script but also want some flexibility, using (shell) environment variables is a better choice.
cat main.php

<?php
        $d=getenv('debug');
        $debug=$d!=''?(int)$d:1;        // default debug mode is 1
        $p=getenv('preview');
        $preview=$p!=''?(int)$p:0;      // default preview mode is 0


        if(count($argv)<2) {
                die("Usage: [debug=0|1] [preview=0|1] {$argv[0]} arg1 arg2 ...\n");
        }
        echo "program starts with preview=$preview, debug=$debug\n";
        var_dump( array_slice($argv, 1) );

Different mode combinations can be achieved through, for example,

$ php main.php aa
program starts with preview=0, debug=1
array(1) {
[0]=>
string(2) "aa"
}

$ preview=1 php main.php aa bb
program starts with preview=1, debug=1
array(2) {
[0]=>
string(2) "aa"
[1]=>
string(2) "bb"
}

$ preview=1 debug=1 php main.php aa bb
program starts with preview=1, debug=1
array(2) {
[0]=>
string(2) "aa"
[1]=>
string(2) "bb"
}

$ preview=0 debug=0 php main.ph aa bb
program starts with preview=0, debug=0
array(2) {
[0]=>
string(2) "aa"
[1]=>
string(2) "bb"
}

$ export preview=1
$ php main.php aa bb cc
program starts with preview=1, debug=1
array(3) {
[0]=>
string(2) "aa"
[1]=>
string(2) "bb"
[2]=>
string(2) "cc"
}

$ php main.php
Usage: [debug=0|1] [preview=0|1] main.php arg1 arg2 ...

Advertisements
Categories: php, Programming

A couple of plugins that make web developing life easier.

September 18, 2011 Leave a comment

matchit
The plugin basically extends the functionality of % in vim, it cycles between opening and closing tags, very handy if you love coding htmls by hand.
Steps to make it work: { windows users pls unzip the files to the vim home directory }
1) download the zip file from the above link
2) unzip matchit.zip -d ~/.vim
3) add the following line to your .vimrc
filetype plugin on
if filetype plugin is set to off [ default setting ]
4) open an existing .html file or create a new one, under normal mode, pressing % will cycle between html tags, v% will select text between opening and closing tags (with the opening tag name selected)

jsbeatify
This is yet another handy and powerful vim plugin. As its name suggests it does one thing and it does really well – beatifies javascript files. Steps to make it work:
1) Download it and save it to ~/.vim/plugin
2) Open an existing .js file or create a new one, under normal mode, press \ff and the code is formatted

There’s one thing that this plug in is not able to do – format the selected js code – in other words you can’t beautify the embedded js code in html or php files.

[ Edit 9/18/2011: Actually I just found another better solution to format javascript code – what I like the best is that this indenter formats all javascript code either in stand-alone file or embedded code. Just put the file html.vim from http://www.vim.org/scripts/download_script.php?src_id=6885 to ~/.vim/indent and use gg=G to format the whole file or = to format selected code. ]

Categories: html, Tip, vim

crontab editor

September 10, 2011 Leave a comment

To use your favoriate editor to modify user’s crontab, here’s how:

1) Quick and dirty solutions

   EDITOR=vim crontab -e

or

   export EIDTOR=vim
   crontab -e

2) Permanent solution:
add the following line to either ~/.bashrc or ~/.bash_profile

export EDITOR=vim
Categories: Bash, crontab

Using mqseries to put multiple messages to a queue in PHP

September 10, 2011 Leave a comment

The basic usage can be found everywhere via any search engine and the most official one can be found at this link. The problem with those examples is that none of them (at least so far) tells you how to write multiple messages to a queue in a proper way. Through a small project that I finished recently I found the trick how to do just that. Let’s start with the basic – putting a single message to a queue. The following code is slightly modified off the one on the PHP site:

<?php
    // open connection to the queue manager
    mqseries_conn('WMQ1', $conn, $comp_code, $reason);
    // $conn now hold the reference to the connection to the queue manager.

    // open the connectio to the testq queueu
    mqseries_open(
                $conn,
                array('ObjectName' => 'TESTQ'),
                MQSERIES_MQOO_INPUT_AS_Q_DEF | MQSERIES_MQOO_FAIL_IF_QUIESCING | MQSERIES_MQOO_OUTPUT,
                $obj,
                $comp_code,
                $reason);
    // $obj now holds the reference to the object (TESTQ)

    // setup the message descriptor array. Check MQSeries reference manuals.
    $md = array(
                'Version' => MQSERIES_MQMD_VERSION_1,
                'Expiry' => MQSERIES_MQEI_UNLIMITED,
                'Report' => MQSERIES_MQRO_NONE,
                'MsgType' => MQSERIES_MQMT_DATAGRAM,
                'Format' => MQSERIES_MQFMT_STRING,
                'Priority' => 1,
                'Persistence' => MQSERIES_MQPER_PERSISTENT);

    // setup the put message options.
    $pmo = array('Options' => MQSERIES_MQPMO_NEW_MSG_ID|MQSERIES_MQPMO_SYNCPOINT);
    
    $msg='test message.';
    // put the message $msg on the queueu.
    mqseries_put($conn, $obj, $md, $pmo, $msg, $comp_code, $reason);

    if ($comp_code !== MQSERIES_MQCC_OK) {
        printf("put CompCode:%d Reason:%d Text:%s<br>\n", $comp_code, $reason, mqseries_strerror($reason));
    }

    // close the object reference $obj    
    mqseries_close($conn, $obj, MQSERIES_MQCO_NONE, $comp_code, $reason);

// disconnect from the queue manager.    
    mqseries_disc($conn, $comp_code, $reason);
    
?>

The above code is pretty straight forward and in order to put multiple messages to a queue, we can either
1) Connect to mq server, open the queue, put one message, close the queue, ,close the connection then start over (from making connection to mq server) and put another message. This will work for sure but it’s way too inefficient.
2) Connect to mq server, open the queue, then enter a loop by calling mqseries_put until all messages are put into the queue, then close the queue and disconnect from mq. This is the preferred way and sometimes is the only right way because there might be a large number of messages to be put into the queue.

Here’s the modified code for putting multiple messages into the queue showing only the parts that are different to the above code.

<?php
...
    
    $messages=array(...);
    // put the messages on the queueu.
    foreach($messages as $msg) {
        mqseries_put($conn, $obj, $md, $pmo, $msg, $comp_code, $reason);

        if ($comp_code !== MQSERIES_MQCC_OK) {
            printf("put CompCode:%d Reason:%d Text:%s<br>\n", $comp_code, $reason, mqseries_strerror($reason));
        }
    }
...
    
?>

We expect the above code to work because it seems to be a very easy task. But to your surprise you will find the loop is only able to put the first message to the queue and as soon as the second time mqseries_put is called, a “Segmentation Fault” error is raised. I don’t know what exactly causes the problem but I found out that I have to re-initialize $md and $pmo variables each time before calling mqseries_put. The following version works:

<?php
...
    
    $messages=array(...);
    // put the messages on the queueu.
    foreach($messages as $msg) {
        // setup the message descriptor array. Check MQSeries reference manuals.
        $md = array(
                'Version' => MQSERIES_MQMD_VERSION_1,
                'Expiry' => MQSERIES_MQEI_UNLIMITED,
                'Report' => MQSERIES_MQRO_NONE,
                'MsgType' => MQSERIES_MQMT_DATAGRAM,
                'Format' => MQSERIES_MQFMT_STRING,
                'Priority' => 1,
                'Persistence' => MQSERIES_MQPER_PERSISTENT);

        // setup the put message options.
        $pmo = array('Options' => MQSERIES_MQPMO_NEW_MSG_ID|MQSERIES_MQPMO_SYNCPOINT);
        mqseries_put($conn, $obj, $md, $pmo, $msg, $comp_code, $reason);

        if ($comp_code !== MQSERIES_MQCC_OK) {
            printf("put CompCode:%d Reason:%d Text:%s<br>\n", $comp_code, $reason, mqseries_strerror($reason));
        }
    }
...
    
?>

Hope that helps if you also need to do something similar with mqseries in PHP.

Categories: mqseries, php, Programming

Sending message with attachements using Mail::Sender in Perl

September 8, 2011 Leave a comment

Due to the security setting of a network, not every server is allowed to send out email directly, that’s the reason why I wrote this script. The following Perl packages are required: Mail::Sender and Getopt::Long. Feature that would be nice to have but hasn’t been supported yet: smtp authentication. Therefore in order to be able to run this script, the external smtp server should add the ip of server where mail.pl runs to the allow-to-send list, assuming the smtp server is not configured to be a open relay.

cat mail.pl

#!/usr/bin/perl
# purpose of this script is to address the followings:
# 1) support simple sending through external smtp server that doesn't require authentication
# 2) attach file(s) while sending message
# run the script without parameters will print the usage
# example usage:
# echo "message sent using mail.pl" | perl mail.pl -f sender@email.address -s "sending test" -a file1.txt -a info.log john@email.address,smith@email.address
use strict;
use warnings;
use Mail::Sender;
use Getopt::Long;

my $subject='[NO SUBJECT]';
my @attach=();
my $from='unspecified_sender@company.ltd'; # change this
my $through='localhost';
my $help=0;

usage() if ( @ARGV < 1 or
    ! GetOptions(
        'attach|a=s@'=>\@attach,
        'subjec|st=s'=>\$subject,
        'from|f=s'=>\$from,
        'through|t=s'=>\$through,
        'help|h'=>\$help,
    ) or $help );
 
sub usage
{
  print "Unknown option: @_\n" if ( @_ );
  print "usage: program [--subject|-s SUBJECT] [--from|-f FROM] [--through|-t SMTP] [--attach|-a FILE]  [--help|-h] recipient1@domain1[,recipient2@domain2...]\n";
  print "Suject will become [NO SUBJECT] if not provided.\n";
  print "Multiple --attach can be supplied to attach more than 1 file\n";
  exit;
}

my $to=$ARGV[0];

# check if files exist
map {
    die("File $_ doesn't exist!\n") if ! -f $_;
} @attach;

my $msg='';
while(<STDIN>) {
    $msg.=$_;
}
if($msg eq '') {
    $msg='[BLANK]';
}

my $sender=new Mail::Sender( {
    smtp=>$through,
    from=>$from,
});

$sender->OpenMultipart( {
    to=>$to,
    subject=>$subject,
});

$sender->Body();
$sender->SendLine($msg);
$sender->SendFile( {
    description=>'Raw data File',
    encoding=>'7BIT',
    file=>\@attach
});
$sender->Close();
Categories: emailing, perl