Friday, December 31, 2010

Happy New Year

At the end of da year.
Thanx to those who hated me,
they made me a stronger person.

Thanx to those who loved me,
they made my heart bigger.

Thanx to those who were worried about me,
they let me know that they cared about me.

Thanx to those who left me,
they made me realize that nothing lasts forever.

Thanx to those who entered my life never left,
they made me know who i am.
Special thanks to all my friends,
who supp0rted me thr0ugh0ut da
year.. (:->At the end of da year.
Thanx to those who hated me,
they made me a stronger person.

Thanx to those who loved me,
they made my heart bigger.

Thanx to those who were worried about me,
they let me know that they cared about me.

Thanx to those who left me,
they made me realize that nothing lasts forever.

Thanx to those who entered my life never left,
they made me know who i am.
Special thanks to all my friends,
who supp0rted me thr0ugh0ut da
year.. (:->

Tuesday, December 28, 2010

What Is Domain Parking?

Domain Parking is a simple way to earn money from your domains' natural traffic. If you have registered domain names, but they are not currently being used, then domain parking is a great way to put those domains to work, earning you revenue. You can make money without even lifting a finger! The idle domain is used to display relevant advertisements -every time a consumer clicks on one of the advertisements, you earn money.

Monday, December 27, 2010

Magento Shopping Cart And Its Demands

Magento Shopping Cart is the ultimate online solution for online merchants for its dramatic features. On one side it has lots of features for online customers with an option to add or remove and on the other hand; its all available for a small amount of money. There are multi language options and currencies updates available to give customers more shopping options. All these features enable Magento to lead the others in the race and the customers have a healthy and fun giving online shopping experience. Though Magento is regarded as the future of the ecommerce business and has left lots of shopping carts solutions
behind, yet its not that simple as it seems. Its suggested by some professionals that a PHP programmer can help integrate shopping cart with Magento, but its not true since it requires more than that.

Its not more than an oversimplification that people regard Magento Shopping Cart as an open source based on PHP programming. The truth is Magento cart is based on Zend frame work that requires a collective knowledge of PHP and one or both object oriented programming languages
like C or C++. Its because of this confusion that people are crying for not proper integration with Magento. Programmers also create problems for not being able to integrate their clients shopping cart with Magento because they are not equipped with the required programming skills. As a result, they either stop working on their clients project when theyre gone just half of the way; or they stop replying their clients phone calls. Whatever the case is, the project doesnt complete and produces problems for clients.

Magneto Shopping Cart is a flexible solution with advance technology. Its called future of ecommerce, therefore, for smooth shopping cart integration;

Advantages Of Implementing Php Shopping Cart

The making of shopping cart software is amazingly easy and when done with accuracy it could translate in to an exceedingly successful and collectively accepted php shopping cart.

The information of the stocks are unsurprisingly stored in the database
and the only information obligatory from the enduring which would in turn require to be stored is none other than the id of each product that has been added to the php shopping cart.

The php shopping cart is reachable and there are a diversity of ways of accomplishment it - the most popular being the clicking on a link or by clicking on the 'add to cart' option on the product page.

In the occurrence of the php shopping cart being inwards at using the link on the product page - 'add to cart' - the requirement of the hour is unquestionably to update the products in the php shopping cart before the demonstration of an innovative product range.

It is not infrequent for the php shopping cart to have more than one of a kind of any meticulous product, which could be compiled, and it is not desirable to list the number of products of a scrupulous kind in the php shopping cart.

There is an accord between the links to 'delete' or 'add' a product to the php shopping cart. The customer also could have the alternative of updating the products in the php shopping cart via manually.

The php shopping cart is uncommonly unfilled and if it is a suitable message need to be flashed to the consequence. This is one feature of the php shopping cart, which can hardly be negotiated.

PHP Shopping Cart Software Integration

PHP ecommerce software integration is frequently something that is overlooked. People simply think that all shopping cart software is easily integrated into a design. However, many shopping carts are not designed in a way that makes it very easy at all, while others make it so easy that a novice programmer could do it without blinking an eye. You should definitely keep an eye out though when purchasing shopping cart software on how easy it will be to get it onto your website.

If you are truly concerned, I would start out by asking the developer to provide the documentation on how to integrate it. This will likely give you a good perspective on what to expect. If the developer will not give you access to that, this could be a red flag that perhaps there is not good documentation or that it could end up being far more difficult than one would hope for.

I have seen some shopping carts that it is just a matter of putting a single line of code into your website.

It will show up, look great, and you will never have a problem. Others will require that you manipulate every page of the shopping cart from beginning to end. You will need to build your website around the shopping cart, change button colors, alter the css file, and make other various HTML changes. These are a pain, and should be avoided when possible if they do not have the proper documentation. A good cart will make it easy to alter the size, structure, and layout of the shopping cart. They might even have different themes available that might help you to match your existing design. When all else fails and you have odd colors, you might even just have to change a little bit of CSS to really get it looking like you would want it to look.
It starts with good documentation though from the developer.

The importance of having an integrated online web cart often goes overlooked. I will even go on to say that it lacks professionalism when it is not done properly. Some companies feel that simply having their banner or logo on the page of the shopping cart is good enough. To be honest though, this is not the extent I consider integration to be. If the buttons and colors of the shopping cart do not match your website, then this is not true integration. This is just something that lacks professionalism in my opinion.

When people are in the ordering process, it is natural for people to frequently back out. They might just be checking the final price on one of your items. However, others will place something in their shopping cart and the ordering process gives them time to ponder. Do they really need the item? Is this the right company to buy from? Is this the cheapest available on the internet? These are all questions that will run through almost every buyers mind. Why do you want to give them a reason to doubt the professionalism of your company? This is something that will cross their mind if you have a poorly done job on integrating your shopping cart. You want to give them every reason to buy from you, not every reason to leave your site. In the end, with good integration you will find that you will be much more pleased with your conversion ratios when people visit your shopping cart if it is integrated properly and matches your website as closely as possible.

Choosing a PHP Shopping Cart

I could sit here and tell you everything that I look for a shopping cart. It would probably be a laundry list of things. However, that is for my own website, and may not fit yours. Since you are selling different items more than likely, you may have a demand for different things. This is why there are also so many shopping carts on the market. Several of them have good customer service, they all run well, but it's the little things that make their products unique. For this reason, several different shopping carts do sell well online because they are tailored towards different types of business needs. Below though, I have created a few things that should be true for all people who are looking for a good PHP shopping cart. I hope it helps you narrow down your choices.

Must Be Easy to Update Your Website

The most frustrating thing that can happen to anyone is to get their website up and running.


The developer helped you get the products added to the website, you go live, and a few weeks later you realize that there are some missing items. You should be aware of how to update your website, because it is only going to be a matter of time before you have a desire to do so. You will want to tweak wording and change things to hopefully help you improve your sales. Believe it or not, there are some shopping carts on the market that make this process near impossible for anyone who is not familiar with HTML or PHP Programming
. With that said, if I were you, I would make sure that before you purchase a PHP shopping cart
that you understand how to update your products and those types of things. It will save you a headache in the end.

Must Have Good Support from Developers

It is simply natural that anyone who purchases a script is going to have some questions.
They will want to know how to work a specific feature, how to set something up, or if there can be a feature added in a future release. Unfortunately, not all shopping carts are supported well. You essentially buy them "as is" and the minute you make your payment you are left on your own to figure things out or fix problems that might be in the script. The tip I offer to anyone who wants to see how good support is, is to simply ask a few questions to their customer service. Generally, in small businesses the people helping in sales / customer service will be the same people answer technical questions after you purchase the script. You will get a good idea of how helpful they will be, how clear their emails are, and how quick you might get a response. It is safe to say that no response probably means you will not get a response when you purchase the script and ask a question then either.

The Shopping Cart Meets But Does Not Surpass Your Needs

This is a tough line to follow because the first priority is to ensure that the script contains all of the features you might need. However, having one with too many can be almost an equally bad thing. Shopping carts with too many features can quickly become so complex that you will find it hard to manage your website. As well, those shopping carts that will virtually work for any website may have a very complex ordering form. This is not something you want if you really do not need it. The idea with ordering forms online is to have exactly what you need and nothing more. Therefore, even a script with too many features may need to be heavily modified just as if one you purchase that maybe does not have all the features you need. Therefore, both are going to cost you money. It is better to find a shopping cart as close to what you need as possible. It will save you money in the long run.

Php Shopping Cart:for Fastest Transactions

Selling products on the internet can be troublesome and excruciating if you do not have the right tools to do it. Just imagine a day where you falter with various orders from different eager buyers. Mixing up the information can cost profit and worse, a returning client to buy your products. Acquiring a system which can do the job efficiently will greatly benefit your business and can even cause your profit to increase. Just image a program that can sort out and categorize different products, automatically add up the costs of products purchased, and will even provide the buyer the transaction information that they need to complete orders. If you do not want to face these kinds of problems again, then purchase a php shopping cart software to simplify the business.

A program that can be easily placed in an e-commerce website without too much hassle, the Php shopping cart is a good investment to everyone engaging in online selling. Because of the fact that all transactions in e-commerce occurs online, it is important to have someone who will secure the transactions. A php shopping cart is comparable to a cashier in a supermarket. You are the owner of the supermarket and it is the lady cashier who does the job for you. You just have to sit back and monitor the rest of the transaction.

The beauty about implementing a php shopping cart is that it does not use any kind of database. It also allows buyers to choose from different payment modes. Providing your buyers all the means and ways to pay will increase the chances of selling your product. Just imagine if an eager buyer really wants to buy your product but your system cannot process credit cards
.
That's already a minus to your sales. With a php shopping cart integrated into the web store, you will have coupon support and system that analyzes and computes tax configurations in sales.

Installing this programming is also as easy as it can get. It only takes minutes to start using the software. With costs ranging from $20 to a few hundred dollars, one can definitely afford it. This program is specifically designed to provide e-commerce owners and even buyers the means to easily transact. It provides a total shopping solution for everyone. It is not difficult to use and can be understood by people of all ages. All one has to do is to choose a product, drag it down to the system, and the system will automatically add it for you. No more hassles, no more stressful computations and transactions, just plain buying and selling.

Save yourself the hassles of sorting those orders onto a piece of paper and spending too much time using a calculator. The faster the transaction is, the more sales a web store can do. The implication of having a php shopping cart in your own e-commerce website may not seem apparent at first, but sooner or later you will realize that faster transactions draw repeat customers.

Thursday, December 23, 2010

Five common PHP database problems

If only there were one way to use databases correctly ...
You can create database design, database access, and the PHP business logic code that sits on top of it in any number of ways, and you often end up getting it wrong. This article illustrates five common problems in database design, in the PHP code that accesses databases, and how to fix these problems when you see them.
Problem 1: Using MySQL directly
One common problem is older PHP code using the mysql_ functions to access the database directly. Listing 1 shows how to access the database directly.

Listing 1. Access/get.php
<?php
function get_user_id( $name )
{
  $db = mysql_connect( 'localhost', 'root', 'password' );
  mysql_select_db( 'users' );

  $res = mysql_query( "SELECT id FROM users WHERE login='".$name."'" );
  while( $row = mysql_fetch_array( $res ) ) { $id = $row[0]; }

  return $id;
}

var_dump( get_user_id( 'jack' ) );
?>

Notice the use of the mysql_connect function to access the database. Also notice the query in which we use string concatenation to add the $name parameter to the query.
This technique has two good alternatives: the PEAR DB module and the PHP Data Objects (PDO) classes. Both provide abstraction from the choice of a particular database. Therefore, your code can run without too much adjustment on IBM® DB2®, MySQL, PostgreSQL, or any other database you want to connect to.
The other value in using the abstraction layers of the PEAR DB module and PDO is that you can use the ? operator in your SQL statements. Doing so makes the SQL easier to maintain and secures your application from SQL injection attacks.
The alternative code using PEAR DB is shown below.

Listing 2. Access/get_good.php
<?php
require_once("DB.php");

function get_user_id( $name )
{
  $dsn = 'mysql://root:password@localhost/users';
  $db =& DB::Connect( $dsn, array() );
  if (PEAR::isError($db)) { die($db->getMessage()); }

  $res = $db->query( 'SELECT id FROM users WHERE login=?',
  array( $name ) );
  $id = null;
  while( $res->fetchInto( $row ) ) { $id = $row[0]; }

  return $id;
}

var_dump( get_user_id( 'jack' ) );
?>

Notice that all direct mentions of MySQL are gone except for the database connection string in $dsn. In addition, we use the $name variable in the SQL through the ? operator. Then, the data for the query is sent in through array at the end of the query() method.

Problem 2: Not using auto-increment functionality
Like most modern databases, MySQL has the ability to create auto-incrementing unique identifiers on a per-record basis. Despite that, we still see code that first runs a SELECT statement to find the maximum id, then adds one to that id, as well as a new record. Listing 3 shows a sample bad schema.

Listing 3. Badid.sql
DROP TABLE IF EXISTS users;
CREATE TABLE users (
  id MEDIUMINT,
  login TEXT,
  password TEXT
);

INSERT INTO users VALUES ( 1, 'jack', 'pass' );
INSERT INTO users VALUES ( 2, 'joan', 'pass' );
INSERT INTO users VALUES ( 1, 'jane', 'pass' );

The id field here is specified simply as an integer. So, although it should be unique, we can add any value we like, as shown in the INSERT statements that follow the CREATE statement. Listing 4 shows the PHP code that adds users into this type of schema.

Listing 4. Add_user.php
<?php
require_once("DB.php");

function add_user( $name, $pass )
{
  $rows = array();

  $dsn = 'mysql://root:password@localhost/bad_badid';
  $db =& DB::Connect( $dsn, array() );
  if (PEAR::isError($db)) { die($db->getMessage()); }

  $res = $db->query( "SELECT max(id) FROM users" );
  $id = null;
  while( $res->fetchInto( $row ) ) { $id = $row[0]; }

  $id += 1;

  $sth = $db->prepare( "INSERT INTO users VALUES(?,?,?)" );
  $db->execute( $sth, array( $id, $name, $pass ) );

  return $id;
}

$id = add_user( 'jerry', 'pass' );

var_dump( $id );
?>

The code in add_user.php first performs a query to find the maximum value of the id. Then the file runs an INSERT statement with the id value plus one. This code could fail in race conditions on servers with a heavy load. Plus, it's just inefficient.
So what's the alternative? Use the auto-increment feature in MySQL to create unique IDs for each insertion automatically. The updated schema is shown below.

Listing 5. Goodid.php
DROP TABLE IF EXISTS users;
CREATE TABLE users (
  id MEDIUMINT NOT NULL AUTO_INCREMENT,
  login TEXT NOT NULL,
  password TEXT NOT NULL,
  PRIMARY KEY( id )
);

INSERT INTO users VALUES ( null, 'jack', 'pass' );
INSERT INTO users VALUES ( null, 'joan', 'pass' );
INSERT INTO users VALUES ( null, 'jane', 'pass' );

We added the NOT NULL flag to indicate that the fields must not be null. We also added the AUTO_INCREMENT flag to indicate that the field is auto-incrementing, as well as the PRIMARY KEY flag to indicate which field is an id. These changes speed things up a bit. Listing 6 shows the updated PHP code that inserts users into the table.

Listing 6. Add_user_good.php
<?php
require_once("DB.php");

function add_user( $name, $pass )
{
  $dsn = 'mysql://root:password@localhost/good_genid';
  $db =& DB::Connect( $dsn, array() );
  if (PEAR::isError($db)) { die($db->getMessage()); }

  $sth = $db->prepare( "INSERT INTO users VALUES(null,?,?)" );
  $db->execute( $sth, array( $name, $pass ) );

  $res = $db->query( "SELECT last_insert_id()" );
  $id = null;
  while( $res->fetchInto( $row ) ) { $id = $row[0]; }

  return $id;
}

$id = add_user( 'jerry', 'pass' );

var_dump( $id );
?>

Instead of getting the maximum id value, I now just use the INSERT statement to insert the data, then use a SELECT statement to retrieve the id of the last inserted record. This code is a lot simpler and more efficient than the original version and its related schema.
An alternative to using MySQL's auto-increment functionality is to use the nextId() method in the PEAR DB system. In the case of MySQL, this creates a new sequence table and manages that using an elaborate locking mechanism. The advantage of using this method is that it will work across different database systems.
Either way, you should use a system that manages incrementing unique IDs for you and not rely on a system where you query first, then increment the value yourself, and add the record. The latter approach is susceptible to race conditions on high-volume sites.

Problem 3: Using multiple databases
Once in a while, we see an application in which each table is in a separate database. There are reasons for doing that in extraordinarily large databases, but for an average application, you don't need this level of segmentation. In addition, even though it's possible to perform relation queries across multiple databases, I strongly recommend against it. The syntax is more complex. Backup and restore is not easily managed. The syntax may or may not work between different database engines. And it's difficult to follow the relational structure when the tables are split over multiple databases.
So, what would multiple databases look like? To begin, you need some data. Listing 7 shows this data divided into four files.

Listing 7. The database files
Files.sql:
CREATE TABLE files (
  id MEDIUMINT,
  user_id MEDIUMINT,
  name TEXT,
  path TEXT
);

Load_files.sql:
INSERT INTO files VALUES ( 1, 1, 'test1.jpg', 'files/test1.jpg' );
INSERT INTO files VALUES ( 2, 1, 'test2.jpg', 'files/test2.jpg' );

Users.sql:
DROP TABLE IF EXISTS users;
CREATE TABLE users (
  id MEDIUMINT,
  login TEXT,
  password TEXT
);

Load_users.sql:
INSERT INTO users VALUES ( 1, 'jack', 'pass' );
INSERT INTO users VALUES ( 2, 'jon', 'pass' );

In the multiple-database version of these files, you would load SQL statements into one database, then load the users SQL statements into another database. The PHP code to query the database for the files associated with a particular user is shown below.

Listing 8. Getfiles.php
<?php
require_once("DB.php");

function get_user( $name )
{
  $dsn = 'mysql://root:password@localhost/bad_multi1';
  $db =& DB::Connect( $dsn, array() );
  if (PEAR::isError($db)) { die($db->getMessage()); }

  $res = $db->query( "SELECT id FROM users WHERE login=?",
  array( $name ) );
  $uid = null;
  while( $res->fetchInto( $row ) ) { $uid = $row[0]; }

  return $uid;
}

function get_files( $name )
{
  $uid = get_user( $name );

  $rows = array();

  $dsn = 'mysql://root:password@localhost/bad_multi2';
  $db =& DB::Connect( $dsn, array() );
  if (PEAR::isError($db)) { die($db->getMessage()); }

  $res = $db->query( "SELECT * FROM files WHERE user_id=?",
  array( $uid ) );
  while( $res->fetchInto( $row ) ) { $rows[] = $row; }

  return $rows;
}

$files = get_files( 'jack' );

var_dump( $files );
?>

The get_user function connects to the database that contains the users table and retrieves the ID for a given user. The get_files function connects to the files table and retrieves the file rows associated with the given user.
A better way to do all this is to load the data into one database, then perform a query, such as that shown below.

Listing 9. Getfiles_good.php
<?php
require_once("DB.php");

function get_files( $name )
{
  $rows = array();

  $dsn = 'mysql://root:password@localhost/good_multi';
  $db =& DB::Connect( $dsn, array() );
  if (PEAR::isError($db)) { die($db->getMessage()); }

  $res = $db->query(
  "SELECT files.* FROM users, files WHERE
  users.login=? AND users.id=files.user_id",
  array( $name ) );
  while( $res->fetchInto( $row ) ) { $rows[] = $row; }

  return $rows;
}

$files = get_files( 'jack' );

var_dump( $files );
?>

This code is not only shorter but it's also easier to understand and more efficient. Instead of performing two queries, we're performing one.
While this problem sounds a bit far-fetched, we've seen it in practice enough times to know that all tables should be in the same database unless there's a pressing reason otherwise.

Problem 4: Not using relations
Relational databases aren't like programming languages. They don't have array types. Instead, they use relations among tables to create a one-to-many structure between objects, which has the same effect as an array. One problem I've seen with applications is when engineers attempt to use a database as though it were a programming language, creating arrays by using text strings with comma-separated identifiers. Look at the schema below.

Listing 10. Bad.sql
DROP TABLE IF EXISTS files;
CREATE TABLE files (
  id MEDIUMINT,
  name TEXT,
  path TEXT
);

DROP TABLE IF EXISTS users;
CREATE TABLE users (
  id MEDIUMINT,
  login TEXT,
  password TEXT,
  files TEXT
);

INSERT INTO files VALUES ( 1, 'test1.jpg', 'media/test1.jpg' );
INSERT INTO files VALUES ( 2, 'test1.jpg', 'media/test1.jpg' );
INSERT INTO users VALUES ( 1, 'jack', 'pass', '1,2' );

One user in the system can have multiple files. In a programming language, you would use an array to represent the files associated with a user. In this example, the programmer chose to create a files field containing a list of file ids separated by commas. To get a list of all the files for a particular user, the programmer must first read the row from the users table, then parse the file's text and run an individual SELECT statement for each file. This code is shown below.

Listing 11. Get.php
<?php
require_once("DB.php");

function get_files( $name )
{
  $dsn = 'mysql://root:password@localhost/bad_norel';
  $db =& DB::Connect( $dsn, array() );
  if (PEAR::isError($db)) { die($db->getMessage()); }

  $res = $db->query( "SELECT files FROM users WHERE login=?",
  array( $name ) );
  $files = null;
  while( $res->fetchInto( $row ) ) { $files = $row[0]; }

  $rows = array();

  foreach( split( ',',$files ) as $file )
  {
    $res = $db->query( "SELECT * FROM files WHERE id=?",
      array( $file ) );
    while( $res->fetchInto( $row ) ) { $rows[] = $row; }
  }

  return $rows;
}

$files = get_files( 'jack' );

var_dump( $files );
?>

This technique is slow, difficult to maintain, and doesn't make good use of the database. The only solution is to re-architect the schema to turn it back into a traditional relational form, as shown below.

Listing 12. Good.sql
DROP TABLE IF EXISTS files;
CREATE TABLE files (
  id MEDIUMINT,
  user_id MEDIUMINT,
  name TEXT,
  path TEXT
);

DROP TABLE IF EXISTS users;
CREATE TABLE users (
  id MEDIUMINT,
  login TEXT,
  password TEXT
);

INSERT INTO users VALUES ( 1, 'jack', 'pass' );
INSERT INTO files VALUES ( 1, 1, 'test1.jpg', 'media/test1.jpg' );
INSERT INTO files VALUES ( 2, 1, 'test1.jpg', 'media/test1.jpg' );

Here, each file is related to the user through the user_id function in the file table. This probably seems backwards to anyone looking at this as an array. Certainly, arrays don't reference their containing objects -- in fact, just the opposite. But in a relational database, this is how things work and why queries are so much faster and easier. Listing 13 shows the corresponding PHP code.

Listing 13. Get_good.php
<?php
require_once("DB.php");

function get_files( $name )
{
  $dsn = 'mysql://root:password@localhost/good_rel';
  $db =& DB::Connect( $dsn, array() );
  if (PEAR::isError($db)) { die($db->getMessage()); }

  $rows = array();
  $res = $db->query(
    "SELECT files.* FROM users,files WHERE users.login=?
      AND users.id=files.user_id",
        array( $name ) );
  while( $res->fetchInto( $row ) ) { $rows[] = $row; }

  return $rows;
}

$files = get_files( 'jack' );

var_dump( $files );
?>

Here, we make one query to the database to get all the rows. The code isn't complex, and it uses the database as it was intended.

Problem 5: The n+1 pattern
I can't tell you how many times we've seen large applications in which the code first retrieves a list of entities -- say, customers -- then comes back and retrieves them one by one to get the details for each entity. We call it the n+1 pattern because that's how many queries will be performed -- one query to retrieve the list of all the entities, then one query for each of the n entities. This isn't a problem when n=10, but what about when n=100 or n=1000? Then the inefficiency really kicks in. Listing 14 shows an example of such a schema.

Listing 14. Schema.sql
DROP TABLE IF EXISTS authors;
CREATE TABLE authors (
  id MEDIUMINT NOT NULL AUTO_INCREMENT,
  name TEXT NOT NULL,
  PRIMARY KEY ( id )
);

DROP TABLE IF EXISTS books;
CREATE TABLE books (
  id MEDIUMINT NOT NULL AUTO_INCREMENT,
  author_id MEDIUMINT NOT NULL,
  name TEXT NOT NULL,
  PRIMARY KEY ( id )
);

INSERT INTO authors VALUES ( null, 'Jack Herrington' );
INSERT INTO authors VALUES ( null, 'Dave Thomas' );

INSERT INTO books VALUES ( null, 1, 'Code Generation in Action' );
INSERT INTO books VALUES ( null, 1, 'Podcasting Hacks' );
INSERT INTO books VALUES ( null, 1, 'PHP Hacks' );
INSERT INTO books VALUES ( null, 2, 'Pragmatic Programmer' );
INSERT INTO books VALUES ( null, 2, 'Ruby on Rails' );
INSERT INTO books VALUES ( null, 2, 'Programming Ruby' );

This schema is solid. There's nothing wrong here. The problem is in the code that accesses the database to find all the books for a given author, as shown below.

Listing 15. Get.php
<?php
require_once('DB.php');

$dsn = 'mysql://root:password@localhost/good_books';
$db =& DB::Connect( $dsn, array() );
if (PEAR::isError($db)) { die($db->getMessage()); }

function get_author_id( $name )
{
  global $db;

  $res = $db->query( "SELECT id FROM authors WHERE name=?",
    array( $name ) );
  $id = null;
  while( $res->fetchInto( $row ) ) { $id = $row[0]; }
  return $id;
}

function get_books( $id )
{
  global $db;

  $res = $db->query( "SELECT id FROM books WHERE author_id=?",
    array( $id ) );
  $ids = array();
  while( $res->fetchInto( $row ) ) { $ids []= $row[0]; }
  return $ids;
}

function get_book( $id )
{
  global $db;

  $res = $db->query( "SELECT * FROM books WHERE id=?", array( $id ) );
  while( $res->fetchInto( $row ) ) { return $row; }
  return null;
}

$author_id = get_author_id( 'Jack Herrington' );
$books = get_books( $author_id );
foreach( $books as $book_id ) {
  $book = get_book( $book_id );
  var_dump( $book );
}
?>

If you look at the code at the bottom, you are likely to think to yourself, "Hey, this is really clean." First, get the author id, then get a list of the books, then get information about each book. Sure, it's clean -- but is it efficient? No. Look at how many queries we had to perform to retrieve only the books by Jack Herrington. One to get an id, another to get the list of books, then one for each book. Five queries for three books!
The solution is to have one function that performs one bulk query, as shown below.

Listing 16. Get_good.php
<?php
require_once('DB.php');

$dsn = 'mysql://root:password@localhost/good_books';
$db =& DB::Connect( $dsn, array() );
if (PEAR::isError($db)) { die($db->getMessage()); }

function get_books( $name )
{
  global $db;

  $res = $db->query(
    "SELECT books.* FROM authors,books WHERE
      books.author_id=authors.id AND authors.name=?",
      array( $name ) );
  $rows = array();
  while( $res->fetchInto( $row ) ) { $rows []= $row; }
  return $rows;
}

$books = get_books( 'Jack Herrington' );
var_dump( $books );
?>

Now retrieving the list requires a fast, single query. It means that I will likely have to have several of these types of methods with different parameters, but there really is no choice. If you want to have a PHP application that scales, you must make efficient use of the database, and that means smarter queries.
The problem with this example is that it's a bit too clear-cut. Typically, these types of n+1 or n*n problems are much more subtle. And they only appear when the database administrator runs a query profiler on your system when it has performance problems.

Conclusion
Databases are powerful tools, and -- like all powerful tools -- they can be abused if you don't know how to use them properly. The trick behind identifying and solving these problems is to better understand the underlying technology. For too long, I've heard business logic coders lament that they don't want to have to understand the database or the SQL code. They wrap the database in objects and wonder why the performance is so poor.
They fail to realize that understanding the SQL is fundamental to turning the database from a difficult necessity into a powerful ally. If you use databases on a daily basis, but SQL isn't your strong suit, read The Art of SQL. It's a well-written, practical guide to getting the most out of a database.

Resources
Learn
  • The Art of SQL, by Stephane Faroult and Peter Robson, is a must-read book for programmers who use databases in their applications.
  • PHP.net is the starting point for all things PHP.
  • The PEAR DB documentation is an excellent resource.
  • The PDO Functions documentation can bring you up to speed on PHP Data Objects (PDO).
  • MySQL.org has excellent documentation with examples that show how to make better use of a database.
  • Visit IBM developerWorks' PHP project resources to learn more about PHP.
  • Stay current with developerWorks technical events and webcasts.
  • Check out upcoming conferences, trade shows, webcasts, and other Events around the world that are of interest to IBM open source developers.
  • Visit the developerWorks Open source zone for extensive how-to information, tools, and project updates to help you develop with open source technologies and use them with IBM's products.
  • To listen to interesting interviews and discussions for software developers, be sure to check out developerWorks podcasts.

Problems with PHP

PHP is a nice language for some tasks. Lots of good software uses it. No other language makes it so convenient to mix code and html, which is great for lone web developers who are also programmers. I've found it pretty useful for running my site, mainly because I can so easily put code in the middle of my content, and keep the overall per-page authoring overhead down. However, from a pure programming or information theory standpoint, it's got some serious problems:
  1. Namespaces don't exist at all. (this is similar to keeping all your files in one directory) There have been discussions about adding namespaces, but the proposed separator is \? because "there isn't any other character left"...
  2. Exceptions didn't exist until PHP5, and aren't implemented in a useful "deep" fashion.
  3. Built-in and library APIs are a disorganized mess.
    1. There are thousands of symbols in the PHP namespace. Cleaner languages only have a few dozen. "Everything is built in" just means it has way too many functions in its core, especially since many are minor variations of each other.
    2. No consistent naming convention is used. Some functions are verb_noun() and others are noun_verb(). Some are underscore_separated, while others are CamelCase or runtogether. Some are prefixed_byModuleName, and others use a module_suffix_scheme. Some use "to" and others use "2". And if you take a random set of ten library functions, chances are half a dozen different conventions will be included.
    3. PHP tends to use a lot of similar functions, instead of just one, powerful one. For example, PHP has sort(), arsort(), asort(), ksort(), natsort(), natcasesort(), rsort(), usort(), array_multisort(), and uksort(). For comparison, Python covers the functionality of all of those with list.sort().
    4. PHP includes lots of cruft or bloat. Do we really need a built-in str_rot13() function? Also, a lot of other built-ins are just trivial combinations of each other. Users don't really need case-insensitive variants of every string function, since there is already a strtolower().
    5. Many parts of PHP either deviate from standards, or otherwise don't do what users would expect.
      For example, exec() returns the last line of text output from a program. Why not return the program's return value, like every other language does? And further, when would it ever be useful to get only the last line of output?
      Another example: PHP uses non-standard date format characters.
  4. The language was generally thrown together without any coherent design, accreted in a messy and complex fashion.
  5. Functions...
    1. Functions cannot be redefined. If I want a set of includes which all use the same interface, I can only use one of them per page load -- there's no way to include a then call a.display() then include b and execute b.display(). I also cannot transparently wrap existing functions by renaming/replacing them.
    2. Functions cannot be nested. (actually, they can, but it has the same effect as if they were not. All functions are global, period.)
    3. Anonymous functions (lambda) don't exist. create_function() is not the same thing. Given two strings, it compiles them into code, binds the code to a new global function, and returns the new function name as a string.
      $foo = create_function('$x', 'echo "hello $x!";');
      $bar = "\0lambda_1";
      $bar("bar"); // sometimes prints "hello bar!", sometimes fails
      Note that the number after "\0lambda_" is not predictable. It starts at one and increments each time create_function is called. The number keeps incrementing as long as the web server process is running, and the counter is different in each server process. The memory for these new global functions is not freed, either, so you can easily run out of memory if you try to make lambdas in a loop.
    4. Functions are case insensitive.
  6. No "doc strings". Documentation must either be maintained separately from the code, or by (rather finicky) 3rd-party code-level documentation interpreters.
  7. The documentation...
    • ... is often incorrect or incomplete, and finding relevant information tends to require reading pages and pages of disorganized user-contributed notes (which are incorrect even more often) to find the details the documentation left out. Sometimes really important details are left out, such as "this function is deprecated -- use foo() instead".
    • ... is (as of PHP 5.1.2) not included with the source, nor typically installed along with the binary packages. Downloadable documentation is available, but does not match the docs on PHP.net. Specifically, it leaves out all the user-contributed notes, which are important because of reasons mentioned above.
    • ... is not built in. You can't just point an introspection tool at a PHP module and get usage information from it.
    These issues are important because it's not very feasible to use PHP without referring to the documentation frequently. There is very little internal consistency, and even less consistency between modules, so you'll probably spend a lot of time looking through the docs. Simply guessing how things work, based on conventions, usually doesn't work in PHP.
  8. Default to pass-by-value. (php5 now defaults to reference, for objects, though I'm not sure if it's "real" references or reference-by-name)
  9. Default error behavior is to send cryptic messages to the browser, mid-page, instead of logging a traceback for the developer to investigate.
  10. Many errors are silent.
    For example, accessing a nonexistent variable simply returns nothing. Whether this is a Bad Thing is debatable (I believe it's bad), but it can nevertheless interact badly with some other aspects of PHP -- such as the inconsistent case sensitivity (variables are sensitive, but functions are not):
    function FUNC() { return 3; }
    $VAR = 3;
    print func(); // produces "3"
    print $var; // produces nothing
  11. The combination list/hash "array" type causes problems by oversimplifying, often resulting in unexpected/unintuitive behavior.

    For example, PHP's weak type system interferes with hash keys:
    CodeResult
    $a = array("1" => "foo", 1 => "bar");
    echo $a[1], " ", $a["1"], "<br />\n";
    print_r($a);
    bar bar
    Array ( [1] => bar )
    After a little experimentation, I see that hash keys cannot be functions, classes, floats, or strings which look like integers. There are likely other invalid types as well. The only usable key types I've found so far are integers, and strings that do not parse as integers. (note that the parsing used here is different than the automatic str-to-int coercion used for the "+" operator) .
  12. Awkward / overlapping names can exist... foo and $foo are completely unrelated.
  13. Magic quotes (and related mis-features) make data input needlessly complex and error-prone. Instead of fixing vulnerabilities (such as malformed SQL query exploits), PHP tries to mangle your data to avoid triggering known flaws.
  14. The server-wide settings in PHP's configuration add a lot of complexity to app code, requiring all sorts of checks and workarounds. Instead of simplifying or shortening code (which the features are supposed to do), they actually make the code longer and more complex, since it must check to make sure each setting has the right value and handle situations when the expected values aren't there.
  15. PHP's database libraries are among the worst in any language. This is partially due to a lack of any consistent API for different databases, but mostly because the database interaction model in PHP is broken. The SQL injection issues in PHP deserve particular attention.

    How can it be that hard for web developers to check data before it is submitted? I wouldn't imagine trusting the data that an anonymous user can enter into my website.. so maybe I'm just trained to check data. Of course, I'm also glad I use MySQL with PHP where a simple mysql_real_escape_string can prevent any popular SQL Injection attempt.


    You're glad that you use pretty much the only langauge where this is not done automatically for you, but which instead forces you to use a function with a name like mysql_real_escape_string()? And that actually has a similarly-named function without the "_real_" that doesn't do the job right? Just kidding with that other one, here's the real one!
  16. The performance is crippled for commercial reasons (zend). Free optimizers are available, but aren't default or standard.
  17. Bad recursion support. Browse bug 1901 for an example and some details. BTW, ever heard of tail recursion? They might have mentioned it in the "Intro to Computer Science" course.
  18. Not thread safe.
  19. No unicode support. It's planned for PHP 6 but that could be a long time away.
  20. Vague and unintuitive automatic coercion; "==" is unpredictable, and "===" does not solve all the problems caused by "==". According to the manual, "==" returns true if the operands are equal, and "===" returns true if the operands are equal and of the same type. But that's not entirely true. For example:
    Two different strings are equal... sometimes.
    "1e1" == "10" => True
    "1e1.0" == "10" => False
    So, they're "equal and of the same type", right?
    "1e1" === "10" => False

    Unexpected results:
    "1 two 3" == 1 => True
    1.0 === 1 => False
    "11111111111111111117" == "11111111111111111118" => True

    Equality is (apparently) not transitive:
    $a = "foo"; $b = 0; $c = "bar";
    $a == $b => True
    $b == $c => True
    $a == $c => False
    Further, the coercion rules change depending on what you're doing. The behavior for "==" is not the same as used for "+" or for making hash keys.
    "22 cream puffs" == "22 bullfrogs" => False
    "12 zombies" + "10 young ladies" + "bourbon" == "22 cream puffs" => True
    Even though math asserts that, if A minus B equals zero, then A must equal B, PHP disagrees:
    "bourbon" - "scotch" => 0
    "bourbon" == "scotch" => False
  21. Variable scoping is strange, inconsistent, and inconvenient -- particularly the notably unusual "global" scope which gave rise to kludges like "superglobal" or "autoglobal" as workarounds.

    Further, variables cannot be scoped beyond global or function-local.
  22. The mixture of PHP code with HTML markup tends to make code difficult to read. Readability is important.
  23. Various "features" cause very unusual behavior and add complexity. This tends to cause bugs for programmers who expect it to behave like other languages.
    For example, this will fail sporadically: Open a file. Write to it. Close it. Open it. Read from the file. To make this actually work, the programmer must A) know it will fail, B) have some clue why it fails, and C) call the correct function (clearstatcache()) before re-opening the file. Note that the online docs aren't much help -- searching for "cache" takes the viewer to the docs for cosh(), but returns nothing at all related to files or caches.
  24. It provides no way to log errors verbosely, but only display critical errors to the user. Further, some of the most critical errors (such as running out of memory) give absolutely no response to the user -- not even a blank page.
  25. Poor security, and poor response to security issues. This is a large and detailed topic, but regardless of whether it's caused by inexperienced programmers or by PHP itself, the amount of PHP-related exploits is rather high. And according to a PHP security insider, the effort is futile.
  26. Its object model is (still) very lacking, compared to other systems.
  27. Most of the development since v3 seems to be devoted to damage control, and dealing with earlier mistakes... not a good sign.
  28. In general, has a tendency to create more problems than it solves.
