Archive

Archive for the ‘php’ Category

PHP templating with Smarty

July 4, 2012 Leave a comment

I found using Smarty in PHP the most effective way to avoid spaghetti codes (codes that mix programming logic and html output that rely heavily on string concatenation), especially in the following two use cases
1) Generate html output in a structured, organized way
Let’s look at an example:

cat test.php

<?php
    require_once '/usr/share/php/smarty3/Smarty.class.php';
    // stock path installed with apt-get install smarty3 in ubuntu, you might need to adjust the require_once path
    // if you install smarty in other distros or through other means
    $smarty=new Smarty();
    $smarty->assign('label', 'my favorite tools');
    $smarty->assign('friends', array('node.js', 'underscore.js', 'backbone.js', 'Smarty', 'swift mailer', 'express'));
    $smarty->display('test.tpl');

cat templates/layout.tpl

<!DOCTYPE HTML>
<html>
    <head>
        <meta http-equiv="content-type" content="text/html; charset=utf-8">
        <title>{block name=title}{/block}</title>
        <link rel="stylesheet" href="/css/master.css" type="text/css" media="screen" charset="utf-8">
        {block name=morecss}{/block}
    </head>
    <body>
    {block name=body}{/block}   
    <script type="text/javascript" src="path/to/jquery.min.js" charset="utf-8"></script>
    {block name=morejs}{/block} 
    </body>
</html>

cat templates/test.tpl

{extends file='layout.tpl'}
{block name=title}{$label|capitalize}{/block}
{block name=morejs}
	<script type="text/javascript" src="path/to/my.main.js" charset="utf-8"></script>
{/block}
{block name=body}
Say hello to {$label}:
<ul>
	{foreach $friends as $friend}
	<li>{$friend}</li>
	{/foreach}
</ul>
{/block}

2) Prepare html (or plain text) email message to send out
cat email.php

<?php
    require_once '/usr/share/php/smarty3/Smarty.class.php';
    $smarty=new Smarty();
    $smarty->assign('url', 'http://a.link.to.reset/your/password');
    $message=$smarty->fetch('email/forget.tpl');
    // send_email_to($someaddress, $somesuject, $message);
    // you can echo it out as well
    // echo $message;

cat templates/email/master.tpl

<html>
	<body>
		<div id="content" style="width:400px;margin:40px auto"> 
			{block name=body}{/block}
		</div>
	</body>
</html>

cat templates/email/forget.tpl

{extends file='email/master.tpl'}
{block name=body}
<p>
Dear User,
</p><p>
Here's the url to reset your password:<br />
<a href="{$url}">{$url}</a>
</p><p>
&nbsp;
</p></p>
Sincerely,
</p></p>
Blah Blah
{/block}

Notes on directory structure:
1) in the above examples, the file/folder structure is as follows (generated through this little powerful tool called tree, installed via ‘apt-get install tree‘)

2) folders cache and templates_c are given the following ownership/perimssion:
ls -ld cache templates_c/
drwxr-xr-x 2 www-data www-data 4096 2012-07-03 18:23 cache/
drwxr-xr-x 2 www-data www-data 4096 2012-07-03 22:35 templates_c/

Advertisements
Categories: php

PHP: removed trailing zeros from numeric strings (code illustration)

June 14, 2012 1 comment
<?php
	$nums=array('1.0', '2.300', '4', '5.9000');

	echo "Original format:\n";
	foreach($nums as $num) {
		echo "$num\n";
	}

	echo "\nTrailing zeros removed:\n";
	foreach($nums as $num) {
		echo ($num+0)."\n";
	}

Output:
Original format:
1.0
2.300
4
5.9000

Trailing zeros removed:
1
2.3
4
5.9

Categories: php, Programming

Simple html to text converter

May 3, 2012 2 comments

This is follow-up post on sending html email using swift mailer [ see previous post here ].

Since it’s never fun to have to write the same (or similar) stuff twice, the other morning I started to look for something than can do some basic html to text conversion, that is, turn br, p into newline, at the minimum. Through googling I discovered this handy php script to do the job. For example, html2text is able to convert the following html

    Dear Customer,
    <p>blah blah...</p>
    <p />
    Sincerely,<br />
    ABC Company Service Dept<br />
    <a href="http://example.com">A link</a>

