PHP Twitter Application tutorial

Creating Twitter Apps in PHP

In this post we will look into accessing Twitter REST API in PHP. This can be useful if you need to post Tweets from your PHP application or anaylze, search Tweets. In the following examples we will use the twitter-api-php PHP wrapper for Twitter v1.1 API. Although there are a few wrappers around, this one I like for its simplicity.

Installation

If you use composer, here’s what you need to add to your composer.json file to have TwitterAPIExchange.php (Twitter PHP wrapper) automatically imported into your vendor’s folder:

{
    "require": {
        "j7mbo/twitter-api-php": "dev-master"
    }
}

You’ll then need to run ‘composer install’.

If you don’t use composer, just download the zip from git and include TwitterAPIExchange.php in your application path.

Registering your Twitter app

Before writing any code, you will first need to create a Twitter app and register it onhttps://apps.twitter.com/. You will be greeted with the following screen. (The following screenshot shows you an existing app. If this is your first app than the page will be blank).

twitter-app-1

Click on the ‘Create New App’ button and enter the required details in the fields provided. Leave the ‘Callback URL’ field blank for now. Once the app is created, click on the app name and note down the various access and security tokens, we will be needing these later. Change your Access Level to ‘Read and Write’. ‘Read Only’ access does not allow you to update, add or delete Tweets. If your purpose is to only read tweet data, it is safer to set the Access Level to ‘Read Only’.

Note that you will need to regenerate the access tokens if you change the Access Levels anytime and modify the same in your PHP code.

twitter-app-2

Accessing the Twitter API from PHP

Now that you have created and registered a Twitter app, we can now use PHP to acccess the API. First include the ‘TwitterAPIExchange.php’ class and set various security tokens collected earlier.

require_once('TwitterAPIExchange.php');
 
$settings = array(
    'oauth_access_token' => "YOUR_ACCESS_TOKEN",
    'oauth_access_token_secret' => "YOUR_ACCESS_TOKEN_SECRET",
    'consumer_key' => "YOUR_CONSUMER_KEY",
    'consumer_secret' => "YOUR_CONSUMER_SECRET"
);

For this example we will be using the ‘https://api.twitter.com/1.1/statuses/user_timeline.json‘ resource url. This returns a collection of the most recent Tweets posted by the user indicated by the screen_name or user_id parameters. This particular method is one of the dozens of various methods available to access and modify Twitter data; others can be found here.

A complete GET request method is shown below. Here we are requesting the recent 3 tweets for the user ‘johndoe123’.

$url = "https://api.twitter.com/1.1/statuses/user_timeline.json";
$requestMethod = "GET";
$getfield = '?screen_name=johndoe123&count=3';

Once we specify the request methods and fields, we can call Twitter.

$twitter = new TwitterAPIExchange($settings);
 
$response = $twitter->setGetfield($getfield)
                    ->buildOauth($url, $requestMethod)
                    ->performRequest();

The complete code is shown below.

<?php
 
require_once('TwitterAPIExchange.php');
 
$settings = array(
    'oauth_access_token' => "YOUR_ACCESS_TOKEN",
    'oauth_access_token_secret' => "YOUR_ACCESS_TOKEN_SECRET",
    'consumer_key' => "YOUR_CONSUMER_KEY",
    'consumer_secret' => "YOUR_CONSUMER_SECRET"
);
 
$url = "https://api.twitter.com/1.1/statuses/user_timeline.json";
$requestMethod = "GET";
$getfield = '?screen_name=johndoe123&count=3';
 
$twitter = new TwitterAPIExchange($settings);
 
$response = $twitter->setGetfield($getfield)
                    ->buildOauth($url, $requestMethod)
                    ->performRequest();
 
print_r($response);

Executing the above code will return the recent 3 tweets for the given user in JSON format. You can specify the number of tweets to return using the ‘count parameter. The maximum that can be returned is 200.

$getfield = '?screen_name=johndoe123&count=3';

Note that all GET fields for this method are optional. Not specifying any GET parameters will return 20 recent tweets for the current user, i.e the user with the given access tokens. You can query without the GET parameters as shown below.

$url = "https://api.twitter.com/1.1/statuses/user_timeline.json";
$requestMethod = "GET";
 
$twitter = new TwitterAPIExchange($settings);
 
$response = $twitter->buildOauth($url, $requestMethod)
                    ->performRequest();
 
print_r($response);

Also, the response is returned in JSON, so will need to decode the JSON first before working further.

$tweets = json_decode($response);
print_r($tweets);

The tweet is stored in the ‘text’ field of the response, so we can enumerate all returned tweets with the following. Various other fields can be accessed in similiar manner.

$tweets = json_decode($response);
 
foreach($tweets as $tweet)
{
    echo $tweet->text . PHP_EOL;
}

Posting a new Tweet

Posting a new Tweet can be done with the following code, which uses a POST method instead of a GET. The initial code remains the same.

<?php
 
$url = "https://api.twitter.com/1.1/statuses/update.json";
 
$requestMethod = 'POST'; 
 
$postfields = array(
    'status' => 'Testing Twitter app'
);
 
$twitter = new TwitterAPIExchange($settings);
 
$response = $twitter->buildOauth($url, $requestMethod)
                   ->setPostfields($postfields)
                   ->performRequest();
 
print_r($response);

There are additoinal parameter you can use, the details for which are given here.

Searching for Tweets

Searching for Tweets based on a query is as easy as the above examples. Here in the following example we query for the ‘laravel’ keyword and ask o return 10 statuses.

$url = "https://api.twitter.com/1.1/search/tweets.json";
 
$requestMethod = "GET";
 
$getfield = '?q=laravel&count=10';
 
$twitter = new TwitterAPIExchange($settings);
$response = $twitter->setGetfield($getfield)
                    ->buildOauth($url, $requestMethod)
                    ->performRequest();
 
$tweets = json_decode($response);
 