I would not recommend using PHP, except as a template language for HTML. It's very good at that, so long as you keep the complexity of related code down. It's more powerful and (IMHO) more convenient than strict template languages like TAL, but cannot compete with "normal" scripting languages like Python, Perl, Ruby, and Lisp. PHP is a language optimized for a purpose, at the expense of all other uses. It's very good at what it was originally designed for, but has become stretched way too far since then.

This is waxing philosophical, but in my experience, PHP has an uncomfortably low ceiling. Programming isn't just about putting one instruction after another; it's about building abstractions to better represent and solve problems. The more complex the problem, the higher the level of abstraction needed to solve it cleanly. With PHP, I often hit my head on its low ceiling of abstraction, and it seems to require a great deal more effort and discipline (than in other languages) to avoid ducking down into the details of implementation when I should be focusing on the upper-level design.

Domain Name Slamming - It can disable your website and turn off your emails

if you receive a notice in the mail claiming that your domain name was about to expire. The letter was written in extremely alarming terms, as if my entire world would be destroyed forever if I was stupid enough to allow the name to expire. The letter made it clear that I could renew immediately and should, because if the domain expired I would, of course, lose it and thus life as I knew it would come to a close.
Closer examination revealed that the document was not from my domain registrar at all. In fact, it was from some company that I had never heard of before. The letter certainly looked official and important, but in reality it was just more junk mail.
Okay, first question: how had these idiots gotten my home address? Simple. As it turns out, this is a common practice among some of the less ethical domain registrars. Using the WHOIS database, they get a list of all of the domain names about to expire, then send a letter to each address explaining this fact and offering to renew the domain.
The WHOIS database is a list of each domain name that exists on the internet, along with the name and address (and some other information) of each owner. This information is public knowledge, freely available to anyone.
What would have happened if I had sent a check to the domain registrar to pay for a renewal? It would have been transferred to the new registrar. If I had not read the letter carefully, I probably would not have realized that I was not just renewing my domain, I was transferring my domain to a new registrar.
In some instances worse things happen. You could receive an email in your inbox, for example, making the same claim: your domain is about to expire. Click on a link and you've given (unknowingly) permission for your domain to be transferred. A few days later you might discover your web site not working, your email turned off and your domain information completely unavailable.
This is called "domain name slamming", and it is named after the practice that some highly unethical long distance phone companies employ. These companies will, at the least provocation, change your phone company to themselves. You could cash a check, return a post card or use any number of other means to "give permission" to change.  Some of the most unethical companies have been known to just change your service without even asking.
The moral of the story? Keep good records of where your domain names are registered. If you do get an email or a letter, go directly to your domain registrar's web site and renew the domain yourself. Don't click anything in the email, respond or send back a letter. Just go to the web site and renew. This way you can be sure you understand exactly what is happening, and this way you can be positive that nothing else is occurring.
And oh yes, stay away from those registrars who engage in this practice. At least, that's my humble advice. I find the whole tactic unethical in the extreme, and personally, I will go to extremes to not do business with any registrar who slams.