into plain text

    Dear Customer,

    blah blah...


    Sincerely,
    ABC Company Service Dept
    [A link](http://example.com)

To use the code can’t be easier:

...
require_once 'path/to/html2text.php';
$html="<p>some html text here</p>";  // original html message
$plain=convert_html_to_text($html);   // converted plain text
...

Here’s a complete example on how to use it with swift mailer to send out html email (at a low SPAM score):

<?php
        require_once 'lib/swift_required.php'; // or absolute path if swift mailer library is not under current directory
        require_once 'path/to/html2text.php';
        define('mailhost', 'localhost'); // change if using external smtp server
        $to='some_recipient@email.address';
        $subject='HTML msg sending test';
        $body_html='<p>This is a <strong>test</strong>.</p>';
        $plain=convert_html_to_text($body_html); 
        $transport=Swift_SmtpTransport::newInstance(mailhost, 25);
        $mailer=Swift_Mailer::newInstance($transport);
        $message=Swift_Message::newInstance($subject)
            ->setFrom( array('noreply@yourcompany.com'=>'Your Company Name') )
            ->setTo( array($to) )
            ->setBody($plain)
            ->addPart($body_html, 'text/html');
        $result = $mailer->send($message);
Categories: html2text, php, swift_mailer

How-to: Lower html email spam score using swift mailer

April 19, 2012 Leave a comment

Swift mailer is yet another great PHP emailing library. Working as a web developer, I am faced quite often with the tasks of sending out html email. One particular area I always pay attention to is try to lower the emails’ spam score so they won’t end up in recipient’s junk or spam box. Here’s the ‘magic’ code that does the trick:

<?php
        require_once 'lib/swift_required.php'; // or absolute path if swift mailer library is not under current directory
        define('mailhost', 'localhost'); // or external smtp server
        $to='some_recipient@email.address';
        $subject='HTML msg sending test';
        $body='This is a test.';
        $body_html='<p>This is a <strong>test</strong>.</p>';
        $transport=Swift_SmtpTransport::newInstance(mailhost, 25);
        $mailer=Swift_Mailer::newInstance($transport);
        $message=Swift_Message::newInstance($subject)
            ->setFrom( array('noreply@yourcompany.com'=>'Your Company Name') )
            ->setTo( array($to) )
            ->setBody($body)
            ->addPart($body_html, 'text/html');
        $result = $mailer->send($message);

In real-life examples, I’ve seen score dropping by as much as 2.1 by sending html message along with its plain-text counterpart. The reasoning behind this is well explained in this stackoverflow question:
http://stackoverflow.com/questions/5787185/is-it-sensible-to-send-html-only-email-these-days.

Categories: php, spam score, swift_mailer

Howto: Handle phpredis connection error

March 26, 2012 1 comment

Example Code:

<?php
    $redis=new Redis();
    $connected= $redis->connect('127.0.0.1', 6379);
    if(!$connected) {
        // some other code to handle connection problem
        die( "Cannot connect to redis server.\n" );
    }
    $redis->setex('somekey', 60, 'some value');

I came up with the above code after reading the doc because I found out the following try/catch code doesn’t work as expected

<?php
    $redis=new Redis();
    try {
        $redis->connect('127.0.0.1', 6379);
    } catch (Exception $e) {
    // tried changing to RedisException, didn't work either
        die( "Cannot connect to redis server:".$e->getMessage() );
    }
    $redis->setex('somekey', 60, 'some value');
Categories: php, redis

Install phpredis on Ubuntu

March 25, 2012 10 comments

Tested on Ubuntu 10.10 64bit server edition but should apply to other versions as well.

1) Preparation

sudo apt-get install php5-dev

php5-dev provides the dev library as well as the phpize command which is required for the compiling step
2) Get phpredis source code, should be pretty easy by running

git clone git://github.com/nicolasff/phpredis.git

3) Compile and install

cd phpredis
phpize
./configure
make
sudo -s make install

4) Enable the phpredis extension

sudo -s
echo "extension=redis.so">/etc/php5/conf.d/redis.ini
exit

5) Write a simple php script to test (running on cli would be fine if php5-cli is installed)

<?php
        // phpredis_set.php
        $redis=new Redis() or die("Can'f load redis module.");
        $redis->connect('127.0.0.1');
        $redis->set('set_testkey', 1);

Prior to try phpredis I was using Rediska as the php redis client. I did some pretty quick and dirty benchmarking comparison and phpredis is clearly a winner here, not surprisingly because phpredis is a compiled extension written in C while Rediska is a pure php library.

time for i in `seq 1 1000`; do php phpredis_set.php; done

real 0m13.072s
user 0m6.560s
sys 0m3.620s

time for i in `seq 1 1000`; do php rediska_set.php; done

real 0m21.035s
user 0m12.150s
sys 0m5.050s

and the source code for rediska_set.php:

<?php
        require_once 'Rediska/library/Rediska.php';
        $rediska=new Rediska();
        $rediska->set('set_testkey', 1);

The above tests were conducted on a single-core i3 2.1GHZ Virtualbox guest with 512MB of RAM.

Categories: php, phpredis, redis

Build a simple PHP template with str_replace()

January 5, 2012 Leave a comment

You are given a task to notify a list of customers regarding their pin setting changes through their email address on file. There are many ways to accomplish this in PHP. One way I found quite interesting is through a simple php function str_replace. Let me demo through the following example (only showing how the message body is constructed, the email address part should be easy to take care of):

<?php
        /* main.php */
        function build_key($key) {
                return '{{'.$key.'}}';
        }

        function gen_msg($format_str, $arr) {
                $keys=array_map(build_key, array_keys($arr));
                // $keys can also be generated by using the following code
                // but I found using array_map is more elegant and fun
                // $keys=array();
                // foreach(array_keys($arr) as $k) {
                //      array_push($keys, '{{'.$k.'}}');
                // }

                return str_replace( $keys, array_values($arr), $format_str);
        }

        // here's the template
        $template="Dear {{user}}, your pin number has been changed to {{pin}}.";

        // here's the data, hard-coded in this example but it can be pulled from external sources as well
        $data=array(
                array( 'user'=>'John Smith', 'pin'=>'1234' ),
                array( 'user'=>'Mr. S', 'pin'=>'9999' ),
                array( 'user'=>'Customer', 'pin'=>'****' )
        );

        foreach($data as $d) {
                printf("%s\n", gen_msg($template, $d));
        }

Run the above code through php (cli) will output the following:

Dear John Smith, your pin number has been changed to 1234.
Dear Mr. S, your pin number has been changed to 9999.
Dear Customer, your pin number has been changed to ****.

[ Update ] I also added an OOP implementation of the above code, if you are interested you can checkout my code on github.

Categories: php, Programming