Tizag.com Webmaster Tutorials - A collection of webmaster tutorials from HTML to PHP.

Wednesday, September 30, 2009

Send Mail using PHP

Send Email from a PHP Script Example



The first argument to this function is the recipient, the second specifies the message's subject and the third one should contain the body. So to send a simple sample message, we could use:



<?php
$to = "recipient@example.com";
$subject = "Hi!";
$body = "Hi,\n\nHow are you?";
if (mail($to, $subject, $body)) {
echo("<p>Message successfully sent!</p>");
} else {
echo("<p>Message delivery failed...</p>");
}
?>



Send Mail from HTML Form



<html><body>
<form method="post" action="sendmail.php">
Send Mail To:<input type="text" name="sendto">
Name:<input name="Name">
Email:<input type="text" name="Email">
Company:<input type="text" name="Company">
Phone:<input type="text"name="Phone">
Subscribe to mailing list:<input type="radio" name="list" value="No"> No Thanks <input type="radio" name="list" value="Yes" checked> Yes, keep me informed<br>
Message:<textarea name="Message" rows=5 cols=35></textarea>
<input type=submit name="send" value="Submit">
</form>
</body>
</html>


code in sendmail.php


<?php
$to = $_REQUEST['sendto'] ;
$from = $_REQUEST['Email'] ;
$name = $_REQUEST['Name'] ;
$headers = "From: $from";
$subject = "Web Contact Data";

$fields = array();
$fields{"Name"} = "Name";
$fields{"Company"} = "Company";
$fields{"Email"} = "Email";
$fields{"Phone"} = "Phone";
$fields{"list"} = "Mailing List";
$fields{"Message"} = "Message";

$body = "We have received the following information:\n\n"; foreach($fields as $a => $b){ $body .= sprintf("%20s: %s\n",$b,$_REQUEST[$a]); }

$headers2 = "From: noreply@YourCompany.com";
$subject2 = "Thank you for contacting us";
$autoreply = "Thank you for contacting us. Somebody will get back to you as soon as possible, usualy within 48 hours. If you have any more questions, please consult our website at www.oursite.com";

if($from == '') {print "You have not entered an email, please go back and try again";}
else {
if($name == '') {print "You have not entered a name, please go back and try again";}
else {
$send = mail($to, $subject, $body, $headers);
$send2 = mail($from, $subject2, $autoreply, $headers2);
if($send)
{header( "Location: http://www.YourDomain.com/thankyou.html" );}
else
{print "We encountered an error sending your mail, please notify webmaster@YourCompany.com"; }
}
}
?>

PHP mail() and SMTP Authentication



Part of what makes the PHP mail() function is so simple is its lack of flexibility. Most importantly and frustratingly, the stock mail() does not usually allow you to use the SMTP server of your choice, and it does not support SMTP authentication, required by many a mail server today, at all.


Fortunately, overcoming PHP's built-in shortcomings need not be difficult, complicated or painful either. For most email uses, the free PEAR Mail package offers all the power and flexibility needed, and it authenticates with your desired outgoing mail server, too. For enhanced security, secure SSL connections are supported.
Send Email from a PHP Script Using SMTP Authentication



To connect to an outgoing SMTP server from a PHP script using SMTP authentication and send an email:



  • Make sure the PEAR Mail package is installed.

  • Typically, in particular with PHP 4 or later, this will have already been done for you. Just give it a try. <

    *Adapt the example below for your needs. Make sure you change the following variables at least:

    • from: the email address from which you want the message to be sent.

    • to: the recipient's email address and name.

    • host: your outgoing SMTP server name.

    • username: the SMTP user name (typically the same as the user name used to retrieve mail).

    • password: the password for SMTP authentication.





Sending Mail from PHP Using SMTP Authentication - Example



<?php
require_once "Mail.php";

$from = "Sandra Sender <sender@example.com>";
$to = "Ramona Recipient <recipient@example.com>";
$subject = "Hi!";
$body = "Hi,\n\nHow are you?";

$host = "mail.example.com";
$username = "smtp_username";
$password = "smtp_password";

$headers = array ('From' => $from,
'To' => $to,
'Subject' => $subject);
$smtp = Mail::factory('smtp',
array ('host' => $host,
'auth' => true,
'username' => $username,
'password' => $password));

$mail = $smtp->send($to, $headers, $body);

if (PEAR::isError($mail)) {
echo("<p>" . $mail->getMessage() . "</p>");
} else {
echo("<p>Message successfully sent!</p>");
}
?>

Sending Mail from PHP Using SMTP Authentication and SSL Encryption - Example



<?php
require_once "Mail.php";

$from = "Sandra Sender <sender@example.com>";
$to = "Ramona Recipient <recipient@example.com>";
$subject = "Hi!";
$body = "Hi,\n\nHow are you?";

$host = "ssl://mail.example.com";
$port = "465";
$username = "smtp_username";
$password = "smtp_password";

$headers = array ('From' => $from,
'To' => $to,
'Subject' => $subject);
$smtp = Mail::factory('smtp',
array ('host' => $host,
'port' => $port,
'auth' => true,
'username' => $username,
'password' => $password));

$mail = $smtp->send($to, $headers, $body);

if (PEAR::isError($mail)) {
echo("<p>" . $mail->getMessage() . "</p>");
} else {
echo("<p>Message successfully sent!</p>");
}
?>

More Email Quick Tips

$subject2 = "Thank you for contacting us";
$autoreply = "Thank you for contacting us. Somebody will get back to you as soon as possible, usualy within 48 hours. If you have any more questions, please consult our website at www.oursite.com";

if($from == '') {print "You have not entered an email, please go back and try again";}
else {
if($name == '') {print "You have not entered a name, please go back and try again";}
else {
$send = mail($to, $subject, $body, $headers);
$send2 = mail($from, $subject2, $autoreply, $headers2);
if($send)
{header( "Location: http://www.YourDomain.com/thankyou.html" );}
else
{print "We encountered an error sending your mail, please notify webmaster@YourCompany.com"; }
}
}
?>