What Is Cybersquatting

Cybersquatting is the purchase of a domain name in bad faith. Usually this is done with the intention of reselling that domain name back to the legal copyright holder, although sometimes there are other reasons. This is considered a violation of the trademark laws.
An example of cybersquatting would be if someone purchased the domain name "mcdonalds.ws" and then proceeded to attempt to sell it back to McDonalds. It would also be considered a violation of the law if the purchaser put up a web site describing how bad McDonald's food was or commenting on the service.
Cybersquatting was made illegal by the passage of a federal law in 1999 known as the Anti-Cybersquatting Consumer Protection Act. The law became necessary because numerous large companies were forced to pay large sums to buy their domain names from third parties. These companies included such notables as Panasonic, Fry's Electronics, Hertz and Avon.
How do you know if a company is a victim of cybersquatting? Type in a name that has been trademarked preceded by "www" and following by ".com", ".net" or ".org". If you get a valid web site which looks like it is related in some way to the domain name, then there is no cybersquatting in effect (although this could be a simple trademark violation). However, if you get one of the following results, then this could be a cybersquatter.
- Can't find server
- under construction
- page with no relationship to domain name
Of course there could be a reasonable explanation for each of these results, so they do not always mean there is cybersquatting occurring. It's a good idea to contact the domain name owner before taking any legal action to find out what's going on.
How do you prove someone is cybersquatting?
- The domain name registrants intention was to profit from your domain name in bad faith
- Your trademark was in effect and widely known at the time the domain name was registered
- The domain name is identical to your trademark
- And you have actually registered the trademark
How do you know there is a bad faith intent? Well, there is probably no bad faith intent if one of the following is true:
- domain name is the same as the person's name or nickname.
- They are actually selling or intend on selling something on their web site
- Does the web site owner actually have a legitimate use of the domain name? This would be, for example, true for a company named "McDonalds Plumbing". They would have a legitimate reason for owning the "McDonalds" domain name.
Some clues that cybersquatting is occurring include:
- The domain name owner has put up a web site which in some way harms your company. For example, if you had somehow purchased "AOL.ORG" and created a web site about how AOL provided terrible service, you are cybersquatting.
- If the domain name owner never legitimately used the domain name and simply offered to sell it to you, he is cybersquatting. If a person buys up a lot of names and has sold them over and over, there is a pattern of cybersquatting.
- If the domain name is the same as a very famous trademark, then it has a greater likelihood of being considered cybersquatting.
What can happen if someone is found guilty of cybersquatting is they can be ordered to hand over the domain name. In addition, if the domain was purchased after 1999, they can be ordered to pay monetary damages.

