Create Thumbnail

To generate thumbnail, here is the  simple and easiest way. It will help you in creating thumb for jpg, png and gif images.


/* generateThumb()
 *
 * @param mixed $source Path to source file
 * @param mixed $destination Path to destination file
 * @param mixed $width Thumbnail file width
 * @param mixed $height Thumbnail file height
 * @return bool
 */
function generateThumb($source, $destination, $width = 100, $height = 100){ $ext = strtolower(substr($source, strrpos($source, ".")+1)); $format = ($ext == 'jpg')?'jpeg':$ext; $from_format = "imagecreatefrom".$format; $source_image = $from_format ( $source ); $source_width = imagesx ( $source_image ); $source_height = imagesy ( $source_image ); $ratio1 = $source_width/ $width; $ratio2 = $source_height / $height; if($ratio1 > $ratio2){ $width = $width; $height = $source_height/$ratio1; }else{ $width = $source_width/$ratio2; $height = $height; } $target_image = imagecreatetruecolor($width,$height); imagecopyresampled($target_image, $source_image, 0, 0, 0, 0, $width, $height, $source_width, $source_height); $image_function = "image" . $format; return $image_function ( $target_image, $destination, 100 ); }
Here is how you use it...


if(generateThumb("images/a.jpg", "images/thumbs/a.jpg", 150, 100)){ echo "done"; } else { echo "failed"; }

Compare 2 mysql databases

Below code will list all the tables with fields (& type) and total records in each table, so that we can verify whether fields are same in both database fields and record counts.
<?php
mysql_connect("localhost", "user1", "pwd1") or die(mysql_error());
mysql_select_db("db1") or die(mysql_error());

$tables = array('tbl1', 'tbl2','tbl3');

echo "<table  border='1' style='float: left'>";
foreach($tables as $tbl){
  $sel = "SELECT COUNT(1) FROM $tbl";
  $res = mysql_query($sel);
  $rec = mysql_fetch_row($res);
 
  echo "<tr><th colspan='2'>$tbl ($rec[0])</th></tr>";
  $sel1 = "SHOW FIELDS FROM $tbl";
  $res1 = mysql_query($sel1) or die($sel1.mysql_error());
  while($rec1 = mysql_fetch_row($res1)){
    echo "<tr><td>$rec1[0]</td><td>$rec1[1]</td></tr>";
  }
}
echo "</table>";
mysql_close();
mysql_connect("localhost", "user2", "pwd2") or die(mysql_error());
mysql_select_db("db2") or die(mysql_error());
echo "<table  border='1' style='float: left'>";
foreach($tables as $tbl){
  $sel = "SELECT COUNT(1) FROM $tbl";
  $res = mysql_query($sel);
  $rec = mysql_fetch_row($res);
 
  echo "<tr><th colspan='2'>$tbl ($rec[0])</th></tr>";
  $sel1 = "SHOW FIELDS FROM $tbl";
  $res1 = mysql_query($sel1) or die($sel1.mysql_error());
  while($rec1 = mysql_fetch_row($res1)){
    echo "<tr><td>$rec1[0]</td><td>$rec1[1]</td></tr>";
  }
}
echo "</table>";
?>

HTTP POST without cURL using PHP