source: http://php.about.com/




Sending emails with attachments using PHP’s mail() function


First, generate a random hash to serve as a MIME Boundary:

$random_hash = md5(date('r', time()));

Next, set some email headers:

$headers = "From: noreply@geekology.co.za\r\nReply-To: noreply@geekology.co.za";

$headers .= "\r\nContent-Type: multipart/mixed; boundary=\"PHP-mixed-".$random_hash."\"";

then convert the attachment into a base64 string:

$attachment = chunk_split(base64_encode(file_get_contents("abc.zip")));



$to = "willem@geekology.co.za";

$subject = "A test email";

$random_hash = md5(date('r', time()));

$headers = "From: noreply@geekology.co.za\r\nReply-To: noreply@geekology.co.za";

$headers .= "\r\nContent-Type: multipart/mixed; boundary=\"PHP-mixed-".$random_hash."\"";

$attachment = chunk_split(base64_encode(file_get_contents("geekology.zip")));

$output = "
--PHP-mixed-$random_hash;
Content-Type: multipart/alternative; boundary='PHP-alt-$random_hash'
--PHP-alt-$random_hash
Content-Type: text/plain; charset='iso-8859-1'
Content-Transfer-Encoding: 7bit

Hello World!
This is the simple text version of the email message.

--PHP-alt-$random_hash
Content-Type: text/html; charset='iso-8859-1'
Content-Transfer-Encoding: 7bit

Hello World!


This is the HTML version of the email message.



--PHP-alt-$random_hash--

--PHP-mixed-$random_hash
Content-Type: application/zip; name=geekology.zip
Content-Transfer-Encoding: base64
Content-Disposition: attachment

$attachment
--PHP-mixed-$random_hash--";

echo @mail($to, $subject, $output, $headers);

taken from http://www.geekology.co.za/

Sunday, September 27, 2009

Model View Controller MVC

Model–View–Controller (MVC) is an architectural pattern used in software engineering. The pattern isolates business logic from input and presentation, permitting independent development, testing and maintenance of each.An MVC application is a collection of model/view/controller triplets (a central dispatcher is often used to delegate controller actions to a view-specific controller). Each model is associated with one or more views (projections) suitable for presentation (not necessarily visual presentation). When a model changes its state, it notifies its associated views so they can refresh. The controller is responsible for initiating change requests and providing any necessary data inputs to the model.

User interface logic tends to change more frequently than business logic, especially in Web-based applications. For example, new user interface pages may be added, or existing page layouts may be shuffled around. After all, one of the advantages of a Web-based thin-client application is the fact that you can change the user interface at any time without having to redistribute the application. If presentation code and business logic are combined in a single object, you have to modify an object containing business logic every time you change the user interface. This is likely to introduce errors and require the retesting of all business logic after every minimal user interface change.


How do you modularize the user interface functionality of a Web application so that you can easily modify the individual parts?

The MVC pattern separates the modeling of the domain, the presentation, and the actions based on user input into three separate classes [Burbeck92]:

Model. The model manages the behavior and data of the application domain, responds to requests for information about its state (usually from the view), and responds to instructions to change state (usually from the controller).

View. The view manages the display of information.

Controller. The controller interprets the mouse and keyboard inputs from the user, informing the model and/or the view to change as appropriate.

Model-View-Controller (MVC) is a classic design pattern often used by applications that need the ability to maintain multiple views of the same data. The MVC pattern hinges on a clean separation of objects into one of three categories — models for maintaining data, views for displaying all or a portion of the data, and controllers for handling events that affect the model or view(s).

Because of this separation, multiple views and controllers can interface with the same model. Even new types of views and controllers that never existed before can interface with a model without forcing a change in the model design.




Events typically cause a controller to change a model, or view, or both. Whenever a controller changes a model’s data or properties, all dependent views are automatically updated. Similarly, whenever a controller changes a view, for example, by revealing areas that were previously hidden, the view gets data from the underlying model to refresh itself.


We explain the MVC pattern with the help of a simple spinner component which consists of a text field and two arrow buttons that can be used to increment or decrement a numeric value shown in the text field. We currently do not have an element type that can directly represent a spinner component, but it easy is to synthesize a spinner using existing element types.



The spinner’s data is held in a model that is shared with the text field. The text field provides a view of the spinner’s current value. Each button in the spinner is an event source, that spawns an action event every time it is clicked. The buttons can be hooked up to trampolines that receive action events, and route them to an action listener that eventually handles that event. Recall that a trampoline is a predefined action listener that simply delegates action handling to another listener.

Depending on the source of the event, the ultimate action listener either increments or decrements the value held in the model — The action listener is an example of a controller.

The trampolines that initially receive the action events fired by the arrow buttons, are also controllers — However, instead of modifying the spinner’s model directly, they delegate the task to a separate controller (action listener).

Multiple Controllers

The MVC pattern allows any number of controllers to modify the same model. While we have so far focused only on the two arrow buttons as likely source of events, there is, in fact, a third event source in this example — Whenever the text field has focus, hitting the enter key fires off an action event that may potentially be handled by a different action listener than the one handling action events from the buttons.

This part of the topic is taken from http://www.enode.com/


Why Create My Own MVC Framework?

This article doesn't really advocate "You should write your own MVC web framework!" as is tries to explain "This is how MVC web frameworks work in theory, and why they are so great."