Domain name and website tools to monitor the performance of your site

Ranking tools
Where is my listing? Want a tool that can tell you which page your site appears on by keyword?
www.top25web.com/cgi-bin/report.cgi
Top25web searches domain names by keyword for the following search engines:- Google, Alta vista and inktomi, drilling down for the first 500 entries on each search engine.
How many of my websites pages are indexed? Do you have a large site? – it can be a pain using the site: command in google, the following tells you how many of your pages are indexed in Fast, Google, Alta Vista and MSN
www.neutralize.com creates a pie chart of the % of your pages indexed in each of the engines.
Meta – Tag analysers
Meta tags are much less important than they used to be, though the Title tag is still very powerful.
The following are my favourites:
http://www.sitesolutions.com/analysis.asp - select the website analysis option from the left hand, this is particularly good at telling if you’ve got the right combination of keywords in your tags and which keyword should be where.
http://www.sitescreamer.com/from22.html - this analyses your tags, and gives a narrative opinion – excellent being the best rating.
Traffic statistics
Good traffic statistics are essential for your own site, but how to get information on rivals traffic?, Alexa makes use of its own database of user and converts these to a traffic ranking.
The Alexa site can be found at www.alexa.com
Good HTML
Google and other search engines have problems with poor html – so cleaning up the glitches in your scrip can be helpful. The following is a good free html validator :-
www.htmlhelp.com/tools/validator
Keyword density
Writing keyword rich copy isn’t the easiest task in the world, but to get a good ranking, your keyword density has to be right, not too low, not too high ( between 3% and 7%). The following is a good article on the subject and contains a link to a good density tool.
The article http://www.in-vancouver.com/members/news_item.php?record_num=48
The tool: www.keyworddensity.com
Selecting keywords
Not sure which keywords will bring what traffic?
Wordtracker has a great site – try their free report first, if it works for you, the sell a days usage from £4.00 ($6.00).
www.wordtracker.com
I hope you find these tools helpful, I use them on a daily basis and find them very helpful.
Every thought of a question you wanted to ask Google?
Google answers works by you posting a price for each question - the higher the price the more likely it will be answered. Higher bids also get more thorough explanations. Payment is by credit card and prices start from $2.00
This is a good place to get started with web site optimisation. Typically an experienced researcher will spend an hour or so looking at your site for £40-50. This compares very favourable to the £100's you can pay elsewhere.
A good tip is to read the last few weeks of questions - most likely there will be questions very similar to yours.
The answers given often are full of links to sites which are both reputable and amongst the leaders in their field.
The site is also full of helpful questions and answers on domain names and web tools
I hope you found this ariticle helpful, my site now has a glossary full of similiar ones.