I don't think we do a very good job of evangelizing some of the nice things that the PHP streams layer does in the PHP manual, or even in general. At least, every time I search for the code snippet that allows you to do an HTTP POST request, I don't find it in the manual and resort to reading the source. (You can find it if you search for "HTTP wrapper" in the online documentation, but that's not really what you think you're searching for when you're looking). 

So, here's an example of how to send a POST request with straight up PHP, no cURL:

<?php
     function do_post_request($url, $data, $optional_headers = null) {
          $params = array('http' => array(
                                'method' => 'POST',
                               'content' => $data
                         ));
         if ($optional_headers !== null) {
              $params['http']['header'] = $optional_headers;
          }
          $ctx = stream_context_create($params);
          $fp = @fopen($url, 'rb', false, $ctx);
          if (!$fp) {
                  throw new Exception("Problem with $url, $php_errormsg");
          }
         $response = @stream_get_contents($fp);
         if ($response === false) {
           throw new Exception("Problem reading data from $url, $php_errormsg");
          }
         return $response;
}
$optional_headers is a string containing additional HTTP headers that you would like to send in your request.
PHP's HTTP wrapper will automatically fill out the Content-Length header based on the length of the $data that you pass in. It will also automatically set the Content-Type to application/x-www-form-urlencoded if you don't specify one in the $optional_headers.
I find this very handy; I don't need to code in redirection logic, HTTP auth handling, user agent setting and so on; they are handled for me by PHP. This works for HTTPS as well, if you have openssl enabled.
You may also want to look into http_build_query() which is a convenience function that allows you to assemble query/post parameters from a PHP variable, applying appropriate escaping. You can find an example of this in the REST helper below.
Kudos to Sara Golemon for both http_build_query and exposing the HTTP context parameters up to userspace.

A Generic REST helper
Many web services offer a REST-ful interface for consuming their data, using GET requests for information retrieval and POST requests for making changes. Below you'll find a helper function that can very easily be used to consume a REST API.

The $url parameter is the HTTP or HTTPS URL for the web service. $params is an associative array of form parameters to pass to the web service; they will be passed as _GET parameters for GET requests or _POST parameters for POST requests. The $verb parameter can be GET or POST (and presumably any other valid HTTP REQUEST verb, such as PUT or DELETE, although I haven't tried those and can't say whether they will work as expected). The $format parameter can be "json" or "xml" and will automatically return a decoded json or XML document, respectively.

I've used simplexml here because it is... simple. You could very easily add a "dom" format to return the object using the richer and more complex DOM API instead.

This function uses the ignore_errors context parameter. Without this set (the default is false), PHP will treat 400 and 500 HTTP status codes as a failure to open the stream and won't return you any data. This is usually what you want when using fopen or file_get_contents, but REST services tend to set the HTTP status to indicate the error and will usually send back a payload that describes the error. We turn on ignore_errors so that we treat any returned payload as json or xml.

When using POST with REST, take care: PHP's HTTP redirection handler will drop your POST payload if the endpoint issues a redirect. If you experience problems using POST with the function below, it might be due to redirects. Most of the POST calls I've run into issue redirects if the URL is missing a trailing '/' character. In other words, if you experience problems where it seems like your parameters are not being sent in, try appending a '/' to the end of the URL and try it again.

<?php
 function rest_helper($url, $params = null, $verb = 'GET', $format = 'json') {
       $cparams = array( 'http' => array( 'method' => $verb,
                                  'ignore_errors' => true ) );
        if ($params !== null) {
              $params = http_build_query($params);
               if ($verb == 'POST') {
                     $cparams['http']['content'] = $params;
                 } else {
                        $url .= '?' . $params;
                }
          }
          $context = stream_context_create($cparams);
          $fp = fopen($url, 'rb', false, $context);
           if (!$fp) {
                 $res = false;
            } else {
               // If you're trying to troubleshoot problems, try uncommenting the
              // next two lines; it will show you the HTTP response headers across
              // all the redirects:
              // $meta = stream_get_meta_data($fp);
              // var_dump($meta['wrapper_data']);
               $res = stream_get_contents($fp);
            }
            if ($res === false) {
                  throw new Exception("$verb $url failed: $php_errormsg");
             }
             
              switch ($format) {
                  case 'json':
                            $r = json_decode($res);
                            if ($r === null) {
                                 throw new Exception("failed to decode $res as json");
                             }
                                     return $r;
                  case 'xml':
                             $r = simplexml_load_string($res);
                             if ($r === null) {
                                 throw new Exception("failed to decode $res as xml");
                             }
                             return $r;
               }
               return $res;
      }
      // This lists projects by Ed Finkler on GitHub:

    foreach ( rest_helper('http://github.com/api/v2/json/repos/show/funkatron') ->repositories as $repo) {
                echo $repo->name, "\n";
                echo htmlentities($repo->description), "\n";
                echo "\n";
       } // This incomplete snippet demonstrates using POST with the Disqus API

       var_dump(
             rest_helper( "http://disqus.com/api/thread_by_identifier/",
                        array(
                                  'api_version' => '1.1',
                                  'user_api_key' => $my_disqus_api_key,
                                  'identifier' => $thread_unique_id,
                                  'forum_api_key' => $forum_api_key,
                                  'title' => 'HTTP POST from PHP, without cURL', ),
                       'POST' ) );
You can find more documentation on the HTTP wrapper options in the HTTP and HTTPS page in the PHP manual, more on the GitHub API at github.com, more on the Disqus API and more on Ed Finkler at his blog.

Original Post

4 Most Important PHP Security Measures

We can say that PHP is a mature language with lot’s of useful, but potentially dangerous features. The rapid growth of the language and the dynamic nature of the Web let people easily create dynamic web pages without any prior knowledge in computer science or the architecture of the Internet.

In this tutorial we’ll have a look at 4 important PHP security measures that you should implement in order to develop a safer website.

1. Register Globals

Up until PHP version 4.2.0 the register_globals directive’s default value was On. One of the most controversial change in following versions was that the PHP core developers changed this default value to Off, not because the directive itself was insecure, but the common misuse of it was.
Note: This feature will be removed starting with PHP 6.0.0
When this directive is On, PHP will inject extra variables in the script such as HTML request variables, etc. The problem with this approach is that a developer cannot rely anything outside of his script and by injecting these variables an outside attacker could overwrite already defined variables or create potentially dangerous ones. For example:
PHP could inject these sort of variables in a script
$username = 'hacked_username';
Now if a $username variable was already set this would overwrite it. Another good example can be found on php.net
if ($authorized) {
 //show members only page
}
An attacker could alter the value of this variable simply by using GET auth.php?authorized=1 if the above code snippet is found in auth.php file
The best practice, that every developer should follow, is setting register_globals directive to Off and use the already defined PHP superglobals such as $_GET, $_POST.
register_globals directive is found in the php.ini file.

2. Error Reporting

When developing a complex website or web application enabling errors display is essential. A developer cannot fix the committed errors if he can’t see them, but once the website is in production the errors display should be disabled, because PHP errors provides detailed information to the outside attacker.
A good approach is to enable error display in development environment:
error_reporting(E_ALL);
ini_set('display_errors','On');
And once in production environment disable error display, but enable error logging to a file:
error_reporting(E_ALL);
ini_set('display_errors','Off');
ini_set('log_errors', 'On');
ini_set('error_log', '/path/to/error/log');
Alternatively you can use error_reporting(E_ALL | E_STRICT), this is the highest setting, offering suggestion for forward compatibility too.

3. Cross-Site Scripting (XSS)

Cross-site scripting vulnerability is the most common form of attack on websites. The mistake made by developers is not filtering input data from web forms and not escaping the output.
For example we have the following comment form
<form action="process.php" method="post" accept-charset="utf-8" enctype="multipart/form-data" name="frmComment">
 
  <textarea name="txtMessage" id="txtMessage"></textarea>  
 <input type="submit" name="submit" value="Send" id="submit" />
 
</form>
The application displays the following data like:
echo $_POST['txtMessage'];
The vulnerability is that the application doesn’t filter the input and escape the output. Let’s say someone writes the following javascript in the comment textarea:
alert ('hacked');
If an application doesn’t escape this output on every page request a Javascript alert box will pop up. The best a developer can do is to filter out any HTML tags from the data with:
$clean_message = strip_tags($_POST['txtComment']);
And escape it when outputting the date with htmlentities:
htmlentities($clean_message, ENT_QUOTES, 'UTF-8');
A better solution is to use HTML Purifier to filter out any unwanted malicious input and to test your web forms that it’s XSS proof use the XSS cheat sheet.

4. Exposing Sensitive Information

Many web developers store sensitive information in files such as database passwords and other credentials. If these files are not properly secured an attacker could see the contents of them, therefore hacking the applications database, etc.
The most common file extension for php include files is .inc. By using this extension and not properly creating parsing rules in Apache, a developer could create a major security hole in the web application.
In Apache configuration the default file type for unknown file extensions is text/plain. If the .inc file is not set to be parsed as a PHP file and it is in the document root then we can access this file and see the contents of it by visiting the corresponding URL.
The best solution to this problem is to store these files outside of your document root (e.g. /www, /public_html, etc.). A best practice is to place the most essential files in your document root.
If you don’t have access outside your document root then at least use the following 2 methods:
  1. Use an extra .php extension on the end of your file. E.g. sensitive.inc.php
  2. Secure the .inc file in a .htaccess file:
    <Files ~ ".inc$">
        Order allow,deny
        Deny from all
    </Files>
    

    Summary

    • Set register_globals directive to Off
    • Disable error display in production environment
    • Avoid XSS attacks, filter your input and escape your output
    • Move all your sensitive information outside of your document root, if that’s not possible add an extra .php extension to your .inc files and/or secure them in a .htaccess file

Security: Password Hashing

In this article I'm going to cover password hashing, a subject which is often poorly understood by newer developers. Recently I've been asked to look at several web applications which all had the same security issue - user profiles stored in a database with plain text passwords. Password hashing is a way of encrypting a password before it's stored so that if your database gets into the wrong hands, the damage is limited. Hashing is nothing new - it's been in use in Unix system password files since long before my time, and quite probably in other systems long before that. In this article I'll explain what a hash is, why you want to use them instead of storing real passwords in your applications, and give you some examples of how to implement password hashing in PHP and MySQL.

Foreword

As you read on you'll see that I advocate the use of a hashing algorithm called Secure Hashing Algorithm 1 (or SHA-1). Since I wrote this article, a team of researchers - Xiaoyun Wang, Yiqun Lisa Yin, and Hongbo Yu - have shown SHA-1 to be weaker than was previously thought. This means that for certain purposes such as digital signatures, stronger algorithms like SHA-256 and SHA-512 are now being recommended. For generating password hashes, SHA-1 still provides a more than adequate level of security for most applications today. You should be aware of this issue however and begin to think about using stronger algorithms in your code as they become more readily available.
For more information please see Bruce Schneier's analysis of the issue at http://www.schneier.com/blog/archives/2005/02/cryptanalysis_o.html

What Is A Hash?

A hash (also called a hash code, digest, or message digest) can be thought of as the digital fingerprint of a piece of data. You can easily generate a fixed length hash for any text string using a one-way mathematical process. It is next to impossible to (efficiently) recover the original text from a hash alone. It is also vastly unlikely that any different text string will give you an identical hash - a 'hash collision'. These properties make hashes ideally suited for storing your application's passwords. Why? Because although an attacker may compromise a part of your system and reveal your list of password hashes, they can't determine from the hashes alone what the real passwords are.

So How Do I Authenticate Users?

We've established that it's incredibly difficult to recover the original password from a hash, so how will your application know if a user has entered the correct password or not? Quite simply - by generating a hash of the user-supplied password and comparing this 'fingerprint' with the hash stored in your user profile, you'll know whether or not the passwords match. Let's look at an example:

User Registration And Password Verification

During the registration process our new user will provide their desired password (preferably with verification and through a secure session). Using code similar to the following, we store their username and password hash in our database:

          Figure 1. Our user enters their preferred access details
/* Store user details */

$passwordHash = sha1($_POST['password']);

$sql = 'INSERT INTO user (username,passwordHash) VALUES (?,?)';
$result = $db->query($sql, array($_POST['username'], $passwordHash));

?>
The next time our user logs in, we check their access credentials using similar code as follows:

                           Figure 2. Logging back in
/* Check user details */

$passwordHash = sha1($_POST['password']);

$sql = 'SELECT username FROM user WHERE username = ? AND passwordHash = ?';
$result = $db->query($sql, array($_POST['username'], $passwordHash));
if ($result->numRows() < 1)
{
    /* Access denied */
    echo 'Sorry, your username or password was incorrect!';
}
else
{
    /* Log user in */
    printf('Welcome back %s!', $_POST['username']);
}

?>

Types Of Hashes

There are a number of strong hashing algorithms in use, the most common of which are MD5 and SHA-1. Older systems - including many Linux variants - used Data Encryption Standard (DES) hashes. With only 56 bits this is no longer considered an acceptably strong hashing algorithm and should be avoided.

Examples

In PHP you can generate hashes using the md5() and sha1 functions. md5() returns a 128-bit hash (32 hexadecimal characters), whereas sha1() returns a 160-bit hash (40 hexadecimal characters). For example:
$string = 'PHP & Information Security';
printf("Original string: %s\n", $string);
printf("MD5 hash: %s\n", md5($string));
printf("SHA-1 hash: %s\n", sha1($string));

?>
This code will output the following:
Original string: PHP & Information Security
MD5 hash: 88dd8f282721af2c704e238e7f338c41
SHA-1 hash: b47210605096b9aa0129f88695e229ce309dd362
In MySQL you can generate hashes internally using the password(), md5(), or sha1 functions. password() is the function used for MySQL's own user authentication system. It returns a 16-byte string for MySQL versions prior to 4.1, and a 41-byte string (based on a double SHA-1 hash) for versions 4.1 and up. md5() is available from MySQL version 3.23.2 and sha1() was added later in 4.0.2.
mysql> select PASSWORD( 'PHP & Information Security' );
+------------------------------------------+
| PASSWORD( 'PHP & Information Security' ) |
+------------------------------------------+
| 379693e271cd3bd6                         |
+------------------------------------------+
1 row in set (0.00 sec)

mysql> select MD5( 'PHP & Information Security' );
+-------------------------------------+
| MD5( 'PHP & Information Security' ) |
+-------------------------------------+
| 88dd8f282721af2c704e238e7f338c41    |
+-------------------------------------+
1 row in set (0.01 sec)
Note: Using MySQL's password() function in your own applications isn't recommended - the algorithm used has changed over time and prior to 4.1 was particularly weak.
You may decide to use MySQL to calculate your hash rather than PHP. The example of storing our user's registration details from the previous section then becomes:
/* Store user details */

$sql = 'INSERT INTO user (username, passwordHash) VALUES (?, SHA1(?))';
$result = $db->query($sql, array($_POST['username'], $_POST['password']));

?>

Weaknesses

As a security measure, storing only hashes of passwords in your database will ensure that an attacker's job is made that much more difficult. Let's look at the steps they'll now take in an effort to compromise your system. Assuming that they've managed to access your user database and list of hashes, there's no way that they can then recover the original passwords to your system. Or is there?
The attacker will be able to look at your hashes and immediately know that any accounts with the same password hash must therefore also have the same password. Not such a problem if neither of the account passwords is known - or is it? A common technique employed to recover the original plain text from a hash is cracking, otherwise known as 'brute forcing'. Using this methodology an attacker will generate hashes for numerous potential passwords (either generated randomly or from a source of potential words, for example a dictionary attack). The hashes generated are compared with those in your user database and any matches will reveal the password for the user in question.
Modern computer hardware can generate MD5 and SHA-1 hashes very quickly - in some cases at rates of thousands per second. Hashes can be generated for every word in an entire dictionary (possibly including alpha-numeric variants) well in advance of an attack. Whilst strong passwords and longer pass phrases provide a reasonable level of protection against such attacks, you cannot always guarantee that your users will be well informed about such practices. It's also less than ideal that the same password used on multiple accounts (or multiple systems for that matter) will reveal itself with an identical hash.

Making It Better

Both of these weaknesses in the hashing strategy can be overcome by making a small addition to our hashing algorithm. Before generating the hash we create a random string of characters of a predetermined length, and prepend this string to our plain text password. Provided the string (called a "salt") is of sufficient length - and of course sufficiently random - the resulting hash will almost certainly be different each time we execute the function. Of course we must also store the salt we've used in the database along with our hash but this is generally no more of an issue than extending the width of the field by a few characters.
When we validate a user's login credentials we follow the same process, only this time we use the salt from our database instead of generating a new random one. We add the user supplied password to it, run our hashing algorithm, then compare the result with the hash stored in that user's profile.
define('SALT_LENGTH', 9);

function generateHash($plainText, $salt = null)
{
    if ($salt === null)
    {
        $salt = substr(md5(uniqid(rand(), true)), 0, SALT_LENGTH);
    }
    else
    {
        $salt = substr($salt, 0, SALT_LENGTH);
    }

    return $salt . sha1($salt . $plainText);
}

?>
Note: The function above is limited in that the maximum salt length is 32 characters. You may wish to write your own salt generator to overcome this limit and increase the entropy of the string.
Calling generateHash() with a single argument (the plain text password) will cause a random string to be generated and used for the salt. The resulting string consists of the salt followed by the SHA-1 hash - this is to be stored away in your database. When you're checking a user's login, the situation is slightly different in that you already know the salt you'd like to use. The string stored in your database can be passed to generateHash() as the second argument when generating the hash of a user-supplied password for comparison.
Using a salt overcomes the issue of multiple accounts with the same password revealing themselves with identical hashes in your database. Although two passwords may be the same the salts will almost certainly be different, so the hashes will look nothing alike.
Dictionary attacks with pre-generated lists of hashes will be useless for the same reason - the attacker will now have to recalculate their entire dictionary for every individual account they're attempting to crack.

Summary

We've seen now what hashes are and why you should store them instead of the plain text passwords they represent in your database. The examples above are a starting point and will get you on the right track with using hashes in your PHP applications. A little bit of work now may well mean much less of a headache further down the track!

MySQL 4.1+ using old authentication

When I was working with XAMPP in Ubuntu and asked write PHP script to connect to remote MySQL server which is using PASSWORD hash function to save the password for user, and I found following error.

Warning: mysql_connect() [function.mysql-connect]: Premature end of data (mysqlnd_wireprotocol.c:554) in path/to/the/file/where/connection/script/is/written/

Warning: mysql_connect() [function.mysql-connect]: OK packet 1 bytes shorter than expected in path/to/the/file/where/connection/script/is/written/

Warning: mysql_connect() [function.mysql-connect]: mysqlnd cannot connect to MySQL 4.1+ using the old insecure authentication. Please use an administration tool to reset your password with the command SET PASSWORD = PASSWORD('your_existing_password'). This will store a new, and more secure, hash value in mysql.user. If this user is used in other scripts executed by PHP 5.2 or earlier you might need to remove the old-passwords flag from your my.cnf file in path/to/the/file/where/connection/script/is/written/

As you will see, the core issue here is that MySQL can have passwords with hashes stored in the old 16-character format, which is not supported by PHP 5.3′s new mysqlnd library.
Since I couldn’t find a good solution with a quick Google, here is how I solved this without having to downgrade PHP or MySQL (as some of the solutions suggested):

1. Change MySQL to NOT to use old_passwords
It seems that even MySQL 5.x versions still default to the old password hashes. You need to change this in “my.cnf” (e.g. /etc/my.cnf): remove or comment out the line that says
old_passwords = 1
Restart MySQL. If you don’t, MySQL will keep using the old password format, which will mean that you cannot upgrade the passwords using the builtin PASSWORD() hashing function. You can test this by running:
 
mysql> SELECT Length(PASSWORD('xyz'));
+-------------------------+
| Length(PASSWORD('xyz')) |
+-------------------------+
|                      16 |
+-------------------------+
1 row in set (0.00 sec)

The old password hashes are 16 characters, the new ones are 41 characters.
2. Change the format of all the passwords in the database to the new format
Connect to the database, and run the following query:
mysql> SELECT user,  Length(`Password`) FROM `mysql`.`user`;

This will show you which passwords are in the old format, ex:
+----------+--------------------+
| user     | Length(`Password`) |
+----------+--------------------+
| root     |                 41 |
| root     |                 16 |
| user2    |                 16 |
| user2    |                 16 |
+----------+--------------------+
Notice here that each user can have multiple rows (one for each different host specification).
To update the password for each user, run the following:
UPDATE mysql.user SET Password = PASSWORD('password') WHERE user = 'username';
Finally, flush privileges:
FLUSH PRIVILEGES;
 

Indian currency format

function indianCurrencyFormat($num){
 $pos = strpos((string)$num, ".");
 if ($pos === false) {
 $decimalpart="00";
 }
 if (!($pos === false)) {
 $decimalpart= substr($num, $pos+1, 2); $num = substr($num,0,$pos);
 }

 if(strlen($num)>3 & strlen($num) <= 12){
 $last3digits = substr($num, -3 );
 $numexceptlastdigits = substr($num, 0, -3 );
 $formatted = makeComma($numexceptlastdigits);
 $stringtoreturn = $formatted.",".$last3digits.".".$decimalpart ;
 }elseif(strlen($num)<=3){
 $stringtoreturn = $num.".".$decimalpart ;
 }elseif(strlen($num)>12){
 $stringtoreturn = number_format($num, 2);
 }

 if(substr($stringtoreturn,0,2)=="-,"){
 $stringtoreturn = "-".substr($stringtoreturn,2 );
 }

 return $stringtoreturn;
 }

 function makeComma($input){
 // This function is written by some anonymous person - I got it from Google
 if(strlen($input)<=2)
 { return $input; }
 $length=substr($input,0,strlen($input)-2);
 $formatted_input = makeComma($length).",".substr($input,-2);
 return $formatted_input;
 }
 
echo indianCurrencyFormat(2313432.23);
//o/p 23,13,432.23 

PHP stands 5th (tells TIOBE Programming community)

The TIOBE Programming Community index gives an indication of the popularity of programming languages. The index is updated once a month. The ratings are based on the number of skilled engineers world-wide, courses and third party vendors. The popular search engines Google, MSN, Yahoo!, Wikipedia and YouTube are used to calculate the ratings. Observe that the TIOBE index is not about the best programming language or the language in which most lines of code have been written.

The index can be used to check whether your programming skills are still up to date or to make a strategic decision about what programming language should be adopted when starting to build a new software system. The definition of the TIOBE index can be found here.

Position
Oct 2013
Position
Oct 2012
Delta in PositionProgramming LanguageRatings
Oct 2013
Delta
Oct 2012
Status
1 1 C 17.246% -2.58%   A
2 2 Java 16.107% -1.09%   A
3 3 Objective-C 8.992% -0.49%   A
4 4 C++ 8.664% -0.60%   A
5 6 PHP 6.094% +0.43%   A
6 5 C# 5.718% -0.81%   A
7 7 (Visual) Basic 4.819% -0.30%   A
8 8 Python 3.107% -0.79%   A
9 23 Transact-SQL 2.621% +2.13%   A
10 11 JavaScript 2.038% +0.78%   A
11 18 Visual Basic .NET 1.933% +1.33%   A
12 9 Perl 1.607% -0.52%   A
13 10 Ruby 1.246% -0.56%   A
14 14 Pascal 0.753% -0.09%   A
15 17 PL/SQL 0.730% +0.10%   A
16 13 Lisp 0.725% -0.22%   A
17 12 Delphi/Object Pascal 0.701% -0.40%   A
18 53 Groovy 0.658% +0.53%   B
19 19 MATLAB 0.614% +0.02%   B
20 26 COBOL 0.599% +0.15%   B
Go to original article