As of this writing, there are very few true MVC frameworks written in PHP. In fact, there is only one that I know of, Solar, that is entirely pure PHP 5 code. Another one out there is Cake, which is trying to be the "Ruby on Rails of PHP." I, personally, have a few problems with both of these frameworks. Both Solar and Cake fail to leverage existing code in PEAR, Smarty, etc. Cake appears a bit disorganized at the moment. Finally, Solar is the work of mostly a single person (not that Paul isn't a great coder or person, but there is only a single gatekeeper at the time of this writing). These may not be issues that concern you, and if they don't concern you, by all means check these two out.

The Old Way

If I could go back in time and look at code I wrote in early 2001, I would find a file called template.txt that looked something like:




require_once('config.php'); // Other requires, DB info, etc.

$APP_DB = 'mydb';
$APP_REQUIRE_LOGIN = false; // Set to true if script requires login
$APP_TEMPLATE_FILE = 'foo.php'; // Smarty template
$APP_TITLE = 'My Application';

if ($APP_REQUIRE_LOGIN == true) {
if (!isset($_SESSION['userID'])) {
header("Location: /path/to/login.php");
exit();
}
}

$db = DB::connect('mysql://'.$DB_USER.':'.$DB_PASS.'@localhost/'.$APP_DB);
if (!PEAR::isError($db)) {
$db->setFetchMode(DB_FETCHMODE_ASSOC);
} else {
die($db->getMessage());
}

// Put your logic here

// Output the template
include_once(APP_TEMPLATE_PATH.'/header.php');
include_once(APP_TEMPLATE_PATH.'/'.$APP_TEMPLATE_FILE);
include_once(APP_TEMPLATE_PATH.'/footer.php');

?>


Oh man, just looking at this code makes me cringe now. The idea with this approach was that every application fit into this set approach and I could just copy template.txt to myapp.php, change some of the variables, and then voila, it would work. However, this top-down approach has some serious flaws.

1. What if my boss wanted me to change myapp.php to output a PDF in some cases, HTML in others, and SOAP if the request posted XML directly?
2. What if this app required IMAP or LDAP authentication?
3. How would I go about handling various modes in the script (including edit, update, and delete)?
4. How would I handle multi-level authentication (admin versus non-admin)?
5. How would I turn on output caching?


The New Way

By bringing everything into an MVC framework, I could make my life a lot easier. Compare the following code:
Notice that this code has no apparent concern with connecting to a database, verifying the user is logged in, or outputting anything. The controller handles all of this.

If I wanted to authenticate against LDAP, I could create FR_Auth_LDAP. The controller could recognize certain output methods (such as $_GET['output']) and switch to the PDF or SOAP presenter on the fly. The event handler, delete, handles only deleting and nothing else. Because the module has an instance of the FR_User class, it's easy to check which groups that user is in, etc. Smarty, the template engine, handles caching, of course, but the controller could also handle some caching.

Switching from the old way to the MVC way of doing things can be a completely foreign concept to some people, but once you have switched, it's hard to go back. I know I won't be leaving the comforts of my MVC framework anytime soon.
Creating the Foundation

I'm a huge fan of PEAR and the PEAR_Error class. PHP 5 introduced a new class, Exception, which is almost a drop-in replacement for PEAR_Error. However, PEAR_Error has a few extra features that make it a more robust solution than Exception. As a result, the framework and foundation classes will use the PEAR_Error class for error handling. I will use Exception, however, to throw errors from the constructors, as they cannot return errors.

The design goals of the foundation classes are:

  • Leverage PEAR to quickly add features to the foundation classes.
  • Create small, reusable abstract foundation classes that will enable developers to build applications quickly within the framework.
  • Document all foundation classes using phpDocumentor tags.
  • Prepend all classes and global variables with FR to avoid possible variable/class/function collisions.

The class hierarchy will look something like this:

  • FR_Object will provide the basic features that all objects need (including logging, generic setFrom(), toArray()).
  • FR_Object_DB is a thin layer to provide child classes a database connection, along with other functions such classes might need.
  • FR_Object_Web is a thin layer that provides session and user information for web-based applications.
  • FR_Module is the base class for all applications (AKA "modules," "model," etc.) built in the framework.
  • FR_Auth is the base authentication class, which will allow for multiple authentication mechanisms.
  • FR_Auth_User is an authentication class to use in modules that require a valid, logged-in user.
  • FR_Auth_No is a dummy authentication class used for modules that require no authentication.
  • FR_Presenter is the base presentation class (the view) that will handle loading and displaying the applications after they have run.
  • FR_Presenter_smarty: the presentation layer will include the ability to load different drivers. Smarty is a great template class that has built in caching and an active community.
  • FR_Presenter_debug is a debugging presentation layer that developers can use to debug applications.
  • FR_Presenter_rest is a REST presentation layer that developers can use to output applications in XML.

Looking at the foundation classes, you can start to see the separate parts of the MVC framework. FR_Module provides for the basic needs of all of the modules (Model), FR_Presenter provides a way to display applications arbitrarily in different formats (Views). In the next part of this series I will create the controller, which will bring all of our foundation classes together in a single place.


Coding Standards

Before you start coding a cohesive framework, you might want to sit down with your team (or yourself) and talk about coding standards. The whole idea of MVC programming revolves around reusable and standardized code. I recommend talking about, at least:

* What are your coding standards regarding variable naming and indentation? Don't start a holy war, but hammer out the basics and stick to them, especially when it comes to your foundation classes.
* Decide on a standard prefix for your functions, classes, and global variables. Unfortunately, PHP does not support namespaces. As a result, it might be a good idea to prepend your variables to avoid name collisions and confusion. Throughout this article, I've prepended my global variables, functions and classes with FR_, so as to distinguish core foundation code from simple application code.
* I highly recommend using phpDocumentor to document your code as you actually code it. I will document all of the core foundation classes as well as my initial applications in this article. At my own place of employment, I run phpDocumentor via a cron job to compile documentation frequently from my code repository.

Coding the Foundation

With all of that theory out of the way, here are the foundation classes. Be sure to read the comments for my reasonings, ideas, and implementation details. I'm presenting a combination of things I've done in the past that work for me, and the results of a few years of trial and error. By no means is this the only way to program an MVC framework, but I think it provides a good overview of how things should work.
Filesystem Layout

The basic layout is simple and somewhat strictly defined. There is a directory for includes, which will follow a specific pattern to make it easy to use PHP's new __autoload() function. Another directory is for modules, which will have their own layout. The hierarchy looks like:

* /
o config.php
o index.php
o includes/


# No.php
# User.php

+ Module.php
+ Object.php
+ Object/
# DB.php
+ Presenter.php
+ Presenter/
# common.php
# debug.php
# smarty.php
+ Smarty/
o modules/
+ example/
# config.php
# example.php
# tpl/
* example.tpl
o tpl/
+ default/
+ cache/
+ config/
+ templates/
# templates_c/

You're probably thinking that's a lot of code! It is, but you'll get through it. At the end of this article and the series, you'll see that MVC programming will make your life a lot easier and speed up development time.

In the filesystem structure, all of the foundation classes live inside of includes/. The example laid out a sample module, as well. Each module has its own configuration file, at least one module file, and one template file. All modules reside in modules/. I've become accustomed to wrapping my modules in an outer-page template, which is what the tpl/ directory is for. Each "theme" or template group has its own template directory. For now, I'm going to use default/ as my outer-page template. Later I'll show how to create a presentation layer for modules that want to render themselves.


config.php
config.php provides a centralized location for global configuration variables, such as the DSN and log file location. Also, notice that I dynamically figure out the installation location on the file system. This will make installing and migrating your code simple if you use FR_BASE_PATH in your own code.

index.php
This is the controller. I will cover this in depth in the next article.

Object.php
This is the base class for all of the foundation classes. It provides some basic features that most, if not all, classes will need. Additionally, the child class FR_Object_DB extends this object and provides a database connection.

The idea is that, by having all children extend from a central object, all of the foundation classes will share certain characteristics. You could put the database connection directly into FR_Object, but not all classes need a database connection. I will talk about FR_Object_DB later.



* @package Framework
*/
abstract class FR_Object
{
/**
* $log
*
* @var mixed $log Instance of PEAR Log
*/
protected $log;

/**
* $me
*
* @var mixed $me Instance of ReflectionClass
*/
protected $me;

/**
* __construct
*
* @author Joe Stump
* @access public
*/
public function __construct()
{
$this->log = Log::factory('file',FR_LOG_FILE);
$this->me = new ReflectionClass($this);
}

/**
* setFrom
*
* @author Joe Stump
* @access public
* @param mixed $data Array of variables to assign to instance
* @return void
*/
public function setFrom($data)
{
if (is_array($data) && count($data)) {
$valid = get_class_vars(get_class($this));
foreach ($valid as $var => $val) {
if (isset($data[$var])) {
$this->$var = $data[$var];
}
}
}
}

/**
* toArray
*
* @author Joe Stump
* @access public
* @return mixed Array of member variables keyed by variable name
*/
public function toArray()
{
$defaults = $this->me->getDefaultProperties();
$return = array();
foreach ($defaults as $var => $val) {
if ($this->$var instanceof FR_Object) {
$return[$var] = $this->$var->toArray();
} else {
$return[$var] = $this->$var;
}
}

return $return;
}

/**
* __destruct
*
* @author Joe Stump
* @access public
* @return void
*/
public function __destruct()
{
if ($this->log instanceof Log) {
$this->log->close();
}
}
}

?>


Auth.php

This is the base class for authentication. It extends from the FR_Module class from Module.php. Its major function is to define how a basic authentication class should behave.

An alternate approach is to define this as a variable in the module and then have the controller create the authentication module through a factory pattern. However, this way works too (and is simpler to explain).

Child classes should override the authenticate() method. The controller will use this method when determining if a user has access to the given module. For instance, the FR_Auth_No class simply returns true, which allows you to create modules that require no authentication.




Module.php

This is the heart of all of the modules. It extends the FR_Object_DB class and provides all of its children with database access and an open log file.

Additionally, it defines the default presentation layer, the default template file for the module, default page template file, and a few other variables that the controller and presentation layer use.

The class also provides the basic structure of what each module must possess as far as functions. The function set() abstracts the method of setting data into a centralized place, which the getData() function then hands off to the presentation layer for rendering.



* @var string $presenter
* @see FR_Presenter, FR_Presenter_common, FR_Presenter_smarty
*/
public $presenter = 'smarty';

/**
* $data
*
* Data set by the module that will eventually be passed to the view.
*
* @author Joe Stump
* @var mixed $data Module data
* @see FR_Module::set(), FR_Module::getData()
*/
protected $data = array();

/**
* $name
*
* @author Joe Stump
* @var string $name Name of module class
*/
public $name;

/**
* $tplFile
*
* @author Joe Stump
* @var string $tplFile Name of template file
* @see FR_Presenter_smarty
*/
public $tplFile;

/**
* $moduleName
*
* @author Joe Stump
* @var string $moduleName Name of requested module
* @see FR_Presenter_smarty
*/
public $moduleName = null;

/**
* $pageTemplateFile
*
* @author Joe Stump
* @var string $pageTemplateFile Name of outer page template
*/
public $pageTemplateFile = null;
// }}}
// {{{ __construct()
/**
* __construct
*
* @author Joe Stump
*/
public function __construct()
{
parent::__construct();
$this->name = $this->me->getName();
$this->tplFile = $this->name.'.tpl';
}
// }}}
// {{{ __default()
/**
* __default
*
* This function is ran by the controller if an event is not specified
* in the user's request.
*
* @author Joe Stump
*/
abstract public function __default();
// }}}
// {{{ set($var,$val)
/**
* set
*
* Set data for your module. This will eventually be passed toe the
* presenter class via FR_Module::getData().
*
* @author Joe Stump
* @param string $var Name of variable
* @param mixed $val Value of variable
* @return void
* @see FR_Module::getData()
*/
protected function set($var,$val) {
$this->data[$var] = $val;
}
// }}}
// {{{ getData()
/**
* getData
*
* Returns module's data.
*
* @author Joe Stump
* @return mixed
* @see FR_Presenter_common
*/
public function getData()
{
return $this->data;
}
// }}}
// {{{ isValid($module)
/**
* isValid
*
* Determines if $module is a valid framework module. This is used by
* the controller to determine if the module fits into our framework's
* mold. If it extends from both FR_Module and FR_Auth then it should be
* good to run.
*
* @author Joe Stump
* @static
* @param mixed $module
* @return bool
*/
public static function isValid($module)
{
return (is_object($module) &&
$module instanceof FR_Module &&
$module instanceof FR_Auth);
}
// }}}
// {{{ __destruct()
public function __destruct()
{
parent::__destruct();
}
// }}}
}