What is the Domain Redemption Period?

What is the Domain Redemption Period? 

The redemption period is a Domain Registry period of up to 30 days that occurs when a domain name is deleted after having expired unrenewed. Instead of just getting deleted and returning to the pool of domain names available for registration, the existing registry keeps a hold on the  domain name in a what is technically called as REDEMPTION PERIOD. During this 30-day redemption period, the original domain registrant (owner of the domain) is allowed to retrieve the domain name from deletion by contacting their Registrar. This process costs an additional fee.
This extra 30-day period - redemption period - extends the time available to renew expired domain names by 30 days. However, all names that enter the redemption period are removed from the zone files in the global DNS, as a result, any Web site or email services associated with the domain name gone into redemption period will stop working and would appear offline.
Pending Delete Phase
In addition, after the 30-day redemption period there is a 5-day Pending Delete Phase. When a domain is in Pending Delete Phase, no one is allowed to renew the domain and it cannot be yet registered because its still not returned to the public domain pool. After the 5-day Pending Delete Phase the Registry will release the domain name back into the public pool of available domain names enabling fresh registration.
Renew domain before redemption phase
It is strongly recommended that you renew your domain registration in time before the domain name is placed in redemption lock because once its placed in redemption, the zone files of such domain gets automatically removed from the Domain Name Service and associated website and email etc services will cease to work.