foreach($tweets->statuses as $tweet)
{
    echo $tweet->text . PHP_EOL;
}

API rate limits

One important point to consider when creating your app is of rate limiting. Twitter limits the rate at which you query using their API. For example search will be rate limited at 180 queries per 15 minute window. More information can be found here.

Important Note

If the above examples do not work you will have to make a small change in ‘TwitterAPIExchange.php’. The curl processing part (around line 192) requires the line ‘CURLOPT_SSL_VERIFYPEER => false,’ to be added. So the curl part in the file should read the following.

        $options = array( 
            CURLOPT_HTTPHEADER => $header,
            CURLOPT_HEADER => false,
            CURLOPT_URL => $this->url,
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_TIMEOUT => 10,
        );

 

Advertisements
Nginx, ubuntu, linux, apache, php, mysql

How To Install Linux, nginx, MySQL, PHP (LEMP) stack on Ubuntu 12.04

About Lemp

LEMP stack is a group of open source software to get web servers up and running. The acronym stands for Linux, nginx (pronounced Engine x), MySQL, and PHP. Since the server is already running Ubuntu, the linux part is taken care of. Here is how to install the rest.

Tutorial source – Digital Ocean

Setup

The steps in this tutorial require the user to have root privileges. You can see how to set that up in the Initial Server Setup Tutorial in steps 3 and 4.

Step One—Update Apt-Get

Throughout this tutorial we will be using apt-get as an installer for all the server programs. On May 8th, 2012, a serious php vulnerability was discovered, and it is important that we download all of the latest patched software to protect the virtual private server.

Let’s do a thorough update.

sudo apt-get update

Step Two—Install MySQL

MySQL is a powerful database management system used for organizing and retrieving data

To install MySQL, open terminal and type in these commands:

sudo apt-get install mysql-server php5-mysql

During the installation, MySQL will ask you to set a root password. If you miss the chance to set the password while the program is installing, it is very easy to set the password later from within the MySQL shell.

Once you have installed MySQL, we should activate it with this command:

sudo mysql_install_db

Finish up by running the MySQL set up script:

sudo /usr/bin/mysql_secure_installation

The prompt will ask you for your current root password.

Type it in.

Enter current password for root (enter for none): 
OK, successfully used password, moving on...

Then the prompt will ask you if you want to change the root password. Go ahead and choose N and move on to the next steps.

It’s easiest just to say Yes to all the options. At the end, MySQL will reload and implement the new changes.

By default, a MySQL installation has an anonymous user, allowing anyone
to log into MySQL without having to have a user account created for
them.  This is intended only for testing, and to make the installation
go a bit smoother.  You should remove them before moving into a
production environment.

Remove anonymous users? [Y/n] y                                            
 ... Success!

Normally, root should only be allowed to connect from 'localhost'.  This
ensures that someone cannot guess at the root password from the network.

Disallow root login remotely? [Y/n] y
... Success!

By default, MySQL comes with a database named 'test' that anyone can
access.  This is also intended only for testing, and should be removed
before moving into a production environment.

Remove test database and access to it? [Y/n] y
 - Dropping test database...
 ... Success!
 - Removing privileges on test database...
 ... Success!

Reloading the privilege tables will ensure that all changes made so far
will take effect immediately.

Reload privilege tables now? [Y/n] y
 ... Success!

Cleaning up...

Once you’re done with that you can finish up by installing PHP.

Step Three—Install nginx

Once MySQL is all set up, we can move on to installing nginx on the VPS.

echo "deb http://ppa.launchpad.net/nginx/stable/ubuntu $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/nginx-stable.list
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys C300EE8C
sudo apt-get update
sudo apt-get install nginx

nginx does not start on its own. To get nginx running, type:

sudo service nginx start

You can confirm that nginx has installed an your web server by directing your browser to your IP address.

You can run the following command to reveal your VPS’s IP address.

ifconfig eth0 | grep inet | awk '{ print $2 }'

Step Four—Install PHP

To install PHP-FPM, open terminal and type in these commands. We will configure the details of nginx and php details in the next step:

sudo apt-get install php5-fpm

Step Five—Configure php

We need to make one small change in the php configuration.Open up php.ini:

 sudo nano /etc/php5/fpm/php.ini

Find the line, cgi.fix_pathinfo=1, and change the 1 to 0.

cgi.fix_pathinfo=0

If this number is kept as 1, the php interpreter will do its best to process the file that is as near to the requested file as possible. This is a possible security risk. If this number is set to 0, conversely, the interpreter will only process the exact file path—a much safer alternative. Save and Exit. We need to make another small change in the php5-fpm configuration.Open up http://www.conf:

 sudo nano /etc/php5/fpm/pool.d/www.conf

Find the line, listen = 127.0.0.1:9000, and change the 127.0.0.1:9000 to /var/run/php5-fpm.sock.

listen = /var/run/php5-fpm.sock

Save and Exit.

Restart php-fpm:

sudo service php5-fpm restart

Step Six—Configure nginx

Open up the default virtual host file.

sudo nano /etc/nginx/sites-available/default

The configuration should include the changes below (the details of the changes are under the config information):

UPDATE: Newer Ubuntu versions create a directory called ‘html’ instead of ‘www’ by default. If /usr/share/nginx/www does not exist, it’s probably called html. Make sure you update your configuration appropriately.

 [...]
server {
        listen   80;
     

        root /usr/share/nginx/www;
        index index.php index.html index.htm;

        server_name example.com;

        location / {
                try_files $uri $uri/ /index.html;
        }

        error_page 404 /404.html;

        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
              root /usr/share/nginx/www;
        }

        # pass the PHP scripts to FastCGI server listening on the php-fpm socket
        location ~ \.php$ {
                try_files $uri =404;
                fastcgi_pass unix:/var/run/php5-fpm.sock;
                fastcgi_index index.php;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                include fastcgi_params;
                
        }

}
[...]

