Friday, November 18, 2011

Opt-in vs. Confirmed Opt-in vs. Double Opt-in


If you're new to email marketing, you might not understand the difference between opt-in, opt-out, double opt-in, and confirmed opt-in lists, or all their pros and cons...
Here's a quick run-down of how each one works, plus some pros and cons...
Opt-out: This is an old-fashioned way of building your email list where you'd typically have some form for people to fill out (like to receive a free whitepaper or something). Hidden at the bottom of the page would be a little pre-checked box, with something like, "Yes, please sign me up for your email newsletter!" It's sort of a scummy way of doing it, but technically it's legal. We highly recommend against it, because you'll end up with tons of people who don't understand how they got on your list, who won't read your emails, and who will send complaints to the anti-spam authorities to get your server blacklisted. It's yucky, so stay away from it.
Opt-in: Sometimes referred to as "single opt-in," this method basically means people are never automatically signed up for any email lists. They are only added to an email list if they actually fill out your registration form. While this is much better than opt-out, it's still got its problems. People can sign up friends or family members to lists without their permission. They you end up sending emails to people who've never heard of you. Those people tend to get pretty angry.

Confirmed Opt-in:
This is similar to the opt-in method, but after someone signs up for your email list, you'd send them a "thank you" confirmation email that contains a link to unsubscribe from your list (just in case they were signed up by someone else without their permission). On the surface, this method looks a lot better than single opt-in, since it gives people a way out if they never signed up for your list. But think about it. If someone signed you up for an email list that you've never heard of, and you got the confirmation email out of the blue, would you trust the unsubscribe link? Would you have even read the email in the first place?
Double Opt-in: Someone signs up for your email list. You send a confirmation email with a link that they must click before they're added to your list. If they don't click the link, they don't get added to the list. When users confirm that they want on your list, you should store their IP address, and confirmation date and time in your records. This is, in our opinion, the best way to handle your email list. Advantages to this approach include:
  • Only people who are truly interested in hearing from you will double opt-in, so your response rates will be much higher (we've seen differences up to 20% higher with double opt-in).
  • Since your audience truly wants to hear from you, you can charge more for any advertising that you sell within your email.
  • Your competition won't be able to sign up for your email newsletter, then report you for spamming them to the blackhole lists, because you'll have proof they double opted in. Yes, this happens quite a lot.
Disadvantages? Some marketers worry that a lot of people will never follow through with the confirmation link. But we have to ask: if someone's too lazy or unwilling (or incompetent) to click your simple little confirmation link, do you think they're really going to read your emails, or respond to them in any way?

Tuesday, November 15, 2011

Update content in AJAX with partialRender

The easiest way to update content in AJAX is to use the partialRender method.
For this exemple I have three files: a controller (HelloWorldController.php) and two views (index.php and _ajaxContent.php)

controllers/HelloWorldController.php

class HelloWorldController extends CController
{
    public function actionIndex()
    {
        $data = array();
        $data["myValue"] = "Content loaded";
 
        $this->render('index', $data);
    }
 
    public function actionUpdateAjax()
    {
        $data = array();
        $data["myValue"] = "Content updated in AJAX";
 
        $this->renderPartial('_ajaxContent', $data, false, true);
    }
}
The actionIndex set myValue to "Content loaded" and this variable is passed to the view "index.php" and to "_ajaxContent.php"

Note: if using accessRules() in your controller file, you will need to modify accessRules() by adding the appropriate part of the function name to a rule set - in this case 'updateajax' like this:
array('allow',  // allow all users to perform 'index' and 'view' actions
    'actions'=>array('index','view','updateajax'),
    'users'=>array('*'),
        ),

views/helloWorld/index.php

<div id="data">
   php $this->renderPartial('_ajaxContent', array('myValue'=>$myValue)); ?>
div>
 
php echo CHtml::ajaxButton ("Update data",
                              CController::createUrl('helloWorld/UpdateAjax'), 
                              array('update' => '#data'));
?>
The ajaxButton call "actionUpdateAjax" and the returned data are inserted in the div "data"

views/helloWorld/_ajaxContent.php

 echo $myValue ?>
Display $myValue

Now, run index.php?r=helloWorld
Enjoy!

Sunday, November 13, 2011

How to create a Yii Behavior

Agile Web Application Development with Yii 1.1 and PHP5Yii FrameworkFirst of all let’s find out what is exactly a behavior in Yii’s language (text extracted from Yii’s Definitive Guide):
A behavior is an object whose methods can be ‘inherited’ by its attached component through the means of collecting functionality instead of specialization (i.e., normal class inheritance). A component can be attached with several behaviors and thus achieve ‘multiple inheritance’.
Behavior classes must implement the [IBehavior] interface. Most behaviors can extend from the CBehavior base class. If a behavior needs to be attached to a model, it may also extend from CModelBehavior or CActiveRecordBehavior which implements additional features specifc for models.
This means that if we require additional features to the models we could extend them by using behaviors and also, that a model could actually implement more than one behavior thus extending endlessly its functionality.
Behaviors is the answer to those who wish to do things that differ from normal use and they need to be shared among other models but not to all of them. What that means? Well, IMHO, I think that if you need a special functionality that is shared among model objects then I suggest that would it better that you create a class that extends from the CActiveRecord and then extend your models from it.
I heard so many times that people wishes to create functions in controllers and we should stick to the MVC approach as it is, and not try to reinvent the wheel with things that come out our creative minds. If you need to do specific actions thing about a controller but if that action involves DB data then work with Models. This is a long discussion that could hold an article by itself; let’s be focus with this article.

Building and Using a Behavior

Our behavior will transform a model into a JSON array and as the Yii guide says, it implements the IBehavior interface as it extends from CBehavior. The code is extracted from my own extension behavior EJsonBehavior, here it is:




















































//
// EJsonBehavor extends from CBehavior
class EJsonBehavior extends CBehavior{
//
// this property will hold a reference to
// its owner - the model class that will
// have this behavior attached to it
private $owner;
//
// this property will reference the
// relations of the model class -owner
private $relations;
public function toJSON(){
//
// getting a reference to model class
// having this behavior attached to it
$this->owner = $this->getOwner();
//
// making sure it is a CActiveRecord descendant
if (is_subclass_of($this->owner,'CActiveRecord')){
//
// play with it!
//
// get model attributes
$attributes = $this->owner->getAttributes();
//
// if this model has related model classes
// get them attributes
$this->relations     = $this->getRelated();
//
// structure the to-be-converted JSON
$jsonDataSource = array('jsonDataSource'=>array('attributes'=>$attributes,'relations'=>$this->relations));
//
// return the JSON result
return CJSON::encode($jsonDataSource);
}
return false;
}
//
// returns related model's attributes
private function getRelated()
{
$related = array();
$obj = null;
$md=$this->owner->getMetaData();
foreach($md->relations as $name=>$relation){
$obj = $this->owner->getRelated($name);
$related[$name] = $obj instanceof CActiveRecord ? $obj->getAttributes() : $obj;
}
return $related;
}
} // end of class
The important thing about the above code is not the funcitonality exposed, converting the model to a JSON array, but how we could get a hold to the behavior’s parent and access all its properties. That means, that by the same technique we could use that reference (owner) to play with the database referred by the object itself (check for example the code of the SLUG behavior).
Attaching the Behavior to a Model
This is the easiest part -yes, it is true, writing behaviors is a pretty easy thing with Yii. One way is the one referred on the wiki, which is the way I use it when I just need the use of a behavior certain times but the way I mostly use them is like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//
// This function is in the model
// where we want to attach the
// behavior too
public function behaviors() {
//
// needs to return an array
// of behavior objects
return array(
'EJsonBehavior'=>array(
//
// please check how it says to Yii
// where the class is located
'class'=>'application.behaviors.EJsonBehavior'
),
);
}
In the code above, you see how I tell Yii where the class is located in my applications folder; in this case I say to Yii to look for our behavior in the protected/behaviors folder and inside it there is a file EJsonBehavior.php which holds a behavior with a class name as the name of the file -EJsonBehavior.
Once we have attached the behavior to our model class, to use it is as simple as to call its public methods and/or properties. With our behavior above, we just do:
1
2
3
//
// pfff, so easy...
echo $model->toJSON();
After you have seen how easy is to create behaviors, having a look to the code of the Behaviors list at Yii’s site, will incredibly help your current learning curve. Hope this article has helped you to better understand behaviors.

Behaviors & events

These features provide endless possibilities and unbelievable flexibility, but as current documentation does not give more than a few examples, it might be difficult to fully understand their internals and requirements.
It should be noted that they do mostly the same thing. You can attach behaviors and event handlers to components to modify the components' behavior.

Events

It is useful when you want to interrupt the normal application flow without extending base classes.
For example, enabling gzip compression on the output could be done via extending CWebApplication. But because there are entry points for event handlers, one can do this:
Yii::app()->onbeginRequest = create_function('$event', 'return ob_start("ob_gzhandler");'),
Yii::app()->onendRequest = create_function('$event', 'return ob_end_flush();'),
You can create an event handler -- which is simply a method in some class with a specific signature -- and attach it to the event of an object. You can add as many event handlers as you wish, from as many objects as you wish. If the event handler is, effectively static, then you can create the object as you assign it:
$test_comp->onSomethingGoesOn = array(new SomeClass, 'eventHandler1');
$test_comp->onSomethingGoesOn = array(new SomeOtherClass, 'eventHandler2');
$test_comp->onSomethingGoesOn = array(new YetAnotherClass, 'eventHandler3');
As long as you have a handle on the object, then you can add an event handler to it.
At some point, you can then raise the event with something like one of these:
$test_comp->onSomethingGoesOn(new CEvent($this));
$test_comp->onSomethingGoesOn(new CEvent());
So, basically, it allows you to build a list of function calls that can later be executed, in the order they were added. It can save you passing around a lot of object refs and building conditional code, since you can still raise the event, even if it doesn't do anything.

Behaviors

Behaviors are simply a way of adding methods to an object.
Take this scenario: You have 2 classes: MySuperClass1, MySuperClass2. There might be lots of methods from MySuperClass1 & 2 that you want in some new class, say MyBoringClass. Unfortunately, php does not allow for this:
class MyBoringClass extends MySuperClass1, MySuperClass2 {
}
This is where behaviors come in. Instead, you can go:
class MyBoringClass extends MySuperClass1 {
}
 
$classInstance = new MyBoringClass();
$classInstance->attachbehavior('uniqueName', new MySuperClass2);
Now $classInstance has all the methods from MySuperClass1 and MySuperClass2. Since MySuperClass2 is being used as a behavior, it has to extend CBehavior. The only caveat to this is an attached behavior cannot override any class methods of the component it is being attached to. If a method already exists, if it be from the original class or already added by a previously attached behavior, it will not be overwritten.
In an OO language like Ruby, it's quite possible to start with a completely empty object and simply build its behavior as you go along. Yii provides this behavior with a little magic. The key is that the class you wish to add the behavior from must extend Cbehavior.
class SomeClass extends CBehavior
{
    public function add($x, $y) { return $x + $y; }
}
Then use with:
$test_comp = new TestComponent(); 
$test_comp->attachbehavior('blah', new SomeClass);
$test_comp->add(2, 5);
So, in this case, you are extending the functionality of an object with functionality of another object.
After studying this cookbook page you are encouraged to reread the corresponding guide page as it contains advanced information (for example, if you are familiar with interfaces, you might find it enough to implement IBehavior before extending CBehavior).

Friday, November 11, 2011

How to work with flash messages

Summary

Set your messages in a controller:
Yii::app()->user->setFlash('success', "Data1 saved!");
Yii::app()->user->setFlash('error', "Data2 failed!");
Yii::app()->user->setFlash('notice', "Data3 ignored.");
Display them in your view:

    foreach(Yii::app()->user->getFlashes() as $key => $message) {
        echo '
' . $key . '">' . $message . "
\n"; } ?>

Setting flash messages

A flash message is used in order to keep a message in session through one or several requests of the same user. By default, it is removed from session after it has been displayed to the user. Flash messages are usually used in combination with HTTP redirections, because in this case there is no view, so messages can only be displayed in the request that follows redirection.
A flash message has a name and a content (AKA key and value). It is an entry of an associative array. The name is a string: often "notice", "success", or "error", but it can be anything. The content is usually a string. You can put HTML tags in your message if you display it raw. You can also set the message value to a number or an array: it will be serialized and kept in session like a string.
Flash messages can be set using the setFlash() Method of CWebUser. For example, if you would like to inform the user that his changes were successfully saved, you could add the following line to your Controller:

Yii::app()->user->setFlash('success', "Data saved!");
$this->redirect(array('thing/view', 'id' => 1));
In this example we used the key 'success'. If you want to define more than one flash messages, you will have to use different keys.

Displaying flash messages

To check for flash messages we use the hasFlash() Method and to obtain the flash message we use the getFlash() Method. Since Yii v1.1.3, there is also a method getFlashes() to fetch all the messages.
By default, fetching a message deletes it from the session. This means that a message is meant to be displayed only on the first page served to the user. The fetching methods have a boolean parameter that can change this behavior. See the API links in the previous paragraph.

Displaying statically

So showing of the flash message defined above in a view is done by
 if(Yii::app()->user->hasFlash('success')):?>
    <div class="info">
        php echo Yii::app()->user->getFlash('success'); ?>
    div>
php endif; ?>
These few lines of code will make a flash message with the key "success" visible to the user within a div of class "info". The message will be displayed until this or another page is (re)loaded in the browser.
If you want to always display all the flash messages, then you should add a block to your layout (by default protected/views/layout/main.php). Here is a more elaborate example:

$flashMessages = Yii::app()->user->getFlashes();
if ($flashMessages) {
    echo '
    '; foreach($flashMessages as $key => $message) { echo '
  • ' . $key . '">' . $message . "
  • \n"; } echo '
'; } ?>
The default CSS created by the Yii script yiic webapp has directives for three classes of flash messages on a div tag: flash-error, flash-notice, flash-success.
The best way to know if some flash messages are set is to check if Yii::app()->user->getFlashes() is empty. Since v1.1.7, Yii keeps an associative array of the flash keys in the form array("key1" => 0, ...), or null if not flash message is set. You can fetch this with Yii::app()->user->getState(CWebUser::FLASH_COUNTERS) but this is not recommended, as Yii could change this internal process.

Displaying dynamically (with Javascript)

If you want the flash message to appear somewhere above the content and then automatically fade out after a few seconds, you will have to add the following lines to your view:

Yii::app()->clientScript->registerScript(
   'myHideEffect',
   '$(".info").animate({opacity: 1.0}, 3000).fadeOut("slow");',
   CClientScript::POS_READY
);
?>
With these lines of code we register a piece of jQuery (already included with YII) javascript code, using 'myHideEffect' as ID. It will be inserted in the jQuery's ready function (CClientScript::POS_READY). Due to the chainablity of jQuery the little script will run two effects on the .info DIV sequentially:
.animate({opacity: 1.0}, 3000)
Normally this would animate the .info DIV to a full opacity within 3 seconds. But the DIV is already rendered with full opacity upon page load, so calling this effect will just cause a delay for 3 seconds.
.fadeOut("slow")
This is the fadeOut effect which will hide the .info DIV at slow speed.

Understanding Scenarios

Scenarios are an extremely useful tool for separating validation tasks on any class you use derived from CModel. In this tutorial we will use CActiveRecord.

Specifying a scenario

The first thing is to initialize the Model instance with a scenario. This can be done one of two ways.

1. New CActiveRecord instance with constructor parameter

$model = new MyActiveRecord('formSubmit');
In this example MyActiveRecord extends CActiveRecord and formSubmit is a validation scenario.

2. Pre-existing CActiveRecord instance from find() or other scource

$model = MyActiveRecord::model()->find('id = :id', array(':id' => 1);
$model->scenario = 'formSubmit';
This example is the same as example one except we are switching to a scenario on a pre-existing Model instance.

Creating scenario specific validation rules

Firstly it is important to note that any rules not assigned a scenario will be applied to all scenarios. This can be useful for building a pseudo-inheritance structure of rules. Beware however that setting a validator for any property on a model marks it as safe for massive assignments unless the 'unsafe' rule is used.
Further Reading:
Reference: Model rules validation
Understanding "Safe" Validation Rules

Example of scenario rules:

public function rules() {
  return array(
    array('name', 'required'),
    array(
      'name', 'match', 'not' => true, 'pattern' => '/[^a-zA-Z0-9 ]/',
      'message' => 'Name must consist of letters, numbers and spaces only', 'on' => 'formSubmit'
    ),
  );
}
Note that the rule property that specifies a scenario is 'on' so in this example if there is no scenario then the only rule that applies to name is required. If the Model is set to the scenario 'formSubmit' then the required rule will still apply but so will the match rule.
So to break this down:
$model = new MyActiveRecord('formSubmit');
$model->name = 'Joe Blogs';
if ($model->validate()) {
//this will pass validation as both the required rule and the match rule are satisfied
}
 
$model = new MyActiveRecord('formSubmit');
$model->name = 'Joe Blogs - is awesome!!!!';
if ($model->validate()) {
//this will fail validation as the match rule is not satisfied
}
 
$model = new MyActiveRecord();
$model->name = 'Joe Blogs - is awesome!!!!';
if ($model->validate()) {
//this will pass validation as the match rule is no longer checked
}
 
$model = new MyActiveRecord('formSubmit');
$model->name = null;
if ($model->validate()) {
//this will fail validation as the required rule is not satisfied
}
 
//Note: the default scenario for CActiveRecord is 'insert' so keep this in mind
//when using these examples

Conclusion

Now when you validate user inputs you can stratify or separate different input rules on validation. An example of this is wanting to apply more rigid rules to users then to say internal business logic.

Tutorial: Creating a jQuery plugin

Tutorial: Creating a jQuery plugin
Learn how to create a jQuery plugin from scratch – the basics, options, compatibility and examples.

The Basics

A plugin is written as a method or function.

Creating a jQuery Function

Syntax
The function has to return this.each(..) to maintain chainability – so that the function can be used with a single or several jQuery objects.
jQuery.fn.myFunction = function(){
    return this.each(function(){
        // element-specific code here
    });
};
Example
jQuery.fn.makeTextRed = function(){
    return this.each(function(){
        $(this).css('color', 'red');
    });
};
 
// Example usage
$('#my-div').makeTextRed(); // make text in "my-div" red
$('p').makeTextRed(); // make all paragraphs red

Creating a jQuery Method

Syntax
jQuery.myMethod = function(){
    // code here
};
Example
jQuery.sayHelloWorld = function(){
    alert('Hello World');
};
 
// Example usage
$.sayHelloWorld(); // alerts "Hello World"

Options

Make your plugin as flexible and user friendly as possible using options. The $.extend() method takes two or more objects as arguments and merges the contens of them into the first object.
Example
A function that set text color (red by default).
jQuery.fn.makeTextColored = function(settings){
    var config = {
        'color': 'red'
    };
    if (settings){$.extend(config, settings);}
 
    return this.each(function(){
        $(this).css('color', config.color);
    });
};
We can now choose use this function passing the settings parameter or not.
$('#my-div').makeTextColored(); // make text red (default)
$('#my-div').makeTextColored('blue'); // make text blue

Compatibility

As the $ variable might be used by other plugins, use a alias technique to make your plugin forward-compatible.
(function($){
$.fn.myFunction = function() {
    return this.each(function() {
        // element-specific code here
    });
 };
})(jQuery);
We pass jQuery to the function and can now use whatever alias for jQuery we like. So instead of $ you could also use any other valid JavaScript variable name.

The jQuery Plugin Checklist

This is a list of important points to remember when developing a jQuery plugin (from jQuery.com).
  • Name your file jquery.[insert name of plugin].js, eg. jquery.debug.js
  • All new methods are attached to the jQuery.fn object, all functions to the jQuery object.
  • inside methods, this is a reference to the current jQuery object.
  • Any methods or functions you attach must have a semicolon (;) at the end – otherwise the code will break when compressed.
  • Your method must return the jQuery object, unless explicity noted otherwise.
  • Use this.each to iterate over the current set of matched elements.
  • Always attach the plugin to jQuery instead of $, so users can use a custom alias via noConflict().

jQuery Plugin Templates

These are two good code templates to start from when developing a jQuery plugin.

Function Template

(function($){
    $.fn.myPlugin = function(settings){
        var config = {
            'foo': 'bar'
        };
        if (settings){$.extend(config, settings);}
 
        return this.each(function(){
            // element-specific code here
        });
    };
})(jQuery);

Method Template

(function($){
    $.myPlugin = function(settings){
        var config = {
            'foo': 'bar'
        };
        if (settings){$.extend(config, settings);}
 
        // code here
 
        return this;
    };
})(jQuery);

Example: jQuery Slideshow Plugin

I have chosen to use very simple examples so far in order for you to get started. The following example is a bit more complex and might help to get your inspiration going.
It uses the function setInterval() in combination with the jQuery effects fadeOut() and fadeIn() to cycle any number of images within a HTML-element.

The Setup

HTML
<div id="slideshow">
    <img src="img/sample-image-1.png" alt="" />
    <img src="img/sample-image-2.png" alt="" />
    <img src="img/sample-image-3.png" alt="" />
    <img src="img/sample-image-4.png" alt="" />
</div>
CSS
#slideshow img {
    display: none;
    position: absolute;
}
JavaScript
(function($){
    $.simpleSlideShow = function(selector, settings){
        // settings
        var config = {
            'delay': 2000,
            'fadeSpeed': 500
        };
        if ( settings ){$.extend(config, settings);}
 
        // variables
        var obj = $(selector);
        var img = obj.children('img');
        var count = img.length;
        var i = 0;
 
        // show first image
        img.eq(0).show();
 
        // run slideshow
        setInterval(function(){
            img.eq(i).fadeOut(config.fadeSpeed);
            i = ( i+1 == count ) ? 0 : i+1;
            img.eq(i).fadeIn(config.fadeSpeed);
        }, config.delay);
 
        return this;
    };
})(jQuery);

Usage

To enable slideshow on the #slideshow div, we simply call it using the following JavaScript code:
<script type="text/javascript">
$.simpleSlideShow('#slideshow');
</script>
Because we allow settings to change the behaviour of the slideshow, we could make it wait 5 seconds between images and set the “fade” duration to 200 ms using:
<script type="text/javascript">
$.simpleSlideShow('#slideshow', {'delay':5000, 'fadeSpeed': 200});
</script>
View Example Download Example
 

5 Tricks to Increase Google Page Rank for Your Blog

Google page rank is an elusive term that most bloggers don't completely understand. In fact, there are probably few people in the world who completely understand it, because Google keeps the secrets of its page rank algorithm very guarded. Boosting your Google page rank isn't something you can do in a day. If it were, everyone would have a Google Page Rank of 10. Keep reading to learn a few of the tricks to increase your blog's Google page rank that are fairly easy to implement over time.
1. Get Incoming Links from High Quality Related Sites

The best way to increase your Google page rank might not make a difference over night, but it will make a big difference in time. The key is to get incoming links to your blog from highly authoritative and well-trafficked websites and blogs that are related your blog's topic.

For example, if you write a blog about finance, getting a link from The Wall Street Journal website would give your blog a big boost. If you could get more high quality links from popular sites such as Fortune.com, SmartMoney.com, and so on, your blog's Google page rank would most certainly jump.
Ads

Make money with ForexLiteForex made me $74,300 richer Anyone wants to join in?LiteForex.com

Ping Blog FreePing your blog, site or RSS Feed for Free! Gain traffic and exposurewww.blogpingtool.com

Biotech Answers:Find them at Pharma IQ. We Make Pharma Simplerwww.Pharma-IQ.com
2. Remember to Use SEO Techniques
Search engine optimization is an important part of increasing Google page rank. Read the top 10 SEO tips, and make sure you're using them.
3. Write Original Content
Do not copy content from another site. Even if you're copying and republishing your own content from one page or one site to another, do not do it. Google's algorithm cannot tell the difference and will either give the originating site the credit and downgrade the others or downgrade all of the sites that publish the duplicated content. Google acts harshly toward any kind of content scraping, even if you're completely innocent. Once your page rank is downgraded, it can be nearly impossible to get it back up again.
4. Don't Go Link Crazy
Many bloggers hear that it's important to have incoming links to boost their blog's Google page rank, so they start leaving comments anywhere and everywhere across the web, participating in random link exchanges with anyone who is willing to participate, and so on. Remember, as the first item on this list says, Google's algorithm cares about quality links, not quantity. In fact, your page rank could be downgraded if your blog is deemed to be little more than a bunch of links.
5. Write Great Content
If you write great content, people will want to link to it, particularly high quality websites. Get on the radar screen of popular bloggers and websites by leaving comments, writing guest posts, participating in forums, emailing directly, writing articles, and so on. Build relationships with people who write for high quality sites, and the number of quality, incoming links you get to your blog will grow organically over time.
Search Engine Optimization Tips

Beginner SEO Tips
Intermediate SEO Tips
Advanced SEO Tips

Wordpress Plugins to Boost Traffic and More

7 Wordpress Plugins to Boost Traffic
5 Wordpress Plugins to Increase Page Views
6 Wordpress Plugins to Increase Comments

About Linkbuilding

11 Free Link Building Tips
Link Building vs. Linkbaiting
Where to Find Linkbait Blog Post Ideas

7 reasons to switch from Drupal to Yii

Drupal 7 is about to be released, so many organizations need to decide whether to upgrade from Drupal 5 or 6. Drupal is fine if you're building lots of websites and need to create new sites quickly without much coding, or if you just need a blog-on-steroids content site.

Running on Drupal is like living in a double-wide: it's compromise if you can't afford a custom home. If you have a site that started on Drupal and has grown enough to employ full-time developers, you should migrate your site to the Yii PHP framework. (PHP haters can follow The Onion and use the Django Python framework, although it will take more time to change frameworks and programming languages.)

I'm the CTO of a site that switched from Drupal to Yii on April 30th 2010. It was hard to find information when we were debating a rewrite and there wasn't even a book about Yii yet. There were a few comments about switching from Drupal to Yii but they didn't include enough data to reassure me. I was worried that Yii might be slower than our heavily-optimized install of Drupal, so I decided to rewrite the core 20% of our site (which provided 80% of our functionality) in 30 days. It seemed like a great way to test the productivity and performance of the Yii framework, and if Yii wasn't an improvement after that month we could always switch back to Drupal and copy over any new data.

Yii was much faster than Drupal for our site with 150,000 nodes (each with a rewritten URL) and 50,000 visitors per day. Yes, we were working crazy hours for those 30 days (and the following 15), but it was worth it. The time that we previously spent working around Drupal's slow queries was put to better use, and it was a lot more fun to develop on Yii than on Drupal. The real benefit of Yii came later when we redesigned our site. With Yii's MVC, we only had to change 2 layout files vs a few dozen in Drupal.

I just wish we switched a year earlier. Here's what we learned:

Drupal isn't the best way to avoid starting from scratch. Drupal primary selling point to developers is "why roll your own CMS?" Like many developers, I've written entire web applications from scratch (in 1999 and 2000) and appreciated being able to focus on the unique business needs of the application instead of the writing my own code to handle all aspects of authentication, form validation, SQL injection attack prevention, etc. The company I helped found in early 2007 had a prototype website on Drupal, and I was willing to see what Drupal could do before throwing it away for Ruby on Rails. The Ruby craze reminded me of the Java craze in 1997. I was an intern at a WebEx competitor in 1997-99 that killed their performance by coding their server in Java before server hardware and VM optimizations allowed scalability. PHP had proven itself with the Friendster rewrite and at Facebook, and our users didn't want to see a fail whale if we ran into scalability problems with Ruby.

Sure, it's easier to get started with Drupal than coding every line of PHP yourself. But a bunch of PHP 5 frameworks were launched in 2008 and were put to the test in 2009. A PHP developer starting on a web application now (and working full time on only that site) would either choose a framework or start from scratch and use PHP libraries (PECL or PEAR.)
If Drupal is a framework, only Rube Goldberg could love it. Drupal is designed to be extensible without much PHP programming. That's fine if you're just styling a simple content site or have little traffic. If you're working full-time writing modules to customize forms and add functionality, you'll spend more time suppressing Drupal functionality that you don't want than you would building on a framework. Yii takes the opposite approach — you can use Ruby on Rails-like ORM if it's fast enough and only optimize the 10% of queries that need hand-coded MySQL.
Community-contributed modules are prone to featuritis and the bugs that result from unneeded complexity. There are too many Drupal contributed modules and if you have full-time developers you'll probably just decide as we did to assimilate portions of contributed modules into your own custom modules. Drupal's image resizing-and-caching modules are a great example of this. Because the modules are designed to be generic (so they can work an arbitrary number of other modules!), they include tons of functionality that you'll never use. In our case, we just needed to make thumbnails of various sizes, which the ImageMagick convert binary does. To get that, we had to enable 4 modules, each with a bunch of php files: ImageAPI, the ImageAPI for ImageMagick, ImageCache, and the ImageCache UI. Then the actual commands to generate thumbnails are in 2 tables in the database. If that stops working when you upgrade a part of the chain, it'll take a lot longer to diagnose the problem than if you built only what you needed.

Yii also has an image resizing extension (adapted from the Kohana Image Library), but it includes functionality we don't need (rotate! flip!) and is complicated because it is designed to let you easily switch between ImageMagick and GD. (GD has trouble with 2 MB+ images.) Despite all that, it still didn't enable us to resize images on the fly using a RewriteRule if the thumbnail didn't exist. So I created a simple index.php file that just handles RewriteRule callbacks on a dedicated image virtual host and sends shell-escaped commands directly to the convert binary. It means those RewriteRule callbacks don't go through the Yii index.php file, reducing the overhead and time required for image resize-and-cache operations. It's only a page of PHP and the arguments are sent in one call to the convert binary so it's much easier to test and maintain when we upgrade ImageMagick.
Drupal has PHP 4 baggage. Once I decided to consider PHP frameworks, I quickly realized I wanted only a 100% strict PHP 5 OOP framework. You don't see many people arguing that Drupal's procedural "hooks" approach is superior to OOP. While Drupal 7 requires PHP 5, like CodeIgniter and other older PHP frameworks it still carries the baggage of backward-compatibility. Who wants someone else's baggage?
Don't want Drupal 6 or 7 to slow down a Drupal 5 site? Deal with an outdated jQuery. For most sites that's fine. We really care about speed because Google and Microsoft have demonstrated that users are more loyal to fast sites. In 2009, when Drupal 6 was out and established, we stuck with Drupal 5 because of the measurable speed advantage. The problem is that Drupal 5 includes jQuery 1.0. You can add a contributed module to patch jQuery to 1.2 (and update the Drupal functions that reference it), but that's still an old version. Forget about jQuery 1.3x and Drupal 5.
Drupal's field API/content construction kit (CCK) will drive you crazy, and it's part of Drupal 7 core. Why use $node->ip when you can use $node->field_ip[0]['value']. And if you decide that two content types should both have a text field of the same name, CCK will put that in a table of its own (content_field_ip) with delightful column names (field_ip_value). Sure, Drupal can untangle that mess when a full node is loaded, but it isn't pretty to look at. MySQL queries will need many left joins to handle all of the extra CCK tables, and those unnecessarily-complex queries will end up in the slow query log all too often. I finally got fed up with trying to optimize all of these slow queries and decided to get rid of CCK, which is what led me to PHP frameworks, and then to Yii.

Migrating our data to Yii took about the same amount of time as it would have to kick the CCK habit yet stay on Drupal. However, we were able to start with a clean DB without all of the extra tables Drupal uses for its internal purposes. Our old DB had 173 tables; our new one has 54.
undefined Drupal is a LOT slower than Yii. Drupal only scales if you cache EVERYTHING with memcached and APC and rewrite all slow queries. Caching is especially important if you use SEO-friendly rewritten URLs for all of your links because each l() function is a separate database call. So an average page has 50+ queries on it, versus 3-5 in Yii. After switching, our average page download time decreased from 162 ms to 67 ms according to Google Webmaster Tools. Even better, Yii + APC is so fast that we haven't needed to use memchached, simplifying our code and operations.

Our server stats speak for themselves -- for the same number of simultaneous visitor requests (Apache processes), the DB and CPU utilization went way down. Memory use remained about the same. Over the last year, our traffic has increased 60% to 1.5 million monthly visits while MySQL queries have fallen by 66%

undefined

30+ PHP Best Practices for Beginners


PHP is the most widely-used language for programming on the web. Here are thirty best practices for beginners wanting to gain a firmer grasp of the fundamentals.
Editor’s Note: The “Best Practices” series has been my baby for three articles now. However, due to my focus on the CI video series, I’ve decided to hand off this next entry to Glen. Having said that, I’m not very good at keeping my mouth shut! I thought it might be fun to sporadically add a few rebuttals to his tips. I hope he doesn’t mind!

1. Befriend the PHP Manual

If you’re new to PHP, then it’s time to get acquainted with the awesomeness that is the PHP manual. The PHP manual is incredibly thorough and has truly helpful comments following each article. Before asking questions or trying to figure out an issue on your own, save some time and just head straight to the manual. Odds are the answer to your question is already nestled in a helpful article at the PHP.net site.

2. Turn on Error Reporting

Error reporting in PHP is very helpful. You’ll find bugs in your code that you might not have spotted earlier, as not all bugs keep the application from working. There are different levels of strictness in the reporting that you can use, but E_ALL will show you the most errors, critical and warnings alike.
Once you’ve gotten your application ready for production, you’ll want to turn off error reporting, or your visitors will see strange errors that they don’t understand.

3. Try an IDE

IDE’s (Integrated Development Environments) are helpful tools for any developer. While they’re not for everyone, an IDE definitely has its place. IDE’s provide tools like
  • syntax highlighting
  • code completion
  • error warnings
  • refactoring (reworking)
And many other features. There are plenty of great IDEs out there that support PHP.
Try an IDE

4. Try a PHP Framework

You can learn a lot about PHP just by experimenting with PHP frameworks. Frameworks like CakePHP or CodeIgniter allow you to quickly create PHP applications, without having to be an expert with PHP. In a sense, they’re almost like PHP training wheels that show you what a PHP application should look like, and show you valuable programming concepts (like separating the logic from the design, etc.).
Rebuttal: I personally wouldn’t recommend that beginners use a framework. Learn the fundamentals first. :)

5. Learn the DRY Approach

DRY stands for Don’t Repeat Yourself, and it’s a valuable programming concept, no matter what the language. DRY programming, as the name implies, is ensuring that you don’t write redundant code. Here’s an example from Reinhold Weber:
Learn the DRY approach
This code…
  1. $mysql = mysql_connect('localhost''reinhold''secret_hash');  
  2. mysql_select_db('wordpress'or die("cannot select DB");  
now with the DRY approach:
  1. $db_host = 'localhost';  
  2. $db_user = 'reinhold';  
  3. $db_password = 'secret_hash';  
  4. $db_database = 'wordpress';  
  5.   
  6. $mysql = mysql_connect($db_host$db_user$db_password);  
  7. mysql_select_db($db_database);  
You can read more about the DRY programming principle here and here.

6. Indent Code and Use White Space for Readability

If you don’t use indentations and white space in your code, the result looks like a Jackson Pollack painting. Ensure that your code is readable and easy to search because you’ll most definitely be making changes in the future. IDEs and advanced text editors can add indentation automatically.

7. “Tier” your Code

Tiering your applications is nothing more than separating the different components of the code into different parts. This allows you to easily change your code in the future. NETTUTS writer Jason Lengstorf has written an excellent article on how to tier your PHP applications for easier maintenance.

8. Always Use

Often times programmers try to take shortcuts when declaring PHP. Here are a few common ones:
  1.     echo "Hello world";  
  2. ?>  
  3.   
  4. "Hello world"; ?>  
  5.   
  6. <% echo "Hello world"; %>  
While these do save a few characters, all of these methods are depreciated and unofficial. Stick with the standard as it will be guaranteed to be supported in all future versions.

9. Use Meaningful, Consistent Naming Conventions

Naming this isn’t just for your own good. There’s nothing worse than trying to find your way through some other programmer’s nonsensical naming conventions. Help yourself and others by using names that make sense for your classes and functions.

10. Comment, Comment, Comment

Aside from using white space and indentations to separate the code, you’ll also want to use inline comments to annotate your code. You’ll thank yourself later when you’re needing to go back and find something in the code, or if you just can’t remember what a certain function did. It’s also useful for anyone else who needs to look over your code.

11. Install MAMP/WAMP

MySQL is the most popular type of database to use with PHP (though it’s not the only one). If you’re wanting to set up a local environment to develop and test your PHP applications on your computer, look into installing MAMP (Mac) or WAMP (Windows). Installing MySQL on your own computer can be a tedious process, and both of these software packages are drop-in installs of MySQL. Clean and simple.
Install MAMP/WAMP

12. Give your Scripts Limits

Putting a time limit on your PHP scripts is a very critical thing. There are times when your scripts will fail, and when they do, you’ll want to use the set_time_limit function to avoid infinite loops and database connection timeouts. The set_time_limit puts a time limit on the maximum number of seconds a script will run (the default is 30). After that time period, a fatal error is thrown.

13. Use Objects (or OOP)

Object-oriented programming (OOP) uses objects to represent parts of the application. Not only is OOP a way to break your code into separate, logical sections, it also reduces code repetition and makes it much easier to modify in the future. If you’re wanting to learn more, DevArticles has a great write-up on object-oriented programming with PHP.

14. Know the Difference Between Single and Double Quotes

It is more efficient to use single quotes in strings as the parser doesn’t have to sift through the code to look for escaped characters and other things that double quotes allow. Always try to use single quotes whenever possible.
Rebuttal: Actually, that’s not necessarily true. Benchmark tests show that, when testing strings without variables, there are definite performance benefits to using double quotes.

15. Don’t Put phpinfo() in your Webroot

Phpinfo is a beautiful thing. By simply creating a PHP file that has
  1.   
and dropping it onto the sever somewhere, you can instantly learn everything about your server environment. However, a lot of beginners will place a file containing phpinfo() in the webroot of the server. This is a really insecure practice, and if prying eyes gain access, it could potentially spell doom for your server. Make sure phpinfo() is in a secure spot, and as an extra measure, delete it once you’re done.
don't put phpinfo() in your web root

16. Never, Ever Trust Your Users

If your application has places for user input, you should always assume that they’re going to try to input naughty code. (We’re not implying that your users are bad people. It’s just a good mindset.) A great way to keep your site hacker-free is to always initialize your variables to safeguard your site from XSS attacks. PHP.net has an example of a properly secured form with initialized variables:
  1. if (correct_user($_POST['user'], $_POST['password']) {  
  2.     $login = true;  
  3. }  
  4.   
  5. if ($login) {  
  6.     forward_to_secure_environment();  
  7. }  
  8. ?>  

17. Store Passwords with Encryption

Many PHP beginners often plunk sensitive data like passwords into the database without applying any encryption. Consider using MD5 to encrypt passwords before you put them into the database.
  1. echo md5('myPassword'); // renders - deb1536f480475f7d593219aa1afd74c  
Rebuttal: Keep in mind, however, that MD5 hashes have long since been compromised. They’re absolutely more secure than not, but, with the use of an enormous “rainbow table,” hackers can cross reference your hash. To add even more security, consider adding a salt as well. A salt is basically an additional set of characters that you append to the user’s string.


18. Use Database Visualization Design Tools

If you’re finding it difficult to plan and modify databases for your PHP applications, you might look into using a database visualization tool. MySQL users can work with DBDesigner and MySQL Workbench to visually design your databases.
use database visualization design tools

19. Use Output Buffering

Output buffering is a simple way to greatly improve the performance and speed of your PHP script. Without output buffering, your script will show the HTML on the page as it’s processed – in pieces. Adding output buffering allows the PHP to store the HTML as a variable and send it to the browser in one chunk.
To enable output buffering, simply add ob_start() like so at the top of the file.

Rebuttal: Though not required, it’s generally considered to be a good practice to go ahead and append the “ob_end_flush();” function as well to the bottom of the document. P.S. Want to compress the HTML as well? Simply replace “ob_start();” with “ob_start(‘ob_gzhandler’)”;
Refer to this Dev-tips article for more information.
  1.   
  2. 'ob_gzhandler'); ?>  
  3.   

20. Protect your Script From SQL Injection

If you don’t escape your characters used in SQL strings, your code is vulnerable to SQL injections. You can avoid this by either using the mysql_real_escape_string, or by using prepared statements.
Here’s an example of mysql_real_escape_string in action:
  1. $username = mysql_real_escape_string( $GET['username'] );  
and a prepared statement:
  1. $id = $_GET['id'];  
  2. $statement = $connection->prepare( "SELECT * FROM tbl_members WHERE id = ?" );  
  3. $statement->bind_param( "i"$id );  
  4. $statement->execute();  
By using prepared statements, we never embed the user’s inputted data directly into our query. Instead, we use the “bind_param” method to bind the values (and escaping) to the query. Much safer, and, notably, faster when executing multiple CRUD statements at once.
Read more on creating secure PHP applications at Nettuts.

21. Try ORM

If you’re writing object-oriented PHP, then you can use the nifty object relational mapping (ORM). ORM allows you to convert data between relational databases and object-oriented programming languages. In short: ORM allows you to work with databases the same way that you work with classes and objects in PHP.
There are plenty of ORM libraries for PHP like Propel, and ORM is built into PHP frameworks like CakePHP.

22. Cache Database-Driven Pages

Caching database-driven PHP pages is an excellent idea to improve the load and performance of your script. It’s really not all that difficult to create and retrieve static files of content with the help of our good friend ob_start(). Here’s an example taken from Snipe.net:
  1. // TOP of your script  
  2. $cachefile = 'cache/'.basename($_SERVER['SCRIPT_URI']);  
  3. $cachetime = 120 * 60; // 2 hours  
  4. // Serve from the cache if it is younger than $cachetime  
  5. if (file_exists($cachefile) && (time() - $cachetime < filemtime($cachefile))) {  
  6. include($cachefile);  
  7. echo "";  
  8. exit;  
  9. }  
  10. ob_start(); // start the output buffer  
  11. // Your normal PHP script and HTML content here  
  12. // BOTTOM of your script  
  13. $fp = fopen($cachefile'w'); // open the cache file for writing  
  14. fwrite($fp, ob_get_contents()); // save the contents of output buffer to the file  
  15. fclose($fp); // close the file  
  16. ob_end_flush(); // Send the output to the browser  
This bit of code will use a cached version of a page that is less than 2 hours old.

23. Use a Caching System

If you’re wanting a more robust caching system, there are a few caching scripts for PHP that might be more complete than the above example.
use a caching system

24. Validate Cookie Data

Cookie data, like any data passed on the Web, can be harmful. You can validate cookie data with either the htmlspecialchars() or mysql_real_escape_string().

25. Use Static File Caching Systems

Aside from using database caching systems like Memcached, you might also want to try a templating system to increase performance in your PHP applications. Smarty is a robust templating system has caching built into it.

26. Profile your Code

Profiling your code with a tool like xdebug can help you to quickly spot bottlenecks and other potential problems in your PHP code. Some IDEs like Netbeans have PHP profiling capabilities as well.

27. Code to a Standard

Once you’ve gotten the ropes of PHP down, you can start learning about coding to a standard. There are differences between standards out there (say Zend and Pear), and finding one and sticking with it will help with the consistency of your coding in the long run.

28. Keep Functions Outside of Loops

You take a hit of performance when you include functions inside of loops. The larger the loop that you have, the longer the execution time will take. Take the extra time and line of code and place the function outside of the loop.

Editor’s Note: Think of it this way. Try to remove as many operations from the loop as possible. Do you really need to create that variable for every iteration of the loop? Do you really need to create the function each time? Of course not. :)

29. Don’t Copy Extra Variables

Some people like to try and make their code more appealing by copying predefined variables to smaller-named variables. This is redundant and could potentially double the memory of your script. Google Code has bad and good examples of variable usage:
Bad
  1. $description = strip_tags($_POST['description']);  
  2. echo $description;  
Good
  1. echo strip_tags($_POST['description']);  

Rebuttal: In reference to the comment about “doubling the memory,” this actually is a common misconception. PHP implements “copy-on-write” memory management. This basically means that you can assign a value to as many variables as you like without having to worry about the data actually being copied. While it’s arguable that the “Good” example exemplified above might make for cleaner code, I highly doubt that it’s any quicker.

30. Upgrade to the Latest Version of PHP

While it seems like a common sense thing, many people don’t upgrade PHP as often as they should. There are lots of performance increases between PHP 4 and PHP 5. Check your server to make sure you’re up to date.

31. Reduce the Number of Database Queries

Any way that you can cut back on the number of database queries, the better your PHP script will perform. There are tools like Stace (Unix) and Process Explorer (Windows) that allow you to find redundant processes and how you might combine them.
Reduce the number of database queries

32. Don’t be Afraid to Ask for Help

It’s only human nature to want to hide the fact that we don’t know much about a certain topic. Nobody likes being a n00b! But how are we going to learn without asking? Feel free to use forums, IRC, StackOverflow to ask more seasoned PHP developers questions. The PHP website has a page on getting PHP help.
Have any rebuttals of your own? I’m sure you do! Let’s start the debate.