Categories
HTTP Tips & Tutorials PHP Tips & Tutorials

PHP: How to distinguish values in $_POST or $_GET that are sent via HTTP requests and those that are set / assigned in the code

html form codeTo send parameters to a PHP script, you can either fabricate a form and post a few variables by the POST method or simply send a request of a URL full of GET value pairs. This way, in the server side PHP script code, you can retrieve these parameters sent from the client in $_POST or $_GET. The trick is, other than receiving the values from client requests, you can manually assign values to them in your code. For example,

<?php
$_POST['test'] = 100;
?>

Wherein $_POST['test'] can be used in any way possible as you can with one that is received from a HTTP request. But how can we know the posted ones from the assigned ones? The PHP function filter_has_var() is the answer. To check if a posted variable is really posted from a client request:

if (filter_has_var(INPUT_POST, 'test')) {
	// $_POST['test'] is posted from the client
} else {
	// $_POST['test'] is assigned locally
}

The same rule applies to $_GET. To make sure if a $_GET value is received by URL request:

if (filter_has_var(INPUT_GET, 'test')) {
	// $_GET['test'] is posted from the client by query strings in the URL
} else {
	// $_GET['test'] is assigned locally
}
Categories
Information Security PHP Tips & Tutorials Regular Expression Tips & Tutorials

PHP: Check or Validate URL and Email Addresses – an Easier Way than Regular Expressions, the filter_var() Function

To check if a URL or an email address is valid, the common solution is regular expressions. For instance, to validate an email address in PHP, I would use:

if (preg_match('|^[A-Z0-9._%+-][email protected][A-Z0-9.-]+\.[A-Z]{2,4}$|i', $email)) {
	// $email is valid
}

A simpler and more forgiving one would be:

|^\[email protected]\S+\.\S+$|

Which is usually quite enough for signup forms in preventing stupid typo errors. You get to validate the email by a validation link sent to the address anyway, as a final call whether the address is valid or not. For those who are obsessively curious, this may serve you well.

For URL, you can use this one:

|^\S+://\S+\.\S+.+$|

Or you can use one that is insanely detailed in addressing what a valid URL should be.

The filter_var() function of PHP5

What we are talking about here really is the filter_var() function of PHP5 that simplifies the URL and email validation by a large degree. To validate an email:

if (filter_var($email, FILTER_VALIDATE_EMAIL) !== false) {
	// $email contains a valid email
}

To validate a URL:

if (filter_var($url, FILTER_VALIDATE_URL) !== false) {
	// $url contains a valid URL
}

While filter_var() is meant to return the filtered results of the input according to the filter type specified, such as FILTER_VALIDATE_EMAIL or FILTER_VALIDATE_URL, you can generally use it to see if a valid email or a valid URL can be extracted from something. Better yet, filter and get the results first, use the result if it is good or abandon it when it is false:

$filtered_email = filter_var($email, FILTER_VALIDATE_EMAIL);
if ($filtered_email !== false) {
	// $filtered_email is the valid email got out of $email
} else {
	// nothing valid can be found in $email
}

Same applies to FILTER_VALIDATE_URL. Here’s a full list of filter types of filter_var() you can take advantage of.

Categories
HTTP Tips & Tutorials PHP Tips & Tutorials

PHP: How to detect / get the real client IP address of website visitors?

It may seem simple at first because most of us should be relying on the server side environmental variable REMOTE_ADDR solely for client IP addresses:

echo $_SERVER['REMOTE_ADDR'];

Yet it’s barely enough to get the real IP for a variety of circumstances such as when the user is visiting your website from a proxy server. To everyone’s surprise, there are a lot more environmental variables regarding client IP address than just the most straightforward one, REMOTE_ADDR. Consider this snippet in the attempt to detect the real source IP address of the request:

function get_ip_address() {
    foreach (array('HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'REMOTE_ADDR') as $key) {
        if (array_key_exists($key, $_SERVER) === true) {
            foreach (explode(',', $_SERVER[$key]) as $ip) {
                if (filter_var($ip, FILTER_VALIDATE_IP) !== false) {
                    return $ip;
                }
            }
        }
    }
}

It first searches through a series of possible environmental variables that may contain the client IP address and uses whichever that is set and then extract the potential IP value to be validated. After successful validation by the PHP5 filter_var() function, the value is returned. You better not change the order these variable names are placed in the literal array.

This approach is much more sophisticated than just looking at REMOTE_ADDR but it’s far from mess-proof because it relies on the HTTP header information which can be easily manipulated anywhere along the way the request is routed to your server / website.

Categories
JavaScript Tips & Tutorials jQuery Tips & FAQ

How to define multiple CSS rules / properties in jQuery?

The simplest way to define a CSS rule in jQuery might be:

$(".sth").css("color", "#f00");

To define more than one CSS rule in a single jQuery line:

$(".sth").css("color", "#f00").css("font-style", "italic").css("text-decoration", "underline");

Which simply doesn’t look that good, especially if you intend to add more. A better way to specify multiple CSS rules or properties with jQuery is by a JSON object:

$(".sth").css( {'color' : '#f00', 'font-style' : 'italic', 'text-decoration' : 'underline'} );

However, it is recommended that you use .addClass() instead of .css() to separate the JavaScript logics and CSS styles for maintainability.

Categories
Business and Marketing

It’s not your business, it’s who you are

stack overflow With a Quantcast world traffic rank of less than 1000, Stack Overflow has become the most visited website for developers and software engineers. It doesn’t require a genius to figure out that the site is raking in tremendous advertisement revenues while the full potential of its monetizing capacity hasn’t been unleashed yet because the creators decided that the user experience comes a much higher priority.

The site currently serves 6 million monthly unique visitors. Microsoft MSDN has less traffic. Consider the community nature of the whole Q&A application, the total number of page views should be appalling.

Yet it is merely up for a year and a half.

Joel and Jeff are the top at what they do, plus a little marketing twist. They are the best in the industry and they know their business inside out. People follow them, not just people but really smart people just like them who know a hell lot about how to get things done the right way. That’s the kind of critical mass Stack Overflow enjoyed at the launch to quickly embark on an exponential growth pattern. Quality start. It then took off by unstoppably producing insanely useful content every minute of every day, which you literally can’t find anywhere else on the Internet. These are detailed, sensible answers from friendly, experienced programmers who are thirsty to help you out, usually within 10 minutes of you asking the question.

How can Google not love the content? How can the users not love the site? How can it not succeed? If it weren’t Joel and Jeff who themselves are software heroes, how can Stack Overflow ever take off so quickly let alone attracting the smartest of the world’s programmers to passionately create content for it?

Categories
PayPal & Ecommerce

PayPal Account Access Limitation after Closing Browser Window and Opening It Again

paypal If you were like me who accidentally closed the browser window of his PayPal account AND immediately tried to reopen it by typing in www.paypal.com in the browser address bar, chances are your PayPal account is instantly limited.

It was really weird at first but soon it makes sense. This is to prevent session hijacking that PayPal believe happens when a strange request (my reopening attempt, with unfamiliar session ID) with logged-in cookies is made.

I had to resolve the limitation by changing my password and security questions and wait 48 hours for the limitation review staff to manually grant me full access again. Before my account is recovered of full access, I’d not be able to send or request money or transfer my funds away. Next time when you inadvertently close your PayPal account page, wait till the session expires (a few minutes, 10 minutes to be safe) and log in again or you will be limited for sure.

Categories
Business and Marketing Make Money Online

Email Marketing Statistics and Optimization of Open / Click Rates

Email Marketing Metrics Report A quick post to share with my readers some interesting findings regarding email marketing. Outlined by the ninth bi-annual Email Marketing Metrics Report by MailerMailer, these data is based on 300,000 email messages dispatched over a period of 6 months that ended on December 31, 2008. Here are some key statistic discoveries from the report that can be used to optimize your email marketing campaigns and improve the results.

Open rate – the overall unique open rate of the email messages was 12.52%, a slight decline from the previous 6 months.

Click rate – 2.8% which held steady throughout the year of 2008.

Best day to send – Monday had the highest open rate and click rate; weekends and the beginning of the week outperforms other days.

Subject line length – emails with a subject line shorter than 35 characters were opened more than those with a longer subject line.

Personalization – while personalizing the message body gets more opens and clicks, personalizing only the subject line decreases them.

Number of recipients – messages delivered to small and medium lists have far greater open / click rates than ones delivered to lists with more than 1,000 subscribers.

I personally haven’t tapped into email marketing yet and the 12.52% average open rate was way below what I thought it would be, which may be because of the trends in email clients disabling automatic image download by default. It’s both interesting and useful to know that we should send out important email newsletters on weekends or Monday and try to make the subject lines not so cumbersome to garner more opens and clicks.

Categories
PHP Tips & Tutorials

Use PHP to handle all incoming URL requests in a SEO friendly manner

While you can always use .htaccess and the mod_rewrite module to map SEO friendly URLs to actual PHP parameterized URLs with question marks and ampersands, you can simply put these lines in .htaccess and then rely on PHP entirely to recognize and handle all incoming URL requests of any kind / form:

<IfModule mod_rewrite.c>

RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

</IfModule>

The index.php file in the document root of your domain is now effectively in charge of all incoming URL requests. You can recognize / distinguish the requests and perform accordingly in your PHP script, the key is the PHP environmental variable $_SERVER["REQUEST_URI"] which contains the complete URL request string. Consider a index.php like this:

<?php // index.php

$req = explode('/', $_SERVER['REQUEST_URI']);
print_r($req);

?>

Type in your browser address bar:

http://www.example.com/user/110/edit

And the site will render the output page like this:

Array
(
    [0] =>
    [1] => user
    [2] => 110
    [3] => edit
)

So you can process the request according to the array. It probably means opening the editor page to edit the user whose ID is 110. Just sub-include the responsible PHP script to get the job done from index.php. To parse more complicated request URLs, e.g. with question marks and parameters, you may want to use the parse_url() or preg_split().

Categories
PHP Tips & Tutorials

PHP: Get the File Uploading Limit – Max File Size Allowed to Upload

PHP file upload max size is determined by 3 configuration values in php.ini, namely upload_max_filesize, post_max_size and memory_limit. You can get the maximum file size allowed in uploading by this snippet:

$max_upload = (int)(ini_get('upload_max_filesize'));
$max_post = (int)(ini_get('post_max_size'));
$memory_limit = (int)(ini_get('memory_limit'));
$upload_mb = min($max_upload, $max_post, $memory_limit);

Wherein $upload_mb is the maximum file size allowed for upload in MB. It’s the smallest of the 3 values. Just display this value beside the file upload control so the user knows the limit before choosing the file.

Categories
PHP Tips & Tutorials

PHP: Display Current Year to Automatically Update Copyright Years

I guess most of the websites out there are using plain strings for the years of footer copyright because many of them are still showing 2009 right now. If you have quite a few websites as I do, it’d be kind of intimidating to manually update the copyright years for all of them. So why not use PHP to output the current year automatically? The code is dead simple:

&copy; Copyright 2006 - <?php echo date('Y'); ?>

The PHP date() function does the job, the format string ‘Y’ tells it to return the current year in 4 digits. Now your website would automatically update the copyright footer year to 2006 – 2011 when comes next year.

While it may seem a good idea without tradeoffs, when you think about it, it does consume a little bit more computing resources to process the pages because it’s a function rather than a plain text string. Without a content cache, the date() function would use up extra 0.000045 seconds upon every page view (tested on my personal computer with WAMP installed on Windows XP SP2, could be larger on virtual host where computing power is restrained). With a site receiving 100,000 page views per month, the users would lost a total of 54 seconds across the year. There are also server computing resources that could otherwise be saved, thus electricity, and thus your website’s carbon footprint.

Up to you, though, especially if your time is valuable enough.