?>


Presenter.php

This is the foundation for the presentation layer. It uses the factory design pattern to create the presentation layer. FR_Module::$presenter defines which presentation layer to use, which the controller will then create via the factory method. Once the controller has a valid presentation layer, the only thing left to do is to run the common display() function, which presentation classes inherit from FR_Presenter_common.



* @access public
* @param string $type Presentation type (our view)
* @param mixed $module Our module, which the presenter will display
* @return mixed PEAR_Error on failure or a valid presenter
* @static
*/
static public function factory($type,FR_Module $module)
{
$file = FR_BASE_PATH.'/includes/Presenter/'.$type.'.php';
if (include($file)) {
$class = 'FR_Presenter_'.$type;
if (class_exists($class)) {
$presenter = new $class($module);
if ($presenter instanceof FR_Presenter_common) {
return $presenter;
}

return PEAR::raiseError('Invalid presentation class: '.$type);
}

return PEAR::raiseError('Presentation class not found: '.$type);
}

return PEAR::raiseError('Presenter file not found: '.$type);
}
// }}}
}

?>
This part of the topic is taken from http://oreilly.com/php/archive/mvc-intro.html



TO BE ADDED MORE......

Saturday, September 26, 2009

Steps for URL re-write

Step 1: you have to create a .htaccess file.