What is Redemptionperiod?

A domain name is placed in REDEMPTIONPERIOD status when a registrar requests the deletion of a name that is not within the Add Grace Period.
A name that is in REDEMPTIONPERIOD status will not be included in the zone file. A registrar can not modify or purge a name in EDEMPTIONPERIOD status. The only action a registrar can take on a name in  REDEMPTIONPERIOD is to request that it be restored.
Any other registrar requests to modify or otherwise update the domain will be rejected. Unless restored, the domain will be held in REDEMPTIONPERIOD status for a specified number of calendar days. The current length of this Redemption Period is thirty calendar days.
For someone interested in registering previously registered - but now expiring domains: the domain will always go into REDEMPTIONPERIOD status before it is released to be re-registered.  It will remain in REDEMPTIONPERIOD status for 30 days at which time it will then move to PENDINGDELETE status.
If a domain is renewed by the original registrant during the REDEMPTIONPERIOD status, the domain will NOT go to PENDINGDELETE status.

Sunday, December 19, 2010

Use this form to search Blogger.com profiles

Blogger have not provided a search facility for their profiles, yet. So here's a form to search Blogger.com profiles for interests, books, music and movies (updated Aug 07) or industry or occupation (also in my sidebar, you need to scroll down towards the end) - feel free to try it out (results open in a new window).

Javascript

Here is the Javascript code for the profile search form which you can just copy and paste into your template sidebar if you want to use it in your own blog (I put it under a sidebar heading entitled "Search Blogger.com profiles", but that's not necessary; also note that I haven't yet worked out how to get it to open the search results in a new window without the original window going weird, so it opens them in the same window):
<script language=javascript>
//results open in new window, to change this
//edit target on selectedIndex e.g. target=_self
//by Improbulus http://www.consumingexperience.com/
// licensed under Creative Commons License
//http://creativecommons.org/licenses/by-nc-sa/2.5/
//- based with thanks on code by Petra Richardson at
//http://www.js-x.com/javascript/?id=1041
//and thanks to G-BOAC of Blogger Forum for the fix
//to open results in a new window properly

function send_search()
{
var searchstring=window.document.searchengine.search.value;

if(window.document.searchengine.engine.selectedIndex == "0")
{
window.document.interests.t.value="i";
window.document.interests.q.value=searchstring;
window.document.interests.action="http://www.blogger.com/profile-find.g";
window.document.interests.target="_blank";
window.document.interests.submit()
;
}

if(window.document.searchengine.engine.selectedIndex == "1")
{
window.document.movies.t.value="m";
window.document.movies.q.value=searchstring;
window.document.movies.action="http://www.blogger.com/profile-find.g";
window.document.movies.target="_blank";
window.document.movies.submit()
;
}

if(window.document.searchengine.engine.selectedIndex == "2")
{
window.document.music.t.value="s";
window.document.music.q.value=searchstring;
window.document.music.action="http://www.blogger.com/profile-find.g";
window.document.music.target="_blank";
window.document.music.submit()
;
}

if(window.document.searchengine.engine.selectedIndex == "3")
{
window.document.books.t.value="b";
window.document.books.q.value=searchstring;
window.document.books.action="http://www.blogger.com/profile-find.g";
window.document.books.target="_blank";
window.document.books.submit()
;
}
}
</script>

<!-- below are the submission forms -->
<form name=interests action="http://www.blogger.com/profile-find.g" method="get" />
<input type="hidden" name="t" value="i" />
<input type="hidden" name="q" />
</form>

<form name=movies action="http://www.blogger.com/profile-find.g" method="get" />
<input type="hidden" name="t" value="m" />
<input type="hidden" name="q" />
</form>

<form name=music action="http://www.blogger.com/profile-find.g" method="get" />
<input type="hidden" name="t" value="s" />
<input type="hidden" name="q" />
</form>

<form name=books action="http://www.blogger.com/profile-find.g" method="get" />
<input type="hidden" name="t" value="b" />
<input type="hidden" name="q" />
</form>

<!-- below is the multiple search box that you will see on your webpage -->

<form name=searchengine method=post action="javascript:send_search()">
Find this word or phrase:
<input name="search" type="text" size="25">
within this profile section:
<select name="engine">
<option>Interests</option>
<option>Movies</option>
<option>Music</option>
<option>Books</option>
</select>
<p>
<input type="button" value="Search profiles" name="B1" onclick="javascript:send_search()">
</p>
</form>


HTML

a much simpler search form, which produces exactly the same result, using HTML rather than Javascript.

Here's the code :

<!-- Please do not delete this note
Form to search Blogger.com profiles - results open in new window, to change this delete target="_self"
Copyright Improbulus 2005-2007 http://www.consumingexperience.com/ licensed under Creative Commons License http://creativecommons.org/licenses/by-nc-sa/2.5/
-->
<form action="http://www.blogger.com/profile-find.g" method="get" target="_blank">
<label for="q">Find this word or phrase:</label><br />
<input type="text" size="25" name="q" id="q" /><br />
<label for="t">within this profile section:</label><br />
<select name="t" id="t">
<option value="i">Interests</option>
<option value="m">Movies</option>
<option value="s">Music</option>
<option value="b">Books</option>
<option value="j">Industry</option>
<option value="o">Occupation</option>
</select>
<input type="submit" value="Search" /> <input type="reset" value="Clear" />
</form>

 

Blogger Buzz: Browse Profiles! Find new blogs to read!

Blogger Buzz: Browse Profiles! Find new blogs to read!: "Say you live in Albuquerque, count the Smashing Pumpkins among your favorite bands, and like sushi. Starting today, we’re making it easy for..."

Tips Of Seo

  • Write content that your audience is already looking for within the last 90 days.
  • Does your Web copy speak to the reader or does it speak about yourself?
  • Focus on writing for the human audience first and search engines second.
  • Tips for triggering idea generation and giving your strategies a unique twist.
  • Creating your content so that it "speaks" to a specific audience of visitors.
  • Build your search engine optimization skills in the beginning with the "stress free" approach.

10 Major Points for SEO

  • A Keyword Rich Domain
  • Title Tag
  • Heading Tags
  • Bold, Strong and Emphasis Tags
  • Keyword Rich Text
  • Structured Navigation And Correct Internal Navigation
  • Keyword Rich Internal Links
  • Avoid Flash
  • Avoid Duplicate content
  • Keyword Rich, Relevant Inbound Links

How can boost your traffic and ranking in major search engine

There are some point which can give boost your traffic and highest ranking in all major engine search.
  • Submit your sitemap to Google, Yahoo, MSN and ASK.com
  • Offer a sitemap to your site visitors for easy page navigation.
  • Create unique and rich content sites. Avoid duplicate content. Do not create multiple pages, sub-domains, domains, mirror sites or sites with different domain names but the same content.
  • Check your keywords and make sure they are relevant and actually are contained in your site. Avoid keyword stuffing.
  • Use text instead of images in your content, links and important subjects.
  • Make your TITLE and ALT tags descriptive, simple and keyword rich. Avoid irrelevant and repeated keywords.
  • Your Title tag should be 60-80 characters maximum length.
  • The keywords Meta Tag must be 15-20 words maximum.
  • Optimize pages with Headings (H1, H2, H3..) containing your site's primary keywords.
  • If your site contains dynamic pages (i.e., the URL contains a "?" character), make sure you use SEO friendly URLs. Search engine spiders have difficulty indexing dynamic pages.

Friday, December 17, 2010

eBay Buys Mobile App Developer Critical Path Software

eBay is on a bit of a holiday shopping spree. Weeks after announcing the acquisition of Milo, the e-commerce giant has just bought Critical Path Software. The Portland-based mobile app developer has been helping eBay develop its mobile offerings, including its primary iPhone app, StubHub, eBay Classifieds and Shopping.com iPhone applications. Financial terms of the agreement were not disclosed.
The acquisition, which seems to center around talent, makes sense considering eBay’s big push towards developing its mobile suite of applications. Most recently, eBay just released barcode scanning app RedLaser (which eBay acquired in June) for Android phones.
Not only is mobile a great way to send traffic to eBay’s marketplace (the primary iPhone app has seen 14 million downloads in two years), but it’s also a a way to make money. eBay is posting record holiday sales through its mobile offerings, and is expected to see over $1.5 billion in mobile sales through its marketplace in 2010.

Bing Search Summit: It’s All About Sweating The Small Stuff





Today Microsoft is holding a ‘Bing Search Summit’ in San Francisco, where it’s showcasing some of the latest addition to its search engine, as well as some new features for its mobile applications on iPhone and Android.