Here are the details of the changes:

  • Add index.php to the index line.
  • Change the server_name from local host to your domain name or IP address (replace the example.com in the configuration)
  • Change the correct lines in “location ~ \.php$ {“ section

Save and Exit

Step Seven—Create a php Info Page

We can quickly see all of the details of the new php configuration.

To set this up, first create a new file:

sudo nano /usr/share/nginx/www/info.php

Add in the following line:

<?php
phpinfo();
?>

Then Save and Exit.

Restart nginx

sudo service nginx restart

You can see the nginx and php-fpm configuration details by visiting http://youripaddress/info.php

Your LEMP stack is now set up and configured on your virtual private server.

TimeAgo function in PHP

This can be used for comments and other from of communication to tell the time ago instead of the exact time which might not be correct to some one in another time zone.

The function only uses unix time stamp like the result of time();

function timeago($time) {
        $time = strtotime($time);
        $periods = array(L('second'), L('minute'), L('hour'), L('day'), L('week'), L('month'), L('year'), L('decade'));
        $periodsPlural = array(L('seconds'), L('minutes'), L('hours'), L('days'), L('weeks'), L('months'), L('years'), L('decades'));
        $lengths = array("60","60","24","7","4.35","12","10");

        $now = time();

        $difference     = $now - $time;
        $tense         = L('ago');

        for($j = 0; $difference >= $lengths[$j] && $j < count($lengths)-1; $j++)
        {
            $difference /= $lengths[$j];
        }

        $difference = round($difference);

        if($difference != 1)
        {
            return "$difference $periodsPlural[$j] $tense";
        } else {
            return "$difference $periods[$j] $tense";
        }
    }

Needs a time() value, and it will tell you how many seconds/minutes/hours/days/years/decades ago.

PHP Dynamic page

How to create dynamic pages with php

This tutorial will show you how to create dynamic pages with php. As you know php is the best language to create dynamic website and today we are going to see how it’s done.

Step 1: Create files

First we need few separate pages so let’s go ahead and create few pages. First page we need is index.php that will be our main page, so create a page and name it index.php. After that we need to add some HTML to the page.

<html>
<head>
<title>My PHP Site</title>
</head>
<body>
<h1>Welcome to my PHP Site.</h1>
 <ul>
 <li>Products</li>
 <li>Blog</li>
 <li>About Us</li>
</ul>
</body>
</html>

This is going to be our main page that’s why we are putting our navigation here, it doesn’t look fancy because our main focus is PHP right now.

Add Links:

Now we need to add links to our navigation. As we have three items in our navigation so we will need three more pages for our website but first let’s add some links to our navigation items.

<ul>
 <li><a href="#">Products</a></li>
 <li><a href="#">Blog</a></li>
 <li><a href="#">About Us</a></li>
</ul>

For now we will not specify any path in our links, we will get back to it later. Now if you have done everything alright you will get a page like this:

Dynamic PHP pages

PHP Dynamic Page

Other pages:

Now that we are done with our main page, we want to create few other pages. So just create three pages and name them products.php , blog.php and about.php. After that we want to put some content in these pages, we don’t have to put all those HTML tags again. We will just have to put the content that we want to show on the website, so for product’s page put the following lines in the page.

<?php
echo "<h2>Products</h2>";
echo "This is our product page.<br/>";
echo "You should be able to see all of our products here.";
?>

Do same for other two pages. You can put in there whatever you like, just keep in mind one thing that you won’t have to put <html> tags again.

Step 2: Making Pages Dynamic

As we are done with our main page and we have created other pages, now its turn to make those pages dynamic. We will just have to change the url to get the requested page and after that use GET variable to catch the value and assign it to another variable. Then we can just print that variable and we will get all the content from other pages on our main page.

Add this php code on top of your main page:

<?php
 if(isset($_GET['page'])){
 $page = $_GET['page'];
 }
 else
 $page = NULL;
 ?>

So basically what we have done here is, we have checked if the value in GET is set or not and if it is set we have assigned the value in GET to page variable and if it is not set we have set page variable equal to NULL.
Secondly we need to add some code to our main page where we want to show the content of other pages. As we need to show the content of other pages after our navigation so put these line after closing ul tag.

<?php
 if(empty($page)){
 echo "This is our main page.";
 }
 else
 include($page);
 ?>

Here we are checking if the page variable is empty then show the content of main page and if the page variable is not empty then we will include page variable. Basically the page variable contains our page which we want to show on our main page, don’t worry it will all make sense in a minute.

Changing Links:

After our main page is all set the last thing we need to do is to change our link in the main page. So just make these changes in the links of main page.

<ul>
 <li><a href="index.php?page=products.php">Products</a></li>
 <li><a href="index.php?page=blog.php">Blog</a></li>
 <li><a href="index.php?page=about.php">About</a></li>
 </ul>

As you can see all these pages are referring to the index.php but here our concern is the part after the index.php that is the part after ?. After ? we are using a variable or you can say reference name ‘page’, you can use any name here but you will have to change the GET variable too. We are taking page equal to our required page.

After it’s all set you can try it and hopefully it will work.

Image Not Available

PHP Dynamic Page

Image Not Available

PHP Dynamic Page

Image Not Available

PHP Dynamic Page

Step 3: Improving Links

You can take it one step farther by modifying the code little bit and making your link more attractive instead of index.php?page=about.php. So what you need to do is add a line right after where you are assigning GET variable value to page in index page.

<?php
 if(isset($_GET['page'])){
 $page = $_GET['page'];
 $page .= '.php';  //Add this line here and you are all set.
 }
 else
 $page = NULL;
 ?>

Now last thing you want to do is to remove the .php extension from all the links and after that our links will become:

<ul>
 <li><a href="index.php?page=products">Products</a></li>
 <li><a href="index.php?page=blog">Blog</a></li>
 <li><a href="index.php?page=about">About</a></li>
 </ul>

Now when you will browse to any of these links it will not show .php and your link will look more lively like index.php?page=about. We are done and now you can play a little bit more if you want with your pages. Go ahead and try this and leave a comment if you get stuck anywhere or want to share something new.

Some handy Regular Expressions you should know

Background Info on Regular Expressions

This is what Wikipedia has to say about them:

In computing, regular expressions provide a concise and flexible means for identifying strings of text of interest, such as particular characters, words, or patterns of characters. Regular expressions (abbreviated as regex or regexp, with plural forms regexes, regexps, or regexen) are written in a formal language that can be interpreted by a regular expression processor, a program that either serves as a parser generator or examines text and identifies parts that match the provided specification.

Now, that doesn’t really tell me much about the actual patterns. The regexes I’ll be going over today contains characters such as \w, \s, \1, and many others that represent something totally different from what they look like.

If you’d like to learn a little about regular expressions before you continue reading this article, I’d suggest watching the Regular Expressions for Dummies screencast series.

The eight regular expressions we’ll be going over today will allow you to match a(n): username, password, email, hex value (like #fff or #000), slug, URL, IP address, and an HTML tag. As the list goes down, the regular expressions get more and more confusing. The pictures for each regex in the beginning are easy to follow, but the last four are more easily understood by reading the explanation.

The key thing to remember about regular expressions is that they are almost read forwards and backwards at the same time. This sentence will make more sense when we talk about matching HTML tags.

Note: The delimiters used in the regular expressions are forward slashes, “/”. Each pattern begins and ends with a delimiter. If a forward slash appears in a regex, we must escape it with a backslash: “\/”.


1. Matching a Username

Matching a username

Pattern:

  1. /^[a-z0-9_-]{3,16}$/

Description:

We begin by telling the parser to find the beginning of the string (^), followed by any lowercase letter (a-z), number (0-9), an underscore, or a hyphen. Next, {3,16} makes sure that are at least 3 of those characters, but no more than 16. Finally, we want the end of the string ($).

String that matches:

my-us3r_n4m3

String that doesn’t match:

th1s1s-wayt00_l0ngt0beausername (too long)


2. Matching a Password

Matching a password

Pattern:

  1. /^[a-z0-9_-]{6,18}$/

Description:

Matching a password is very similar to matching a username. The only difference is that instead of 3 to 16 letters, numbers, underscores, or hyphens, we want 6 to 18 of them ({6,18}).

String that matches:

myp4ssw0rd

String that doesn’t match:

mypa$$w0rd (contains a dollar sign)


3. Matching a Hex Value

Matching a hex valud

Pattern:

  1. /^#?([a-f0-9]{6}|[a-f0-9]{3})$/

Description:

We begin by telling the parser to find the beginning of the string (^). Next, a number sign is optional because it is followed a question mark. The question mark tells the parser that the preceding character — in this case a number sign — is optional, but to be “greedy” and capture it if it’s there. Next, inside the first group (first group of parentheses), we can have two different situations. The first is any lowercase letter between a and f or a number six times. The vertical bar tells us that we can also have three lowercase letters between a and f or numbers instead. Finally, we want the end of the string ($).

The reason that I put the six character before is that parser will capture a hex value like #ffffff. If I had reversed it so that the three characters came first, the parser would only pick up #fff and not the other three f’s.

String that matches:

#a3c113

String that doesn’t match:

#4d82h4 (contains the letter h)


4. Matching a Slug

Matching a slug

Pattern:

  1. /^[a-z0-9-]+$/

Description:

You will be using this regex if you ever have to work with mod_rewrite and pretty URL’s. We begin by telling the parser to find the beginning of the string (^), followed by one or more (the plus sign) letters, numbers, or hyphens. Finally, we want the end of the string ($).

String that matches:

my-title-here

String that doesn’t match:

my_title_here (contains underscores)


5. Matching an Email

Matching an email

Pattern:

  1. /^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/

Description:

We begin by telling the parser to find the beginning of the string (^). Inside the first group, we match one or more lowercase letters, numbers, underscores, dots, or hyphens. I have escaped the dot because a non-escaped dot means any character. Directly after that, there must be an at sign. Next is the domain name which must be: one or more lowercase letters, numbers, underscores, dots, or hyphens. Then another (escaped) dot, with the extension being two to six letters or dots. I have 2 to 6 because of the country specific TLD’s (.ny.us or .co.uk). Finally, we want the end of the string ($).

String that matches:

john@doe.com

String that doesn’t match:

john@doe.something (TLD is too long)


6. Matching a URL

Matching a url

Pattern:

  1. /^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/

Description:

This regex is almost like taking the ending part of the above regex, slapping it between “http://” and some file structure at the end. It sounds a lot simpler than it really is. To start off, we search for the beginning of the line with the caret.

The first capturing group is all option. It allows the URL to begin with “http://”, “https://”, or neither of them. I have a question mark after the s to allow URL’s that have http or https. In order to make this entire group optional, I just added a question mark to the end of it.

Next is the domain name: one or more numbers, letters, dots, or hypens followed by another dot then two to six letters or dots. The following section is the optional files and directories. Inside the group, we want to match any number of forward slashes, letters, numbers, underscores, spaces, dots, or hyphens. Then we say that this group can be matched as many times as we want. Pretty much this allows multiple directories to be matched along with a file at the end. I have used the star instead of the question mark because the star says zero or more, not zero or one. If a question mark was to be used there, only one file/directory would be able to be matched.

Then a trailing slash is matched, but it can be optional. Finally we end with the end of the line.

String that matches:

http://net.tutsplus.com/about

String that doesn’t match:

http://google.com/some/file!.html (contains an exclamation point)


7. Matching an IP Address

Matching an IP address

Pattern:

  1. /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/

Description:

Now, I’m not going to lie, I didn’t write this regex; I got it from here. Now, that doesn’t mean that I can’t rip it apart character for character.

The first capture group really isn’t a captured group because

  1. ?:

was placed inside which tells the parser to not capture this group (more on this in the last regex). We also want this non-captured group to be repeated three times — the {3} at the end of the group. This group contains another group, a subgroup, and a literal dot. The parser looks for a match in the subgroup then a dot to move on.

The subgroup is also another non-capture group. It’s just a bunch of character sets (things inside brackets): the string “25″ followed by a number between 0 and 5; or the string “2″ and a number between 0 and 4 and any number; or an optional zero or one followed by two numbers, with the second being optional.

After we match three of those, it’s onto the next non-capturing group. This one wants: the string “25″ followed by a number between 0 and 5; or the string “2″ with a number between 0 and 4 and another number at the end; or an optional zero or one followed by two numbers, with the second being optional.

We end this confusing regex with the end of the string.

String that matches:

73.60.124.136 (no, that is not my IP address :P)

String that doesn’t match:

256.60.124.136 (the first group must be “25″ and a number between zero and five)


8. Matching an HTML Tag

Matching an HTML tag

Pattern:

  1. /^<([a-z]+)([^<]+)*(?:>(.*)<\/\1>|\s+\/>)$/

Description:

One of the more useful regexes on the list. It matches any HTML tag with the content inside. As usually, we begin with the start of the line.

First comes the tag’s name. It must be one or more letters long. This is the first capture group, it comes in handy when we have to grab the closing tag. The next thing are the tag’s attributes. This is any character but a greater than sign (>). Since this is optional, but I want to match more than one character, the star is used. The plus sign makes up the attribute and value, and the star says as many attributes as you want.

Next comes the third non-capture group. Inside, it will contain either a greater than sign, some content, and a closing tag; or some spaces, a forward slash, and a greater than sign. The first option looks for a greater than sign followed by any number of characters, and the closing tag. \1 is used which represents the content that was captured in the first capturing group. In this case it was the tag’s name. Now, if that couldn’t be matched we want to look for a self closing tag (like an img, br, or hr tag). This needs to have one or more spaces followed by “/>”.

The regex is ended with the end of the line.

 

Source: nettutplus.com

Password Hashing and Encryption In PHP; MD5, SHA1, SHA256, BCrypt

Password encryption and hashing in PHP, MD5, SHA1, SHA256, SHA512, bCrypt

Most modern PHP applications access important user information and store them in a database. For example, web app might have a registration system for new users. But how should you store usernames and passwords in the database?

You must always think about security. If passwords are stored in plain text, what happens if an attacker gains access to your database? He can easily read all of the users’ passwords. That’s why we use a technique called password hashing to prevent attackers from getting user passwords.

In this article you’ll learn how to store the passwords securely in the database so that, even if your database falls into wrong hands, no damage will be done.

What Is Password Hashing

Hashing is not a new concept. It has been in practical use for quite a long time. To understand hashing, think about fingerprints. Every person has a unique fingerprint. Similarly, each string can have a unique fixed-size “digital fingerprint” called a hash. For a good hashing algorithm, it’s very rare that two different strings will have same hash (called a collision).

The most important feature of hashes is that the hash generation process is one way. The one way property indicates that it’s impossible to recover the original text from its hash. Therefore password hashing perfectly suits our need for secure password storage. Instead of storing a password in plain text, we can hash the password and store the resulting hash. If an attacker later gains access to the database, he can’t recover original password from the hash.

But what about authentication? You can no longer compare the password entered by user in a login form with the hash stored in the database. You need to hash the login password and compare the result with the hash stored in the database.

How Hashing Is Done In PHP

There are different algorithms for generating hash of a text. The most popular ones are: MD5, SHA1, and Bcrypt. Each of these algorithms are supported in PHP. You really should be using Bcrypt, but I’ll present the other alternatives first because they help illustrate what you need to do to protect your passwords.

Let’s start with PHP’s md5() function which can hash passwords according to the MD5 hashing algorithm. The following example demonstrates the registration process:


<?php
$username = $_POST["username"];
$password = $_POST["password"];

// create connection to database
// ...

// sanitize the inputs
// ...

// create an MD5 hash of the password
$password = md5($password);

// save the values to the database
$sql = "INSERT INTO users (username, password) VALUES (:username, :password)";

$stmt = $db->prepare($sql);

$stmt->execute(array(
    ":username" => $username,
    ":password" => $password
));

And the following example shows the authentication process:


<?php
$username = $_POST["username"];
$password = $_POST["password"];

// create connection to database
// ...

// sanitize the input
// ...

// create an MD5 hash of the password
$password = md5($password);

// retrieve the information from the database
$sql = "SELECT * FROM users WHERE username=:username AND password=:password";
$stmt = $db->prepare($sql);
$stmt->execute(array(
    ":username" => $username,
    ":password" => $password
));

$row = $stmt->fetch();

In the above example, md5() creates a 128-bit hash out of the given password. It’s also possible to use sha1() instead of md5() which produces a 160-bit hash (which means there’s less chance of a collision).

If you generate an MD5 hash of the string “MySecretPassword” and output it to the browser, it will look like the following:

7315a012ecad1059a3634f8be1347846

“MySecretPassword” when hashed with SHA1 will produce the following output:

952729c61cab7e01e4b5f5ba7b95830d2075f74b

Never hash a password two times. It does not add extra security; rather, it makes the hash weak and inefficient. For example, don’t try to create an MD5 hash of a password and then provide it as input to sha1(). It simply increases the probability of hash collisions.

Taking Password Hashing to the Next Level

Researchers have found several flaws in the SHA1 and MD5 algorithms. That’s why modern PHP applications shouldn’t use these two hash functions. Rather, they should use hash algorithms from the SHA2 family like SHA256 or SHA512. As the name suggest, they produce hashes of length 256 and 512 bits. They are newer and considerably stronger than MD5. As the number of bits increase, the probability of a collision decreases. Either of the above two is more than sufficient to keep your application secure.

The following code shows how to use SHA256 hashing in PHP:


<?php
$password = hash("sha256", $password);

PHP offers the built-in function hash(). The first argument to the function is the algorithm name (you can pass algorithm names like sha256, sha512, md5, sha1, and many others). The second argument is the string that will be hashed. The result it returns is the hashed string.

Paranoia is Good – Using Salts for Added Security

Being paranoid about the security of your system is good. So, let’s consider another case here. You have hashed the user’s password and stored it in the database table. Even if an attacker gets access to our database, he won’t be able to determine the original password. But what if he checks all the password hashes with one another and finds some of them to be same? What does this indicate?

We already know two strings will have same hash only if both of them are same (in the absence of any collisions). So if the attacker sees same hashes, he can infer that the passwords for those accounts are same. If he already knows the password to one those accounts, then he can simply use that and gain access to all of the accounts with the same password.

The solution is to use a random number while generating the hash, referred to as salt. Each time we generate hash of a password, we use a random salt. You just need to generate a random number of a particular length and append it to the plain text password, and then hash it. In this way, even if passwords for two accounts are same, the generated hashes will not be same because the salts used in both cases are different.

The following demonstrates the use of salt:


<?php
define("MAX_LENGTH", 6);

function generateHashWithSalt($password) {
    $intermediateSalt = md5(uniqid(rand(), true));
    $salt = substr($intermediateSalt, 0, MAX_LENGTH);
    return hash("sha256", $password . $salt);
}

To create a salt we use the uniqid() function. The first argument is rand() which generates a random integer. The second argument is true to increase the chance of the generated number being unique.

To authenticate the user, you must store the salt used for hashing the password (It’s possible to store the salt in another column in same table where you have username and password stored). When the user tries to login, append the salt to the entered password and then hash it with the hash function.

Going Even Further: Using BCrypt

Learning about MD5/SHA1 and salts are good to gain an understanding of what’s needed for secure storage. But for implementing a serious security plan, Bcrypt is the hashing technique you should be using.

Bcrypt is based on the Blowfish symmetric block cipher. Ideally, we want a hashing algorithm to work very slowly for an attacker’s automated cracking attempts but not too slow that we can’t use it in real world applications. With Bcrypt, we can make the algorithm work n times slower while adjusting n in such a way that it won’t exceed our resources. Also, if you use Bcrypt then there is no need to store your salts in the database.

Let’s have a look at an example that uses the crypt() function to hash the password:


<?php
function generateHash($password) {
    if (defined("CRYPT_BLOWFISH") && CRYPT_BLOWFISH) {
        $salt = '$2y$11$' . substr(md5(uniqid(rand(), true)), 0, 22);
        return crypt($password, $salt);
    }
}

The above function checks whether the Blowfish cipher is available through the CRYPT_BLOWFISH constant. If so, then we generate a random salt. The requirement is that the salt starts with “$2a$” (or “$2y$” see this notice on php.net) to indicate the algorithm is Blowfish, followed by a two digit number from 4 to 31. This number is a cost parameter that makes brute force attacks take longer. Then we append an alphanumeric string containing 22 characters as the main portion of our salt. The alphanumeric string can also include ‘.’ and ‘/’.

Now it’s time to authenticate users:


<?php
function verify($password, $hashedPassword) {
    return crypt($password, $hashedPassword) == $hashedPassword;
}

Notice that we don’t need the salt for the password when authenticating because its part of the hashed output.

For more information on Bcrypt, and why should be using it, see Callum Hopkin’s article Why You Should Use Bcrypt to Hash Stored Passwords.

Summary

An important security measure to follow is always hash your users’ passwords before storing them in your database, and use modern hashing algorithms like Bcrypt, sha256, or sha512 to do so. When you do, even if an attacker gains access to your database, he won’t have the actual passwords of your users. This article explains the principles behind hashing, salts, and Bcrypt.

Article courtesy: Sandeep, PHPMaster.com

PHP (Database) Dependency Injection

PHP (Database) Dependency Injection

Dependency injection is the answer to more maintainable, testable, modular code.

Every project has dependencies and the more complex the project is the more dependencies it will most likely have.  The most common dependency in today’s web application is the database and chances are if it goes down the application will all together stop working.  That is because the code is dependent on the database server, which is perfectly fine.  Not using a database server because it could one day crash is a bit ridiculous.  Even though the dependency has its flaws, it still makes life for the code, and thus the developer, a lot easier.

The problem with most dependencies is the way that code handles and interacts with them. What I really mean is the problem is in the code and not the dependency.  If you are not using dependency injection, chances are your code looks something like this:

class Book {

	public function __construct() {

		$registry  = RegistrySingleton::getInstance();
		$this->_database = $registry->database;

		// or

		global $databaseConnection;
		$this->_database = $database;
	}

}

The book object now is given full access to the database once it is constructed.  That is good, the book needs to be able to talk to the database and pull data.  The problem lies in the way the book gained its access.  In order for the book to be able to talk to the database the code must have an outside variable named $database, or worse, it must have a singleton pattern class (registry) object containing a record for a database connection.  If neither of these exist the book fails, making the code far from modular.

This raises the question, how exactly does the book get access to the database?  This is where inversion of control comes in.

In Hollywood a struggling actor does not call up a director and ask for a role in his next film.  No, the opposite happens.  The director calls up the actor and asks him to play the main character in his next movie.  Objects are struggling actors, they do not get to pick the roles they play, the director needs to tell them what to do.  Objects do not get to pick the outside systems they interact with, instead, the outside systems are given to the objects.  Remember this as Inversion of Control.

This is how a developer tells his objects how to interact with outside dependencies:

class Book {

	private $_databaseConnection;

	public function __construct() { }

	public function setDatabaseConnection($databaseConnection) {
		$this->_databaseConnection = $databaseConnection;
	}

}
$book = new Book();
$book->setDatabase($databaseConnection);

This code allows for the book class to be used in any web application.  The Book is no longer dependent on anything other than the developer supplying a database shortly after object creation.

This is, at its finest, dependency injection.  There are two common ways of injecting dependencies.  The first being constructor injection and the second being setter injection.  Constructor injection involves passing all of the dependencies as arguments when creating a new object.  The code would look something like this:

$book = new Book($databaseConnection, $configFile);

There are some issues with constructor injection. First, the more dependencies a class has the messier the constructor becomes. Passing in three or four dependencies all in a constructor is extremely hard to read. Also, the less work a constructor does the better.

This leaves us with our second method of dependency injection, setter injection. A dependency is set by using a public method inside the class.

$book = new Book();
$book->setDatabase($databaseConnection);
$book->setConfigFile($configFile);

This is easy to follow, but it leads writing more and more code for your application.  When a book object is created three lines of code are required.  If we have to inject another dependency, a 4th line of code is now needed.  This gets messy quickly.

The answer to this problem is a container, which is class that is designed to hold, create, and inject all the dependencies needed for an application or class.  Here is an example:

class Container {

	public static $_database;

	public static function makeBook() {

		$book = new Book();
		$book->setDatabase(self::$_database);
		// more injection...

		return $book;
	}

}

And then:

$book = Container::makeBook();

All dependencies should be registered into the container object during run time.  This object is now the gateway that all dependencies must pass through before they can interact with any classes.  This is the dependency container.

The reason makeBook is a public static function is for ease of use and global access.   When I started this article off I made a reference to the singleton pattern and global access being a poor choices of code.  They are, for the most part.  It is bad design when they control access, but it is perfectly ok when they control creation.  The makeBook function is only a shortcut for creation.  There is no dependency what-so-ever between the book class and the container class.  The container class exists so we can contain our dependencies in one location and automatically inject those dependencies with one line of code creation.

The container class removes all of the extra work of dependency injection.

Before injection:

$book = new Book();

And now:

$book = Container::makeBook();

Hardly any extra work, but tons of extra benefits.

When test code is run, specifically unit tests, the goal is to see if a method of a class is working correctly.  Since the book class requires database access to read the book data it adds a whole layer of complexity.  The test has to acquire a database connection, pull data, and test it.  All of a sudden the test is no longer testing a single method in the book class, it is now also testing database.  If the database is offline, the test would fail.  This is far from the goal a unit test.

A way of dealing with this is just using a different database dependency for the unit tests.  When the test suite starts up a dummy database is injected into the book.  The dummy database will always have the data the developer expects it to have.  If a live database was used in a unit test the data could potentially change causing tests to unnecessarily fail.

The code is more modular because it can dropped into any other web application.  Create the book object and inject a database connection with $book->setDatabase().  It does not matter if the database is in Registry::Database, $database, or $someRandomDatabaseVarible.  As long as there is a database connection the book will work inside any system.

The code is more maintainable because each object is given exactly what it needs.  If separate database connections are required between different instances of the same class then there no extra code needed inside the class what-so-ever.  Give book1 access to database1 and book2 access to database2.

Container::$_database = $ourDatabaseVarForDB1;

$book1 = Container::makeBook();
$book2 = Container::makeBook();
$book2->setDatabase($database2);

Dependency injection really is the answer to more maintainable, testable, modular code.

Displaying all your Instagram images, ignoring next page and pagination

Sometimes you’d like to know exactly how many images a given Instagram account has since creation. This unfortunately is not an option with the current API and today I’ll discuss a work around.

Here’s an example of an Instagram response, note the “next_url” object.

[pagination] => stdClass Object
        (
            [next_max_tag_id] => 1335219704338
            [deprecation_warning] => next_max_id and min_id are deprecated for this endpoint; use min_tag_id and max_tag_id instead
            [next_max_id] => 1335219704338
            [next_min_id] => 1335219773953
            [min_tag_id] => 1335219773953
            [next_url] => https://api.instagram.com/v1/tags/fun/media/recent?access_token=20576411.a30aaf6.c50198ecb09747788f0310e2c49964ed&min_id=&max_id=&max_tag_id=1335219704338
        )

    [meta] => stdClass Object
        (
             => 200
        )

    [data] => Array
        (
            [0] => stdClass Object

As you can see in the above example, The pagination object contains "next_url" which is a link to the next set of pictures. So what if you don't want a link to the next set but you want one big, bulk response of all the pictures? Where create an array of responses of course!

function __apiCall($url, $post_parameters = FALSE) {

    	// Initialize the cURL session
	    $curl_session = curl_init();

	    // Set the URL of api call
		curl_setopt($curl_session, CURLOPT_URL, $url);

		// If there are post fields add them to the call
		if($post_parameters !== FALSE) {
			curl_setopt ($curl_session, CURLOPT_POSTFIELDS, $post_parameters);
		}

		// Return the curl results to a variable
	    curl_setopt($curl_session, CURLOPT_RETURNTRANSFER, 1);

	    // Execute the cURL session
	    $contents = curl_exec ($curl_session);

		// Close cURL session
		curl_close ($curl_session);

		// Return the response
		return  json_decode($contents);
    }

As you can see in the above snippet (reading the comments) we take the set of parameters, use curl to send them to the endpoint, receive and decode our response and return it. Simple. What we need to do is leverage this function, with another function that will keep looping as long as it finds a "next_url" object in the currently received JSON response.

function getResults($url){

        $gotAllResults = false;
        $results = array();

        while(!$gotAllResults) {
        $result = $this-&gt;__apiCall($url);
        $results[] = $result;

        if (!property_exists($result-&gt;pagination, 'next_url')) {
            $gotAllResults = true;
        } else {
            $url = $result-&gt;pagination-&gt;next_url;
        }
    }

    return $results;

    }

And there you have it. The function above takes the url (endpoint for the API), defines the $results variable as an empty array that we will add to for each page and the $gotAllResults variable, which will be set to TRUE once there are no more pages(or "next_url" objects). Our while statement first tests that $gotAllResults is FALSE then performs the _apiCall function seen further above, receives the response and adds it to the array. The if state checks the current response to see if the "next_url" object exists, if it no longer does(meaning we have reached the end of the responses) it will set $gotAllResponses to TRUE, cancel out the while statement and return our array of results.

Now that we have our big array of JSON responses, parsing it can be tricky. Below is a snippet similar to what I uses to parse and display my API call, showing the image and some information about it...

THE PERFECT PHP CLEAN URL GENERATOR (I have found)

In my hunt for the perfect clean url (smart url, slug, permalink, whatever) generator I’ve always slipped in some exception or bug that made the function a piece of junk. But I recently found an easy solution I hope I could call “definitive”.

Clean url generators are crucial for search engine optimization or just to tidy up the site navigation. They are even more important if you work with international characters, accented vowels /à, è, ì, .../, cedilla /ç/, dieresis /ë/, tilde /ñ/ and so on.

First of all we need to strip all special characters and punctuation away. This is easily accomplished with something like:

function toAscii($str) {
	$clean = preg_replace("/[^a-zA-Z0-9\/_|+ -]/", '', $str);
	$clean = strtolower(trim($clean, '-'));
	$clean = preg_replace("/[\/_|+ -]+/", '-', $clean);

	return $clean;
}

With our toAscii function we can convert a string like “Hi! I’m the title of your page!” to hi-im-the-title-of-your-page. This is nice, but what happens with a title like “A piñata is a paper container filled with candy”?

The result will be a-piata-is-a-paper-container-filled-with-candy, which is not cool. We need to convert all special characters to the closest ascii character equivalent.

There are many ways to do this, maybe the easiest is by using iconv.

setlocale(LC_ALL, 'en_US.UTF8');
function toAscii($str) {
	$clean = iconv('UTF-8', 'ASCII//TRANSLIT', $str);
	$clean = preg_replace("/[^a-zA-Z0-9\/_| -]/", '', $clean);
	$clean = strtolower(trim($clean, '-'));
	$clean = preg_replace("/[\/_| -]+/", '-', $clean);

	return $clean;
}

I always work with UTF-8 but you can obviously use any character encoding recognized by your system. Thepiñata text is now transliterated into a-pinata-is-a-paper-container-filled-with-candy. Lovable.

If they are not Spanish, users will hardly search your site for the word piñata, they will most likely search forpinata. So you may want to store both versions in your database. You may have a title field with the actual displayed text and a slug field containing its ascii version counterpart.

We can add a delimiter parameter to our function so we can use it to generate both clean urls and slugs (in newspaper editing, a slug is a short name given to an article that is in production, source).

setlocale(LC_ALL, 'en_US.UTF8');
function toAscii($str, $delimiter='-') {
	$clean = iconv('UTF-8', 'ASCII//TRANSLIT', $str);
	$clean = preg_replace("/[^a-zA-Z0-9\/_|+ -]/", '', $clean);
	$clean = strtolower(trim($clean, '-'));
	$clean = preg_replace("/[\/_|+ -]+/", $delimiter, $clean);

	return $clean;
}

// echo toAscii(“A piñata is a paper container filled with candy.”, ‘ ‘);
// returns: a pinata is a paper container filled with candy

There’s one more thing. The string “I’ll be back!” is converted to ill-be-back. This may or may not be an issue depending on your application. If you use the function to generate a searchable slug for example, looking for “ill” would return the famous Terminator quote that probably isn’t what you wanted.

setlocale(LC_ALL, 'en_US.UTF8');
function toAscii($str, $replace=array(), $delimiter='-') {
	if( !empty($replace) ) {
		$str = str_replace((array)$replace, ' ', $str);
	}

	$clean = iconv('UTF-8', 'ASCII//TRANSLIT', $str);
	$clean = preg_replace("/[^a-zA-Z0-9\/_|+ -]/", '', $clean);
	$clean = strtolower(trim($clean, '-'));
	$clean = preg_replace("/[\/_|+ -]+/", $delimiter, $clean);

	return $clean;
}

You can now pass custom delimiters to the function. Calling toAscii("I'll be back!", "'") you’ll get i-ll-be-back. Also note that the apostrophe is replaced before the string is converted to ascii as character encoding conversion may lead to weird results, for example é is converted to 'e, so the apostrophe needs to be parsed before the string is mangled by iconv.

The function seems now complete. Lets stress test it.

echo toAscii("Mess'd up --text-- just (to) stress /test/ ?our! `little` \\clean\\ url fun.ction!?-->");

returns: messd-up-text-just-to-stress-test-our-little-clean-url-function

echo toAscii("Perché l'erba è verde?", "'"); // Italian

returns: perche-l-erba-e-verde

echo toAscii("Peux-tu m'aider s'il te plaît?", "'"); // French

returns: peux-tu-m-aider-s-il-te-plait

echo toAscii("Tänk efter nu – förr'n vi föser dig bort"); // Swedish

returns: tank-efter-nu-forrn-vi-foser-dig-bort

echo toAscii("ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖÙÚÛÜÝßàáâãäåæçèéêëìíîïðñòóôõöùúûüýÿ");

returns: aaaaaaaeceeeeiiiidnooooouuuuyssaaaaaaaeceeeeiiiidnooooouuuuyy

echo toAscii("Custom`delimiter*example", array('*', '`'));

returns: custom-delimiter-example


echo toAscii("My+Last_Crazy|delimiter/example", '', ' ');

returns: my last crazy delimiter example

I’m sure we are far from perfection and probably some php/regex guru will soon bury me under my ignorance suggesting an über-simple alternative to my function. What do you thing?

Post source author: Andre, from Cubiq.org