Step 2: Edit the htaccess file. In order for apache to be able to rewrite urls you have to switch on the so called Rewrite Engine. This is done by inserting RewriteEngine on into the htaccess file.

Step 3: Creating Rewrite Rules. You can create as many rules as you wish. assuming you have a page called http://www.mywebsite.com/myprofile.php and you want to be able to call it via http://www.mywebsite.com/myprofile you would have to insert the following line


RewriteRule ^myprofile $ myprofile.php

You will still be able to call the page http://www.mywebsite.com/myprofile.php. Once you have tested to see if rewrite works you can change all the links in your web pages from myprofile.php to myprofile.

Now lets assume you have a blog and you have a page where you display articles from a specific category and your url looks like http://www.mywebsite.com/category.php?id=81. You could rewrite it to http://www.mywebsite.com/category/81. Now you don't want to have to do this for all categories because if you add a new category you would have to write a new line.
RewriteRule ^category/([0-9]+)$ category.php?id=$1

What if you have multiple pages of articles within categories?

http://www.mywebsite.com/category.php?id=81&page=19
RewriteRule ^category/([0-9]+)/([0-9]+)$ category.php?id=$1&page=$2

If you are upgrading your website and you want to ensure that all the old links will still be working you can use the mod_rewrite module as well. All you need to do is simply creating a rule and indicate that the page has permanently moved.

Example:
RewriteRule ^oldpage.html$ newpage.html [R=301]
Conditions

You can also create a set of conditions. In the example below it is assumed that the subdomain beta is pointed to the same place as the main website.

The first line is the condition and checks what the host or domain name is. The second line will only be run if the first line it valid.
RewriteCond %{HTTP_HOST} ^www.domain.com$
RewriteRule ^category/([0-9]+)$ category.php?id=$1
RewriteCond %{HTTP_HOST} ^beta.domain.com$
RewriteRule ^category/([0-9]+)$ beta_category.php?id=$1

Other variables that can be used in the condition are

HTTP_REFERER

REQUEST_URI

REQUEST_FILENAME

REMOTE_HOST

REQUEST_METHOD

HTTP_USER_AGENT

If is also possible to combine multiple conditions
RewriteCond %{HTTP_HOST} ^www.domain.com$ [OR]
RewriteCond %{HTTP_HOST} ^beta.domain.com$
RewriteRule ^category/([0-9]+)$ category.php?id=$1

The above rule would only be exectuted if the domain is either www.domain.com or beta.domain.com. If the condition is not met the rule will be ignored.

Thursday, September 24, 2009

URL Re-write - Hide .php extension with url rewriting using .htaccess

what is the benefits of rewriting URL?
When a search engine visits the dynamic url like product.php?id=5 it does not give much importance to that URL as search engine sees “?” sign treat it as a url which keeps on changing. so we’re converting the dynamic URL like the product.php?id=5 to static url format like product-5.html. We’ll rewrite the url in such a way that in browser’s address bar it will display as a product-5.html but it actually calls the file product.php?id=5. So that why these kind of URL also named as SEO friendly URL.

Hiding PHP file extension

Do you want to hide your web site’s server script identity ? If you don’t want to reveal the programming language ( server side script ) of your website to visitors of website so that any hacker or spammer will not be able to intrude or inject any code in your website.

Here is a small technique for you, you can use .html or .asp file to work as a php file i.e. use .asp or .html extension instead of .php. You just need to create a .htaccess file and put the following code in the .htaccess file. Remember that the .htaccess file should be placed in the root folder of your website.

# Make PHP code look like asp or perl code
AddType application/x-httpd-php .asp .pl

if you place the the above code in the .htaccess file then you can use contact.asp as the name of the file. Now a visitor thought that it is a ASP file but this file contains the codes of PHP.

You can put the following code in .htaccess file to work .htm or .html file as PHP file.

# Make all PHP code look like HTML
AddType application/x-httpd-php .htm .html

But there was one flaw in that technique you have had to change the file extension explicitly but in this post I’m going to show you how to rewrite the URL instead of renaming the file extension Using this technique you will see product.html in the address bar of the browser but the actual file name remains product.php and you don’t need to rename the file extension. Furthermore you can rewrite the URL like product.php?id=5 to product-5.html.

what is required for URL rewriting ??