The overarching theme here has been to highlight numerous minor enhancements the Bing team has been making to help improve its search experience. The goal: boil search down to the tasks that most people are typically conducting on Bing.
Microsoft says that the vast majority of Bing queries fall under 155 query segments, which include things like Music (4.6% of searches), Consumer Electronics (1.6%), and Recipes (1.1%). Bing wants to take these segments and figure out which verbs they typically involve: music has “download songs” and “read lyrics”, electronics has “read reviews”, and so on.
To best handle these, Bing has developed 400 “unique visual experiences” depending on the search (in other words, photos, images, and links are presented in different ways depending on the content you’re searching for. Microsoft says that in this respect, it does more than their competition (Google). Today, Bing is launching 50 new integrations.
Bing’s Derrick Connell then launched into a whirlwind tour showcasing some of these new features. Most of these additions were subtle, but that’s sort of the point: they save you a few seconds here and there. Here are a few of the examples he talked about:
  • For a travel search query like “flights from Denver to las vegas in June”, Bing will include a form in your search results, with fields pre-populated with airports in Denver, Las Vegas, and the first weekend in June.
  • A query for “Michael Moore healthcare movie” will display Sicko as your top results, with a grid of reviews from sides like IMDB immediately below.
  • TV shows have a new overview page where you can click around TV listings, and play an episode in-line provided Bing has access to it
  • You can now look at destination overview portals for major cities, which displays images, hotels, and other relevant information
  • Product reviews are displayed inline along with search results about products
Bing also showed off some minor tweaks to its image results. Now when you view images while under the ‘small’ mode, whitespace is eliminated so that it’s a big grid of images. Clicking on an image will display its full sized mode in a pane above the rest of the linked page as usual, and now you can quickly jump to other related images using a neat mouseover effect.
Social

The next big area in Bing’s strategy is its social component, which revolves around the Facebook integration that it launched in October.
Bing has integrated Facebook ‘Likes’ into its results for a couple of months now — if a friend has ‘Liked’ an article that’s relevant to your query, Bing will note that. But these ‘Likes’ have been shown in a separate widget — soon, they’ll actually impact the search algorithm itself, so links will be reordered based on social signals.
For its Maps products, Bing has shifted its focus from Silverlight to HTML5 and AJAX (this was announced last month). Bing Maps will start to show interior maps of shopping centers as part of its Maps, and it’s also partnering with EveryScape to showcase interior panoramas of venues.
To finish off the presentation, Bing showed a new version of its iPhone application. The app has integration with Grubhub and OpenTable, and also includes street-level views. Bing also gave a preview of a very cool Panorama creator that’s based on the Photosynth backend — it looks like it will compete with Occipital’s Panoramic 360 app.
The bottom line here is that Bing isn’t trying to compete with Google in terms of speed. Instead, it’s taking advantage of its underdog position to try to figure out how to help users complete their tasks more quickly than they would using normal search. Of course, despite its long history of featuring a spartan interface, Google has also been making a lot of progress here — and you can be sure if it notices that Bing is doing something better, it’ll incorporate some of those changes itself (see Google’s revamped image search for an example).

Blekko Goes Social, Now Lets You Search Sites Your Friends Have ‘Liked’ On Facebook

As of today search engine Blekko has made search a little bit more social. Now the search engine lets you login through Facebook Connect and, using Facebook API data, shows you what sites your friends have ‘Liked’ as well as lets you search only those sites. Just connect to Blekko through Facebook, wait a few minutes for your ‘Likes’ to load and begin searching with the /Likes slashtag to see only friend-approved sites. Unlike Bing’s Facebook ‘Like’ integration, Blekko’s new feature doesn’t just surface ‘Likes’ next to already existant result URLs. You can actually change the results you see based on what your friends have ‘Liked’ by searching and adding the /Likes slashtag to any search, for example TechCrunch /Likes





And while ‘Like’ data now also shows up  in normal Blekko search, you can also sort by ‘Like’ number by clicking on the thumbs up icon in the top corner of your results page. Click on ‘View’ to see which friends liked what.“We want to give you different views of the web based on how you want to see it,” said Blekko co-founder Mike Markson explaining the recent product development.
The feature also allows for some nifty tricks: You can search for everything movie related in your social graph by searching for /Movies /Likes. You can also click on a users’s name to see their ‘Likes’ and actually ‘Like’ individual results which will add the ‘Likes’ to your /Likes slashtag (Warning, this feature was a little buggy at the time of our demo). “We think this gives users a reason to use the ‘Like’ button, as a way of bookmarking something so you can search for it again in the future,” says CEO Rich Skrenta.

Blekko will now surface ‘Like’ information in three scenarios, a particular page, the site in general and a different page, taking one small step towards a feature of social search. While in actuality Google was the first social search (because links were actually made by humans) today most of the new links to things are not created by individuals, but spammers. Blekko’s use of the social graph is a noble attempt at remedying this.
I for one welcome this new era of personalized search.“We think having the insight of your friends directly into your search results does make search better,” Markson emphasizes. “There’s a real person behind the Facebook accounts, when they ‘Like’ something it’s not just a machine ‘Liking’ it but a human,” adds Skrenta. Maybe they’re right? Perhaps friendship is greatest spam filter there is.

Saturday, December 4, 2010

Written text on image using Gd library


$message="Enter text you want to write on image";
$picture = imagecreatefromgif('images/bg.gif');
$black = ImageColorAllocate ($picture, 0, 0, 0);
if(strlen($message)>100){
$message_ = substr($message,0,100)." ......";
$message = explode("\n",wordwrap($message_,18, "\n"));
//print_r($message);
}else{
$message= explode("\n",wordwrap($message,18, "\n"));
}

$j=10;
$p = 10;
for($i=0;$i
CenterImageString($picture, 143, stripslashes(trim($message[$i])), 10, $p,$j, $black);
$j=$j+18;
}
$imagefile = "images/comments/".$id.".gif";
ImagePng($picture, $imagefile);
function CenterImageString($image, $image_width, $string, $font_size,$x, $y, $color){
//$text_width = imagefontwidth($font_size)*strlen($string);
//$center = ceil($image_width / 2);
//$x = $center - (ceil($text_width/2));
//$font_size=10;
ImageString($image, $font_size, $x, $y, $string, $color);
}

Friday, December 3, 2010

Paypal

paypal.class.php


/*******************************************************************************
* PHP Paypal IPN Integration Class
*******************************************************************************
* Author: Micah Carrick
* Email: email@micahcarrick.com
* Website: http://www.micahcarrick.com
*
* File: paypal.class.php
* Version: 1.3.0
* Copyright: (c) 2005 - Micah Carrick
* You are free to use, distribute, and modify this software
* under the terms of the GNU General Public License. See the
* included license.txt file.
*
*******************************************************************************
* VERION HISTORY:
* v1.3.0 [10.10.2005] - Fixed it so that single quotes are handled the
* right way rather than simple stripping them. This
* was needed because the user could still put in
* quotes.
*
* v1.2.1 [06.05.2005] - Fixed typo from previous fix :)
*
* v1.2.0 [05.31.2005] - Added the optional ability to remove all quotes
* from the paypal posts. The IPN will come back
* invalid sometimes when quotes are used in certian
* fields.
*
* v1.1.0 [05.15.2005] - Revised the form output in the submit_paypal_post
* method to allow non-javascript capable browsers
* to provide a means of manual form submission.
*
* v1.0.0 [04.16.2005] - Initial Version
*
*******************************************************************************
* DESCRIPTION:
*
* NOTE: See www.micahcarrick.com for the most recent version of this class
* along with any applicable sample files and other documentaion.
*
* This file provides a neat and simple method to interface with paypal and
* The paypal Instant Payment Notification (IPN) interface. This file is
* NOT intended to make the paypal integration "plug 'n' play". It still
* requires the developer (that should be you) to understand the paypal
* process and know the variables you want/need to pass to paypal to
* achieve what you want.
*
* This class handles the submission of an order to paypal aswell as the
* processing an Instant Payment Notification.
*
* This code is based on that of the php-toolkit from paypal. I've taken
* the basic principals and put it in to a class so that it is a little
* easier--at least for me--to use. The php-toolkit can be downloaded from
* http://sourceforge.net/projects/paypal.
*
* To submit an order to paypal, have your order form POST to a file with:
*
* $p = new paypal_class;
* $p->add_field('business', 'somebody@domain.com');
* $p->add_field('first_name', $_POST['first_name']);
* ... (add all your fields in the same manor)
* $p->submit_paypal_post();
*
* To process an IPN, have your IPN processing file contain:
*
* $p = new paypal_class;
* if ($p->validate_ipn()) {
* ... (IPN is verified. Details are in the ipn_data() array)
* }
*
*
* In case you are new to paypal, here is some information to help you:
*
* 1. Download and read the Merchant User Manual and Integration Guide from
* http://www.paypal.com/en_US/pdf/integration_guide.pdf. This gives
* you all the information you need including the fields you can pass to
* paypal (using add_field() with this class) aswell as all the fields
* that are returned in an IPN post (stored in the ipn_data() array in
* this class). It also diagrams the entire transaction process.
*
* 2. Create a "sandbox" account for a buyer and a seller. This is just
* a test account(s) that allow you to test your site from both the
* seller and buyer perspective. The instructions for this is available
* at https://developer.paypal.com/ as well as a great forum where you
* can ask all your paypal integration questions. Make sure you follow
* all the directions in setting up a sandbox test environment, including
* the addition of fake bank accounts and credit cards.
*
*******************************************************************************
*/


class paypal_class {

var $last_error; // holds the last error encountered

var $ipn_log; // bool: log IPN results to text file?

var $ipn_log_file; // filename of the IPN log
var $ipn_response; // holds the IPN response from paypal
var $ipn_data = array(); // array contains the POST values for IPN

var $fields = array(); // array holds the fields to submit to paypal


function paypal_class() {

// initialization constructor. Called when class is created.

$this->paypal_url = 'https://www.paypal.com/cgi-bin/webscr';

$this->last_error = '';

$this->ipn_log_file = '.ipn_results.log';
$this->ipn_log = true;
$this->ipn_response = '';

// populate $fields array with a few default values. See the paypal
// documentation for a list of fields and their data types. These defaul
// values can be overwritten by the calling script.

$this->add_field('rm','2'); // Return method = POST
$this->add_field('cmd','_xclick');

}

function add_field($field, $value) {

// adds a key=>value pair to the fields array, which is what will be
// sent to paypal as POST variables. If the value is already in the
// array, it will be overwritten.

$this->fields["$field"] = $value;
}

function submit_paypal_post() {

// this function actually generates an entire HTML page consisting of
// a form with hidden elements which is submitted to paypal via the
// BODY element's onLoad attribute. We do this so that you can validate
// any POST vars from you custom form before submitting to paypal. So
// basically, you'll have your own form which is submitted to your script
// to validate the data, which in turn calls this function to create
// another hidden form and submit to paypal.

// The user will briefly see a message on the screen that reads:
// "Please wait, your order is being processed..." and then immediately
// is redirected to paypal.

include("redirecting.php");


}

function validate_ipn() {


// parse the paypal URL
$url_parsed=parse_url($this->paypal_url);

// generate the post string from the _POST vars aswell as load the
// _POST vars into an arry so we can play with them from the calling
// script.
$post_string = '';
foreach ($_POST as $field=>$value) {
$this->ipn_data["$field"] = $value;
$post_string .= $field.'='.urlencode(stripslashes($value)).'&';
}
$post_string.="cmd=_notify-validate"; // append ipn command

// open the connection to paypal
$fp = fsockopen($url_parsed[host],"80",$err_num,$err_str,30);
if(!$fp) {

// could not open the connection. If loggin is on, the error message
// will be in the log.
$this->last_error = "fsockopen error no. $errnum: $errstr";
$this->log_ipn_results(false);
return false;

} else {

// Post the data back to paypal
fputs($fp, "POST $url_parsed[path] HTTP/1.1\r\n");
fputs($fp, "Host: $url_parsed[host]\r\n");
fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n");
fputs($fp, "Content-length: ".strlen($post_string)."\r\n");
fputs($fp, "Connection: close\r\n\r\n");
fputs($fp, $post_string . "\r\n\r\n");

// loop through the response from the server and append to variable
while(!feof($fp)) {
$this->ipn_response .= fgets($fp, 1024);
}

fclose($fp); // close connection

}

if (eregi("VERIFIED",$this->ipn_response)) {

// Valid IPN transaction.
$this->log_ipn_results(true);
return true;

} else {

// Invalid IPN transaction. Check the log for details.
$this->last_error = 'IPN Validation Failed.';
$this->log_ipn_results(false);
return false;

}

}

function log_ipn_results($success) {


if (!$this->ipn_log) return; // is logging turned off?

// Timestamp
$text = '['.date('m/d/Y g:i A').'] - ';

// Success or failure being logged?
if ($success) $text .= "SUCCESS!\n";
else $text .= 'FAIL: '.$this->last_error."\n";

// Log the POST variables
$text .= "IPN POST Vars from Paypal:\n";
foreach ($this->ipn_data as $key=>$value) {
$text .= "$key=$value, ";
}

// Log the response from the paypal server
$text .= "\nIPN Response from Paypal Server:\n ".$this->ipn_response;

// Write to log
$fp=fopen($this->ipn_log_file,'a');
fwrite($fp, $text . "\n\n");

fclose($fp); // close file
}

function dump_fields() {

// Used for debugging, this function will output all the field/value pairs
// that are currently defined in the instance of the class using the
// add_field() function.

echo "

paypal_class->dump_fields() Output:

";
echo "



";

ksort($this->fields);
foreach ($this->fields as $key => $value) {
echo "";
}

echo "
Field Name
Value
$key
".urldecode($value)."

";
}
}

-------------------------------------------------------------------------------------
paypal.php
//include("requiredfile.php");
/* PHP Paypal IPN Integration Class Demonstration File
* 4.16.2005 - Micah Carrick, email@micahcarrick.com
*
* This file demonstrates the usage of paypal.class.php, a class designed
* to aid in the interfacing between your website, paypal, and the instant
* payment notification (IPN) interface. This single file serves as 4
* virtual pages depending on the "action" varialble passed in the URL. It's
* the processing page which processes form data being submitted to paypal, it
* is the page paypal returns a user to upon success, it's the page paypal
* returns a user to upon canceling an order, and finally, it's the page that
* handles the IPN request from Paypal.
*
* I tried to comment this file, aswell as the acutall class file, as well as
* I possibly could. Please email me with questions, comments, and suggestions.
* See the header of paypal.class.php for additional resources and information.
*/

// Setup class
require_once('paypal.class.php'); // include the class file
$p = new paypal_class; // initiate an instance of the class
$p->paypal_url = 'https://www.sandbox.paypal.com/cgi-bin/webscr'; // testing paypal url
//$p->paypal_url = 'https://www.paypal.com/cgi-bin/webscr'; // paypal url

// setup a variable for this script (ie: 'http://www.micahcarrick.com/paypal.php')
$this_script = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'];

// if there is not action variable, set the default action of 'process'
if (empty($_GET['action'])) $_GET['action'] = 'process';

switch ($_GET['action']) {

case 'process': // Process and order...

// There should be no output at this point. To process the POST data,
// the submit_paypal_post() function will output all the HTML tags which
// contains a FORM which is submited instantaneously using the BODY onload
// attribute. In other words, don't echo or printf anything when you're
// going to be calling the submit_paypal_post() function.

// This is where you would have your form validation and all that jazz.
// You would take your POST vars and load them into the class like below,
// only using the POST values instead of constant string expressions.

// For example, after ensureing all the POST variables from your custom
// order form are valid, you might have:
//
// $p->add_field('first_name', $_POST['first_name']);
// $p->add_field('last_name', $_POST['last_name']);

// get the data posted by form
$p->add_field('email_address', $_POST['email_address']);
$p->add_field('firstName', $_POST['first_name']);
$p->add_field('lastName', $_POST['last_name']);
$p->add_field('address1', $_POST['address']);
$p->add_field('address2', $_POST['address']);
$p->add_field('city', $_POST['city']);
$p->add_field('state', $_POST['state']);
$p->add_field('zip', $_POST['zipcode']);
$p->add_field('country', 'india');
// end of form date
$p->add_field('cmd', '_ext-enter');
$p->add_field('redirect_cmd', '_xclick');

$p->add_field('amount','0.01' );
$p->add_field('currency_code', 'GBP');
$p->add_field('business', 'benan@benan.net');
$p->add_field('paymentType', 'Authorization');
$p->add_field('return', $this_script.'?action=success');
$p->add_field('returnURL', $this_script.'?action=success');
$p->add_field('cancel_return', $this_script.'?action=cancel');
$p->add_field('notify_url', $this_script.'?action=ipn');
$p->add_field('item_name', 'Paypal Test Transaction');

$p->submit_paypal_post(); // submit the fields to paypal
//$p->dump_fields(); // for debugging, output a table of all the fields
break;

case 'success': // Order was successful...

// This is where you would probably want to thank the user for their order
// or what have you. The order information at this point is in POST
// variables. However, you don't want to "process" the order until you
// get validation from the IPN. That's where you would have the code to
// email an admin, update the database with payment status, activate a
// membership, etc.
header('location:thanks.php');
break;

case 'cancel': // Order was canceled...

// The order was canceled before being completed.
header('location:cancelled.php');
break;

case 'ipn': // Paypal is calling page for IPN validation...

$fp=fopen("written.txt","w");
fwrite($fp,$local_date."\n");
fwrite($fp,"Name: Manoj Singh Adha"."\n");
fwrite($fp,"Thanks"."\n");
fclose($fp);
// It's important to remember that paypal calling this script. There
// is no output here. This is where you validate the IPN data and if it's
// valid, update your database to signify that the user has payed. If
// you try and use an echo or printf function here it's not going to do you
// a bit of good. This is on the "backend". That is why, by default, the
// class logs all IPN data to a text file.

if ($p->validate_ipn()) {

// Payment has been recieved and IPN is verified. This is where you
// update your database to activate or process the order, or setup
// the database with the user's order details, email an administrator,
// etc. You can access a slew of information via the ipn_data() array.

// Check the paypal documentation for specifics on what information
// is available in the IPN POST variables. Basically, all the POST vars
// which paypal sends, which we send back for validation, are now stored
// in the ipn_data() array.


// For this example, we'll just email ourselves ALL the data.
$subject = 'Instant Payment Notification - Recieved Payment';
//$to = 'YOUR EMAIL ADDRESS HERE'; // your email
$to = 'manoj.singh@dotsquares.com'; // your email
$body = "An instant payment notification was successfully recieved\n";
$body .= "from ".$p->ipn_data['payer_email']." on ".date('m/d/Y');
$body .= " at ".date('g:i A')."\n\nDetails:\n";

foreach ($p->ipn_data as $key => $value) { $body .= "\n$key: $value"; }
mail($to, $subject, $body);
}
break;
}

?>
------------------------------------------------------------------------------------
redirectring.php

echo "

Please wait, your order is being processed and you";
echo " will be redirected to the paypal website.

\n";
echo "

echo "action=\"".$this->paypal_url."\">\n";

foreach ($this->fields as $name => $value) {
echo " \n";
}
echo "


If you are not automatically redirected to ";
echo "paypal within 5 seconds...

\n";
echo "
\n";

?>