To rewrite the URL you must have the mod_rewrite module must be loaded in apache server. And furthermore, FollowSymLinks options also need to be enabled otherwise you may encounter 500 Internal Sever Error. If you don’t know much about mod_rewrite module then please check this post to know how to check and enable mod_rewrite module in apache?
Examples of url rewriting for seo friendly URL

For rewriting the URL, you should create a .htaccess file in the root folder of your web directory. And have to put the following codes as your requirement.

Options +FollowSymlinks
RewriteEngine on
RewriteRule ^(.*)\.htm$ $1.php [nc]

The following example will rewrite the test.php to test.html i.e when a URL like http://localhost/test.htm is called in address bar it calls the file test.php. As you can see the regular expression in first part of the RewriteRule command and $1 represents the first regular expression of the part of the RewriteRule and [nc] means not case sensitive.

Options +FollowSymlinks
RewriteEngine on
RewriteRule ^product-([0-9]+)\.html$ products.php?id=$1

The following example will rewrite the product.php?id=5 to porduct-5.html i.e when a URL like http://localhost/product-5.html calls product.php?id=5 automatically.


Applications Must Be Safe


A user must not be able to harm your site in any way by modifying a URL that points to your applications. In order to ensure your site's safe, check all the GET variables coming from your visitors (I think it's trivial to mention that the POST variables are a must to examine).

For example, imagine we have a simple script that shows all the products in a category.o Generally, it's called like this:

myapp.php?target=showproducts&categoryid=123

But what will this application do if ScriptKiddie(tm) comes and types this in his browser:

myapp.php?target=showproducts&categoryid=youarebeinghacked

Well, many of the sites I've seen will drop some error message complaining about use of the wrong SQL query, invalid MySQL resource ID, and so on... These sites are not secure. And can anyone guarantee that a site-to-be-finished-yesterday will have all the parameter verifications --even in a programmer group having only 2 or 3 people?

Applications Must Be Search-Engine Friendly


It's not generally known, but many of the search engines will not index your site in depth if it contains links to dynamic pages like the one mentioned above. They simply take the "name" part of the URL (that's everything before the question mark, which contains the parameters that are needed for most of the scripts to run correctly), and then try to fetch the contents of the page. To make it clear, here are some links from our fictitious page:

myapp.php?target=showproducts&categoryid=123
myapp.php?target=showproducts&categoryid=124
myapp.php?target=showproducts&categoryid=125

Unfortunately, there's a big chance that some of the search engines will try to download the following page:

myapp.php

In most cases calling a script like this causes an error - but if not, I'm sure it will not show the proper contents the link was pointing to. Just try this search at google.com:
""you have an error in your sql syntax" .php -forum"

There are both huge bugs and security in the scripts listed -- again, these scripts are not search-engine friendly.

Applications must be user-friendly

If you application uses links like:

http://www.downloadsite.com?category=34769845698752354
1and1.com

then most of your visitors will find it difficult to get back to their favourite category (eg. Nettools/Messengers) every time they start from the main page of your site. Instead, they'd like to see URLs like this:

http://www.downloadsite.com/Nettools/Messengers

It's even easier for the user to find (pick) the URL from the browsers' drop-down list as they type into the Location field (though of course this only works if the user has visited that previously).

And what about you?

Now you have everything you need to answer the following questions:

* Is your site really safe enough?
* Can you protect your site from hackers?
* Are your Websites search-engine compatible?
* Are the URLs on your site 'user friendly' - are they easy to remember? ...and would you like it to be? (everyone who answered 'yes' to all 4 questions: have a beer!)

An elegant solution

Okay, okay, I think you want to know the solution. Well, let's get started. You'll need:

* everyone's favourite Apache Webserver installed (v1.2 or later)
* optionally, your favourite CGI scripts configured for Apache. Yes, I've said optionally, since what we're going to do will happen right inside Apache and not PHP, or Perl, etc.
* since (nearly) everything in Apache is controlled through its configuration files (httpd.conf, .htaccess, etc.), being familiar with these files might help you. You'll also need to have write access to this file, and access to restart the Apache. I'd strongly recommend you do everything on a private testserver first, rather than on your own, or your company's, production server!

Most of you will have read and/or heard about mod_rewrite -- yes, it's an Apache module, and it's even installed by default! Go and check your modules directory (note that under *nix operating systems there's a chance that your Apache was compiled with missing mod_rewrite, in which case, consult your sysadmin).

We're going use this tiny module to achieve everything mentioned above. To use this module, first we have to enable it, since it's initially disabled in the configuration file. Open the httpd.conf file and uncomment the following lines (remove the trailing #s):

#LoadModule rewrite_module modules/mod_rewrite.so
#AddModule mod_rewrite.c

The first line tells Apache to load the mod_rewrite module, while the second one enables the use of it. After you restart Apache, mod_rewrite should be enabled, but not yet running.


What is the mod_rewrite Solution, Exactly?

But what does it exactly do? Hey! Here comes the whole point of this article!

mod_rewrite catches URLs that meet specific conditions, and rewrites them as it was told to.

For example, you can have a non-existing

http://www.mysite.com/anything

URL that is rewritten to:

http://www.mysite.com/deep/stuff/very_complicated_url?text=

having_lots_of_extra_characters
1and1.com

Did you expect something more? Be patient...


RewriteEngine on
RewriteRule ^/shortcut$ /complicated/and/way/too/long/url/here


Of course this, too, should go into the httpd.conf file again, (you can even put it into a virtualhost context).

After you restart Apache (you'll get used to it soon!) you can type this into your browser:

http://localhost/shortcut

If there's a directory structure /complicated/and/way/too/long/url/here existing in your document root, you're going to be "redirected" there, where you'll see the contents of this directory (eg, the directory listing, index.html, whatever there is).

To understand mod_rewrite better, it's important to know that this is not true redirection. "Classic" redirection is done with the Location: header of the HTTP protocol, and tells the browser itself to go to another URL. There are numerous ways to do this, for example, in PHP you could write:



This code shows the same page by sending a HTTP header back to the browser. That header tells the browser to move to another URL location instantly. But, what mod_rewrite does is totally different: it 'tricks' the browser, and serves the page as if it were really there - that's why this is an URL rewriter and not a simple redirector (you can even verify the HTTP headers sent and received to understand the difference).

But it's not just shortening paths that makes mod_rewrite the "Swiss Army Knife of URL manipulation"...
Rules

You've just seen how to specify a really simple RewriteRule. Now let's take a closer look...

RewriteRule Pattern Substitution [Flag(s)]

RewriteRule is a simple instruction that tells mod_rewrite what to do. The magic is that you can use regular expressions in the Pattern and references in the Substitution strings. What do you think of the following rule?

RewriteRule /products/([0-9]+) /siteengine/products.php?id=$1

Now you can use the following syntax in your URLs:

http://localhost/products/123

After restarting Apache, you'll find this is translated as:

http://localhost/siteengine/products.php?id=123

If you use only 'fancy' URLs in your scripts, there will be no way for your visitor to find out where your script resides (/siteengine in the example), what its name is (products.php), or what the name of the parameter to pass (productid) is! Do you like it? We've just completed two of our tasks, look!

* Search-engine compatibility: there are no fancy characters in the URL, so the engines will explore your whole site
* Security: ScriptKiddie(tm)-modified URLs will cause no error, as they're verified with the regular expression first to be a number - URLs with no proper syntax can't even reach the script itself.

Of course, you can create more complex RewriteRules. For example, here's a set of rules I'm using on a site:

RewriteRule ^/products$ /content.php
RewriteRule ^/products/([0-9]+)$ /content.php?id=$1
RewriteRule
^/products/([0-9]+),([ad]*),([0-9]{0,3}),([0-9]*),([0-9]*$)
/marso/content.php?id=$1&sort=$2&order=$3&start=$4

Thanks to these rules I can use the followings links in the application:

* Show an opening page that contains product categories: http://somesite.hu/products
* Product listing, categoryid is 123, page 1 (as default), default order: http://somesite.hu/products/123 http://somesite.hu/products/123,,,,
* Product listing, categoryid is 123, page 2, descending order by third field (d for descending, 3 for third field): http://somesite.hu/products/123,d,3,2

This is also an example of the use of multiple RewriteRules. When there's a RegExp match, the proper substitution occurs, mod_rewrite stops running and Apache serves the page with the substituted URL. Should there be no match (after processing all the rules), a usual 404 page comes up. And of course you can also define one or more rules (eg. ^.*$ as last pattern) to specify which script(s) to run depending on the mistaken URL.

The third, optional part of RewriteRule is:

RewriteRule Pattern Substitution Flag(s)

With flags, you can send specific headers to the browser when the URL matches the pattern, such as:

* 'forbidden' or 'f' for 403 forbidden,
* 'gone' or 'g' for 410 gone,
* you may also force redirection, or force a MIME-type.

You can even use the:

* 'nocase' or 'NC' flag to make the pattern case-insensitive
* 'next'/N' to loop back to the first rule ('next round' -- though this may result in an endless loop, be careful with it!)
* 'skip=N'/'S=N' to skip the following N rules

...and so on.

I hope you feel like I felt while playing around with this module for the first time!

Conditions

But that's not all! Though RewriteRule gives you an opportunity to have professional URL rewriting, you can make it more customized using conditions.

The format of the conditions is simple:
The CSS Anthology

RewriteCond Something_to_test Condition

Any RewriteCond condition affects the behaviour of the following RewriteRule, which is a little confusing, as RewriteCond won't be evaluated until the following RewriteRule pattern matches the current URL.

It works like this: mod_rewrite takes all the RewriteRules and starts matching the current URL against each RewriteRule pattern. If there's a RewriteRule pattern that matches the URL, mod_rewrite checks if there are existing conditions for this RewriteRule, and if the first one returns true. If it does, the proper substitution will occur, but if not, mod_rewrite looks for remaining conditions. When there are no more conditions, the subsequent RewriteRule is checked.

This way you can customize URL rewriting using conditions based on practically everything that's known during a HTTP transfer in Apache -- and a lot more! Basically you can use all of these variables in the Something_to_test string:

* HTTP header variables: HTTP_USER_AGENT, HTTP_REFERER, HTTP_COOKIE, HTTP_FORWARDED, HTTP_HOST, HTTP_PROXY_CONNECTION, HTTP_ACCEPT
* Connection & request variables: REMOTE_ADDR, REMOTE_HOST, REMOTE_USER, REMOTE_IDENT, REQUEST_METHOD, SCRIPT_FILENAME, PATH_INFO, QUERY_STRING, AUTH_TYPE
* Server internal variables: DOCUMENT_ROOT, SERVER_ADMIN, SERVER_NAME, SERVER_ADDR, SERVER_PORT, SERVER_PROTOCOL, SERVER_SOFTWARE
* System variables: TIME_YEAR, TIME_MON, TIME_DAY, TIME_HOUR, TIME_MIN, TIME_SEC, TIME_WDAY, TIME
* mod_rewrite special values: API_VERSION, THE_REQUEST, REQUEST_URI, REQUEST_FILENAME, IS_SUBREQ

The condition can be a simple string or a standard regular expression, with additions like:

* <, >, = simple comparison operators
* -f if Something_to_test is a file
* -d if Something_to_test is a directory

As you can see, these are more than enough to specify a condition like this one (taken from the mod_rewrite manual):

RewriteCond %{HTTP_USER_AGENT} ^Mozilla.*
RewriteRule ^/$ /homepage.max.html [L]

RewriteCond %{HTTP_USER_AGENT} ^Lynx.*
RewriteRule ^/$ /homepage.min.html [L]

RewriteRule ^/$ /homepage.std.html [L]

When a browser requests the index page, 3 things can happen:

* browser with a Mozilla engine the browser will be served homepage.max.html
* using Lynx (character-based browser) the homepage.min.html will open
* if the browser's name doesn't contain 'Mozilla' nor 'Lynx', the standard homepage.std.html file will be sent

You can even disable users from accessing images from outside your server:

RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://localhost/.*$ [OR,NC]
RewriteCond %{HTTP_REFERER} !^http://mysite.com/.*$ [OR,NC]
RewriteCond %{HTTP_REFERER} !^http://www.mysite.com/.*$ [OR,NC]
RewriteRule .*\.(gif|GIF|jpg|JPG)$ http://mysite/images/bad.gif [L,R]

But of course, there are endless possibilities, including IP- or time-dependant conditions, etc.


For Advanced Users

I mentioned user-friendliness in the introduction, and haven't dealt with it. First, let's imagine we're having a huge download site that has the downloadable software separated into categories, each with a unique id (which is used in the SQL SELECTs). We use links like open.php?categoryid=23487678 to display the contents of a category.

To ensure that our URLs were easily memorized (eg. http://www.downloadsite.com/Nettools/Messengers) we could use:
1and1.com

RewriteRule ^/NetTools$ /test.php?target=3
RewriteRule ^/NetTools/Messengers$ /test.php?target=34

assuming the ID is 3 for the NetTools category and 34 for Messengers subcategory.

But our site is huge, as I've mentioned - who wants to hunt down all the IDs from the database, and then edit the config file by hand? No-one! Instead, we can use the mapping feature of mod_rewrite. Map allows us to provide a replacement-table - stored in a single text file -- within a hash file (for fast lookups), or even served through an external program!

For better performance I'd generate a single text file using PHP, which contains the following:

NetTools 3
NetTools/Messengers 34
.
.
.
and so on.

The httpd.conf file would contain:

RewriteMap categories txt:/path/to/file/categoryids.txt
RewriteRule ^(.*)$ open.php?categoryid=${categories:$1|0}

These lines tell mod_rewrite to read the categoryids.txt file upon Apache startup, and provide the ID for the URL for open.php. The |0 means that categoryid will be 0 if there's no matching key in the textfile.

You can also choose to serve the IDs on-the-fly via a script or other executable code. The program is started by Apache on server startup, and runs until shutdown. The program must have buffered I/O disabled, read from the stdin, and write results to stdout -- it's that simple!

With RewriteMap you can do a lot more, including:

* load balancing through servers (using rnd:),
* creation of a Webcluster that has an homogenous URL layout,
* redirection to mirror sites without modifying your Web application,
* denial of user access based on a hostlist,


and so on.
Tips, Tricks and Advice

1. Before using mod_rewrite in a production server, I'd recommend setting up a testserver (or playground, whatever you prefer to call it).

2. During development, you must avoid using 'old-fashioned' URLs in your application.

3. There might still be need to verify data passed through the URL (passing non-existing -- too large or small - IDs, for example, might be risky).

4. Writing 'intelligent' RewriteRules saved me coding time and helped me write simpler code. I'm using error_reporting(E_ALL); everywhere (and I recommend it!), but I find it boring to do the following for the ten thousandths time:

if (isset($_GET['id']) && (validNumber($_GET['id']))
if (isset($_GET['todo']) && ($_GET['todo']=='deleteitem'))

The following trick helped me to get rid of the extra isset() expression by providing all the needed parameters each time in the RewriteRules:

RewriteRule ^/products/[0-9]+$ products.php?id=$1&todo=

I know, I know it's not the answer to the meaning of life -- but it's hard to show how nice and clear a solution this might provide in such a short example.

Finally...

That's all for our 'brief' overview of mod_rewrite. After you've mastered the basics, you'll find you can easily create your own rules. If you like the idea of URL rewriting, may want to play with mod_rewrite - some ideas follow (note that the underlying PHP code is not important in this case):

http://www.mysite.com/1/2/3/content.html
=> 1_2_3_content.html
http://www.mysite.com/1/2/3/content.html
=> content.php ? category=1

http://www.mysite.com/1/2/3/
=> content.php ? category=1 & subcat1 = 2 & subcat2 = 3

http://www.mysite.com/1/2/3/details
=> content.php ? category=1 & subcat1 = 2 & subcat2 = 3
http://www.mysite.com/bookshop/browse/bytitle
=> library.php ? target=listbooks & order = title
http://www.mysite.com/bookshop/browse/byauthor
=> library.php ? target=listbooks & order = author

http://www.mysite.com/bookshop/product/123
=> library.php ? target=showproduct & itemid=123

http://www.mysite.com/bookshop/helpdesk/2
=> library.php ? target=showhelp & page=2
http://www.mysite.com/bookshop/registration
=> library.php ? target=reg

Thursday, September 17, 2009

Difference HTTP and HTTPS

The main difference between http:// and https:// is, It's all about keeping you secure

HTTP stands for HyperText Transport Protocol, which is just a fancy way of saying it's a protocol (a language, in a manner of speaking) for information to be passed back and forth between web servers and clients.

The important thing is the letter S which makes the difference between HTTP and HTTPS.

The S (big surprise) stands for "Secure".
If you visit a website or webpage, and look at the address in the web browser, it will likely begin with the following: http://.

This means that the website is talking to your browser using the regular 'unsecure' language.

In other words, it is possible for someone to "eavesdrop" on your computer's conversation with the website.

If you fill out a form on the website, someone might see the information you send to that site.

This is why you never ever ever enter your credit card number in an http website!

But if the web address begins with https://, that basically means your computer is talking to the website in a secure code that no one can eavesdrop on.

You understand why this is so important, right?

If a website ever asks you to enter your credit card information, you should automatically look to see if the web address begins with https://.

If it doesn't, there's no way you're going to enter sensitive information like a credit card number!

PHP code to "force" https by redirecting all normal http traffic to https.
function SSLon(){

if($_SERVER['HTTPS'] != 'on'){

$url = "https://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];

header('Location: '.$url); exit;

}

}//==== End -- Turn On HTTPS