PHPPB Hangouts edição Fevereiro – Qualidade de código e produtividade

16 fev

549462_512075798844018_754742811_n

Hoje fizemos mais uma edição do projeto “Programe, Promova, Profissionalize” do #PHPPB. Os temas abordados hoje foram: Qualidade de Código e a Evolução do PHP (palestra de Evaldo Junior) e Produtividade com a técnica Pomodoro (debate realizado comigo, Abdala Cerqueira e Ítalo Queiroz).

Vocês podem assistir o vídeo completo aqui:

 

Links:

Grupo PHPPB no Facebook: https://www.facebook.com/groups/176265189091628/

Primeira edição: Aplicativos para o Facebook e o microframework Silex

How to fix ubuntu apt-get connection problems

9 jan

Today I tried to install LAMP on my notebook and got a lot of errors from apt-get, related to connection problems – the server (br server) from which it was trying to download the updates was apparently down. If you ever get these kind of errors on apt-get:

Err http://br.archive.ubuntu.com/ubuntu/ precise/main libapr1 amd64 1.4.6-1
Something wicked happened resolving 'br.archive.ubuntu.com:http' (-5 - No address associated with hostname)

And your internet seems to be ok (in a nutshell, the archive server is offline), there’s a super easy way to fix it: just go to Ubuntu Software Center, then select the “Edit  -> Software Sources…”.

changing the sources on ubuntu software center

changing the sources on ubuntu software center

You can change it to “Server for United States” or another location which suits you better. Then, run a

sudo apt-get update

And that’s all. You can try to install your software again and it will be okay (unless you’re facing internet problems).

Getting started with Silex – the php micro framework based on Symfony 2

21 nov

This post aims to show the basics, and how to get started with the php micro framework Silex- which, by the way, is my favorite php framework nowadays. It’s based on Symfony 2, but focused on smaller applications. It has a really comprehensive and intelligent schema for url rewriting (so-called “Routes”) that brings to PHP one of the great things you can find in Django. It’s concise, extensible – using Pimple and Composer for dependency management – and secure. Oh, almost forgot: it’s practical, easy to learn and super versatile – according to my own experience with the framework so far.

So, lets write some code! These instructions are focused on Linux (Ubuntu) environments. Another important thing to note is that Silex requires PHP 5.3 or higher.

First things first: install Silex via Composer

Let’s start by installing Composer*, so we can download the last version of Silex. This is the best way for maintaining your project and manage dependencies, its really easy to install and update everything! Open the terminal and go to your project folder. Then:

curl -s http://getcomposer.org/installer | php

Now, you must create a composer.json file containing instructions about which packages you are going to use in your project. The basic composer.json file for Silex is bellow:

{
    "require": {
        "silex/silex": "1.0.*"
    },
    "minimum-stability": "dev"
}

Now you can actually install everything:

php composer.phar install

You will get something like this:

 

Note: if you get a json error when installing composer, try to edit the file and trim the whitespaces.

*Composer is a tool for dependency management in PHP. It allows you to declare the dependent libraries your project needs and it will install them in your project for you. If you are not using Linux or have some trouble using Composer, you can also download Silex in the old-fashioned way – just go to http://silex.sensiolabs.org/download and follow the instructions.

Hello Worlding

Now that you have Silex installed, have a look at the directory tree. You will find a folder named “vendor” – that’s where Composer installs all dependencies defined at composer.json . Let’s create an index.php file at the root directory of your project and make some “Hello World” stuff. You can organize things better later. Let’s start with the basics.

<?php

/* include the silex autoload */
require_once __DIR__.'/vendor/autoload.php';

$app = new Silex\Application();

/* silex uses anonymous functions to define routes */
$app->get('/', function() use($app) {

	return 'Hello World!';

});

$app->run();

This will give you a basic “Hello World” output, as you can imagine. But let’s see what happens if you remove the route definition part from the script:

Want to get more information about this error? Set the debug mode in your application to true. The code will be like this:

<?php

require_once __DIR__.'/vendor/autoload.php';

$app = new Silex\Application();
$app['debug'] = true;

$app->run();

And you will get this:

Gorgeous! Now you can debug everything – just remember to unset this option when your project is in production.

Working with Routes

Now that you are familiar with the basics, let’s take a deeper look at the Silex Routes. What if I want to get some parameters along with the request? No problem at all – there’s a quite awesome way to accomplish this:

$app->get('/hello/{name}', function($name) use($app) {

	return 'Hello '.$app->escape($name);	

});

Got it? Heads up: when somebody hits the /hello path, the app will throw an error, since the only defined route is /hello/something. You can use the default modifier to set a default value for {name}, so you don’t need to define another route for /hello. Just like this:

$app->get('/hello/{name}', function($name) use($app) {

	return 'Hello '.$app->escape($name);	

})->value('name','Nobody');

Note that until now we only worked with GET routes. The POST routes are very similar, though. The only difference is that you shall work with a Request object to get the post variables – then you must include the Request class from Symfony HttpFoundation. Like this:

use Symfony\Component\HttpFoundation\Request;
$app->post('/hello', function (Request $request) {
    $name = $request->get('name'); // where 'name' is your form field's name
    return 'Hello '.$app->escape($name);
});

If you don’t want to specify the method (GET, POST, PUT or DELETE) you can use the “match” method. This is useful for getting generic requests like you would do with the $_REQUEST global var in plain PHP. For example – if you want to match GET and POST for the same route and var:

$app->match('/blog', function () {
    ...
})
->method('GET|POST');
Last, but not least: the order in which you define your routes is significant. The first route matched will be used - so place the more generic routes (like '/' ) at the bottom.

For a complete reference about Silex Routes (there’s a lot of other options, including filters and requirements using regex for matching the request variables), take a look at the the documentation: http://silex.sensiolabs.org/doc/usage.html#routing

The purpose of this post was to give a brief introduction to Silex. If you liked what you saw, I strongly recommend you to read the official documentation, so you can take advantage of everything this microframework has to offer to increase your productivity when creating not-that-big projects. Here are some links for getting started:

Silex Website - http://silex.sensiolabs.org

Official Documentation: http://silex.sensiolabs.org/documentation

Matthias Noback’s blog about silex and symfony2 – useful posts and how to’s: http://php-and-symfony.matthiasnoback.nl/category/silex/

Solving VirtualBox problem in Ubuntu Gnome Remix 12.10

30 out

Recently, I installed in my new notebook the Ubuntu Gnome Remix 12.10. Its a fantastic remix from Ubuntu, I am completely in love with this version – although sometimes I get some weird bugs related to package installations.

The most recent problem I had was related to Virtualbox. I installed it from apt-get and it looked ok, but when I tried to start the newly created VM I got this error:

Kernel driver not installed (rc=-1908)
The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing ‘/etc/init.d/vboxdrv setup’ as root. If it is available in your distribution, you should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.

I did some Googling but nothing seemed to work… This “/etc/init.d/vboxdrv” file didn’t exist. I found just a “virtualbox” script inside init.d folder, so after trying to execute it, I got this message:

erika@velvet:/etc/init.d$ sudo virtualbox setup
WARNING: The character device /dev/vboxdrv does not exist.
Please install the virtualbox-ose-dkms package and the appropriate headers, most likely linux-headers-generic.

You will not be able to start VMs until this problem is fixed.

What I did:

sudo apt-get install linux-headers-generic virtualbox-ose-dkms

So, after this, I ran:

sudo dpkg-reconfigure virtualbox-dkms

sudo dpkg-reconfigure virtualbox

And the problem was solved. Hope this can help someone out there!

PHPPB Hangouts – Primeira Edição

29 out

No último sábado, dia 27 de outubro, aconteceu o primeiro Hangout do PHPPB, onde falamos sobre desenvolvimento de aplicativos para o Facebook, qualidade de código e o microframework Silex.

Além da minha participação, estavam presentes também Abdala Cerqueira e Ricardo Belo.

Abaixo, o vídeo completo do hangout, para quem não pôde assistir ao vivo.

Slides da minha palestra sobre desenvolvimento de apps para o Facebook:

O código do script facebook.php está disponível no github do PHPPB: https://github.com/php-pb/Hangout-Page/blob/master/facebook.php

Debate

Slides “Recognizing smelly code” – http://harrieverveer.nl/slides/phpnw12.pdf
Slides “Silex, the microframework” – http://www.slideshare.net/blongden/silex-the-microframework

No repositório do PHPPB vocês também podem encontrar um exemplo de utilização do microframework Silex, que foi o que usei para montar a página do evento ( http://phppb.erikaheidi.com ) – o código completo dessa página está em https://github.com/php-pb/Hangout-Page .

 

How to selectively show content for followers on Facebook Page Tabs

26 set

In this post, you will learn how to selectively show content on your Facebook Page Tabs – you can show a special content for users who liked your fan page, for example – without the need to request any kind of user authorization / permission. This is extremely useful if you have high-value content to share , or if you want to create some kind of giveaway only for your followers (and gather a bunch of new followers as a consequence).

If you are not familiar with Facebook page tab applications, you should take a look at this post: How to Create a Facebook Tab App for your Fan Page - which has a step-by-step guide on creating a tab app from scratch.

First of all, prepare and set up your tab application.

How it Works

When a user reaches your application tab, he will send you a signed request. This signed request contains a piece of (public) information about this user and the relationship between him and your page – if he likes it or not. This data is signed using your App Secret (that’s why is so important to keep it secret: only you and Facebook shall know it). The process to decode this data is quite easy, though. These two functions (which was shameless copied from the Facebook Developers Documentation) below will do all the hard work for you:

	 function parse_signed_request($signed_request, $secret) {
		list($encoded_sig, $payload) = explode('.', $signed_request, 2); 

		// decode the data
		$sig = self::base64_url_decode($encoded_sig);
		$data = json_decode(self::base64_url_decode($payload), true);

		if (strtoupper($data['algorithm']) !== 'HMAC-SHA256') {
			error_log('Unknown algorithm. Expected HMAC-SHA256');
			return null;
		}

		// check sig
		$expected_sig = hash_hmac('sha256', $payload, $secret, $raw = true);
		if ($sig !== $expected_sig) {
			error_log('Bad Signed JSON signature!');
			return null;
		}

		return $data;
	}

	 function base64_url_decode($input) {
		return base64_decode(strtr($input, '-_', '+/'));
	}

Now we are able to actually get the information we need. Lets see a working code using the two functions above – it will print the signed_request data if the user likes the page:

		if(!empty($_REQUEST["signed_request"])) {		
			$data = self::parse_signed_request($_REQUEST["signed_request"], "YOUR_APP_SECRET");

			if (!empty($data["page"]["liked"])) {
				/* do whatever you want to do here for users who liked your page, like showing special content */
                                print_r($data);
			}
		}

Below, you can see an example of a signed_request array taken from the print_r above (I just removed the OAuth token from it).

Array ( 
   [algorithm] => HMAC-SHA256
   [expires] => 1348675200 
   [issued_at] => 1348669677 
   [oauth_token] => (user oauth token suppressed)
   [page] => Array (
       [id] => 462041577153253 
       [liked] => 1 
       [admin] => 1 
    ) 
   [user] => Array ( 
      [country] => br 
      [locale] => en_GB 
      [age] => Array ( [min] => 21 ) 
    ) 
   [user_id] => 707860628 
)

Take a look at the “page” sub array – there you can find out if the user liked or not the page. Also, you can check if the user is an admin of that page. This is useful if you want to show some administrative information / action to perform only for page admins.

You may have noticed that we don’t get much information about the user at all. This is expected, since you didn’t asked the user for it – if you want any other information about the user, such as its name, you need to request authorization (and this will be left for another post).

*I don’t have any coupon codes to give, the image is only representative :D

How to create a Facebook Tab App for your Fanpage – step by step guide

12 set

In this post, I will show you how to create a Facebook Tab App from scratch. If you are a web developer, you can do all the job by yourself, but if you don’t have at least some basic knowledge about web development ,you’ll probably need someone else to help you.

You can find a Portuguese (pt-BR) version of this post, also written by me, here: Tutorial: como criar abas customizadas (timeline apps) para sua fanpage no Facebook .

Fist of all: you’ll need to be a Facebook developer in order to create applications, but it’s quite easy to accomplish that. You just need to register yourself (you need to log-in with a valid Facebook account) at http://developers.facebook.com .

Before you Start

Before creating your application, you need to prepare your content. It must be accessible via http, since Facebook applications work with iframes. When a user reaches your application, in fact he will be accessing your url via an iframe inside Facebook. You can manage to only show content for users who liked your fanpage, or to show an specific content for these users (and another one for the non-followers). Later we’ll talk more about this.

For learning purposes, we’ll be using a simple static html page as content, with a “Hello Facebook” text inside it. This content is online at this url: http://entrebits.com.br/helloface.html . Remember you can use any content you want, as long as it’s publicly accessible via http. It should fits on 810px wide.

Create the App

Access https://developers.facebook.com/apps and click on the “Create New App” button. You will be prompted to fill in the form with basic information about your app:

Give a name to your app in the first field. In the second field, you must provide a unique name as a namespace. Then click on the “Continue” button. A Captcha window will appear. After filling the captcha, you will be redirected to an “edit” page where you can customize your application.

In the header you will find important information about your recently created application. Here you can also upload an image and an icon to your app (just click on the images and a form will pop up).

The App ID identifies your application. As well as the App Secret, the ID must be provided when you need to make requests to the Facebook API through your application. For the first part of this tutorial, we won’t make any requests because our app is just a simple static html page with a “Hello World”.

Configure your app settings

Now you have to configure the application settings, and specify the url of your content. Select the “Page Tab” option and fill in the form with your app information, as shown below.

The app name will be shown as the Tab Name in your fan page (right bellow the Tab Image thumbnail), and also in the header of the application inside Facebook. However, you can change the Tab Name and the Tab Thumbnail directly at the Fan Page, there’s no need to edit the app settings for this.

Don’t forget to check the “Wide (810px)” option for the Page Tab Width.

Note about https (secure page tab url)

It’s not mandatory for your app to have a secure url – if you skip this, your app will run as expected for all users accessing Facebook via normal http – the usual way. But users who are accessing FB via https (secure browsing) will not be able to access your application.

Now, if your web server has ssl enabled and https is working fine (just try to access the same url using https instead of http), you can set this field (secure page tab url) to https://whateverisyourappurl . However, if you don’t own an SSL certificate issued by a reliable entity, users will get something like this when trying to access your application / page tab:

Google Chrome

Mozilla Firefox

Note that this is not Facebook’s fault. It’s a “security care” from browsers.

I couldn’t find any research about how many users are accessing Facebook via https nowadays. So, if you want to create a big app or some “serious stuff”, I recommend you to buy an SSL certificate. After creating your application, you can try a 90-day trial ssl certificate from Comodo for free, and check if it suits your needs.

Now let’s move on to the next step – add the application to your FanPage. Now we’ll need that App ID we talked about after creating the app.

You just need the link bellow – changing, of course, “YOUR_APP_ID” to whatever is your App ID, and “YOUR_URL” to your page tab app url (the same you entered when setting up the application).

http://www.facebook.com/dialog/pagetab?app_id=YOUR_APP_ID&next=YOUR_URL

For our example app, the url is: http://www.facebook.com/dialog/pagetab?app_id=280648832010374&next=http://entrebits.com.br/helloface.html

When accessing this url, you will be prompted to choose in which FanPage you want to add the application as a Tab. You must be one of the FanPage’s administrators to do so.

After choosing, access your FanPage to see the result:

In the next post, I will show how to check if a user liked or not your fanpage, so you can produce restricted content only for followers. See ya!

Url Rewriting – user friendly and professional url structure for your website

28 jul

Its not only a SEO and user friendly functionality; Url Rewriting techniques are also a good approach to make your website safer. By using Url Rewriting, you will be hiding your script extensions and website paths, avoiding sql injection hacks.

*There’s a pt-BR version of this post here: http://erikaheidi.com/2011/08/16/url-rewriting-como-tornar-a-estrutura-de-urls-do-seu-site-amigavel-e-profissional/ . 

As we are talking about PHP here, this is implemented with the mod_rewrite directive on Apache. This extension is available by default in almost any hosting service, ready for you to use it in your website.

WordPress and other CMS’s are ready to use url rewriting, and you just need to enable the option on control panel. But when you are dealing with a custom CMS, for example, you will need to make your own url rewriting structure. There are two paths for accomplishing that: using a rule on .htaccess for every single url on your website – which is impracticable, but sometimes needed for some inherited urls and scripts that you can’t change; and by using a generic rule with an intelligent website structure, as used in WordPress CMS.

On this post you will learn a practical way for implementing url rewriting on your website with this generic single-rule model.

mod_rewrite and .htaccess

Before going any further, you need to understand how url rewriting schema works. We need to establish rules on the .htaccess file, which is situated on the www directory root (you can also use a separated .htaccess file in any subdirectory, establishing rules specific for that directory).  The rules are defined using regular expressions. The image below explains how the request is processed by Apache and PHP. The first request doesn’t uses rewriting, and just by looking at the url you will say “I see what you did here, developer…”. The second request uses url rewriting, letting you think that its just a regular html file.

 

the request

 

Now lets see a functional example. Lets assume we have a directory structure like this on our www folder: “abc/def/ghi” (accessing it via http, the url would be http://mysite.com/abc/def/ghi ). So we would like that the files on this folder could be accessed in a simpler path: /xyz . In other words, rather than using the url http://mysite.com/abc/def/file.html, I want to use: http://mysite.com/xyz/file.html (and this “xyz” directory actually doesn’t exists).

Our .htaccess file would be like this:

RewriteEngine On

RewriteBase   /

RewriteRule  ^/xyz(.*) /abc/def/ghi$1

For more details about all the possible rules, and what each item means, its good to have a look on the Apache’s mod_rewrite documentation:   http://httpd.apache.org/docs/current/mod/mod_rewrite.html . This link also has good basic tips: http://php.refulz.com/201105/url-rewriting-with-apache/ .

First Step – .htaccess

As we talked before, we can use use a lot of rules in our htaccess, but the simplest and most elegant way for working with url rewriting is by using a generic rule and a controller (php) which will manage the requests and grab the right page for that request. The content bellow is the .htaccess file used by WordPress, the same we will be using for our example:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

# END WordPress

Basically, this .htaccess specifies that: every request, having “/” as base, which is not a existing file or directory, shall be passed to /index.php file. This file will be responsible for treating all requests, any way it wants. A controller.

Remember two things:

  • Existing directories will not be affected. Example: If you have a “blog” directory you will not be able to have a rewriting like “/blog” for a script.
  • You have to take care of 404 errors, because as you are getting all requests for files and dirs that don’t exist, the “404″ error will not happen anymore. Everything will come to index.php and you have to deal with “not found” requests on your controller – just like WordPress does.

Step 2 – PHP Controller and Directory Structure

The file bellow will be our controller, responsible for taking care of all requests. On this example, will make this through includes.

<?php
/* on config.php you put your initialization stuff, like session start and bd connection */
require_once("includes/config.php");

$uri = $_SERVER['REQUEST_URI'];
/* default is index */
$pagina = "index";

if($uri != "/")
{
      /* url parsing */

        /* remove url parameters */
	$t = explode('?',$uri);
        /* divide request */
        $path = explode("/",$t[0]);

	$module = strtolower($path[1]);
	/* an extra check if there's a dir with this name */
	if(!is_dir($module))
	{
          /*verifies if there's a module with this name*/
		if(is_dir("modules/$module"))
			$pagina = $module."/index";
		else if(is_file("modules/$module.php"))
			$pagina = $module;
		else
            /* if doesn't, get the 'not found' module */
			$pagina = "404";

	}
}

require_once("modules/$pagina.php");

As you can see, the logic is very simple. A request to “/contact” , for example, will check if there’s a module called contact – this is done by checking if there’s a “modules/contato/index.php” or “modules/contato.php” file.

It’s important to check if the file exists before including it – only this way is possible to know if we must send the user to a “404″ error.

For adding a new page on your website, you will need to create a file (or directory, and then an index.php file inside it) inside the “modules” directory,  and the script will be immediately accessible via http://yoursite.com/yournewmodule - easy as that. A folder with “yournewmodule” cannot exists on the root directory, worth remembering.

That “modules/yournewmodule.php” file will be a controller in an MVC environment. You can do your stuff there and show a template file, for example.

If you want submodules, like “mysite.com/about/company”, you shall check for that $path array, which will contains all the “pieces” of the request. Just make a switch and you are ready to go. Its important to make this $path variable available on all script scope.

Bellow is how our directory structure would be:

/
/includes
   /includes/config.php
/modules
   /contato.php
   /404.php
/.htaccess
/index.php

Starting from here, you can construct a good framework for your php web applications. Good luck ;)

IV Encontro de Comunicação Digital

29 nov

Será realizado em João Pessoa nos dias 9 e 10 de dezembro o IV Encontro de Comunicação Digital – evento anual organizado por alunos do Instituto Federal de Educação, Ciência e Tecnologia da Paraíba – IFPB, de cunho científico e cultural, sem fins lucrativos, que visa a integração acadêmica, a caracterização e a promoção da atividade de Tecnologia da Informação e áreas afins, reunindo estudantes, professores, pesquisadores, profissionais e empresas da área.

Participarei como palestrante do evento, com o tema “Desenvolvimento de aplicações para redes sociais: Twitter”.

Será dada uma visão geral sobre o desenvolvimento de aplicações usando api’s de redes sociais; depois, será mostrado todo o processo de desenvolvimento de uma aplicação para o Twitter, utilizando a biblioteca open source TwitterTools – que facilita esse processo. No decorrer da palestra será mostrado o código e passo a passo da criação de uma aplicação do tipo “robô de reply”, que responde mentions recebidas automaticamente. Minha palestra está marcada para as 17:10 do dia 10/12 (sábado).

As inscrições estão sendo realizadas através do site oficial do evento: http://comunicacaodigital.info/ . A entrada é apenas 1kg de alimento – serão doados à casa da Criança com Câncer.

Url Rewriting – como tornar a estrutura de urls do seu site amigável e profissional

16 ago

Há algumas semanas, um grande buzz foi gerado no Twitter depois que uma reportagem sobre fraudes na internet deu a entender que urls com a extensão .php seriam, em sua maioria, vírus. O “especialista em segurança” estava dando dicas para que as pessoas não clicassem em links suspeitos, e a forma que ele falou, com a edição que foi feita, deixou bem claro que “a maioria das páginas em php são vírus.” O acontecido se deu no Jornal Hoje, e o vídeo pode ser visto nesse link: http://www.youtube.com/watch?v=x9_qwgYrESg .

O que muitas pessoas podem não saber é que a linguagem PHP é a mais utilizada na WEB nos dias atuais. Pesquisas recentes indicam que ele é usado em 59% dos sites (contra 34% do ASP, que fica em segundo). Acontece que nem todo site que usa php precisa mostrar isso através das extensões .php. Existem técnicas para esconder a extensão dos arquivos; essas técnicas são geralmente usadas por questões de segurança e otimização para mecanismos de busca. Sites e CMSs profissionais (como o WordPress, usado aqui neste blog) não exibem suas extensões de arquivo, e a técnica mais utilizada para isso é Url Rewriting.

Para quem não conhece, a técnica de Url Rewriting funciona como uma reescrita de urls, um tipo de mascaramento que tem por objetivo tornar a url mais amigável e esconder as extensões dos arquivos, o que acaba tendo um aspecto de segurança também. Os servidores web e frameworks mais conhecidos implementam esse mecanismo, seja de maneira nativa ou através de módulos. No nosso caso, como estamos falando de PHP, estamos falando de Apache com mod_rewrite habilitado (a maioria dos servidores pagos e instalações padrão já vêm com esse módulo ativo).

Nesse post, você terá uma visão geral de como criar as regras do url rewriting em uma estrutura de site que utiliza essa técnica de maneira prática e inteligente, similar ao que é utilizado pelo WordPress.

mod_rewrite e o .htaccess

Antes de mais nada, é legal entender como funciona o esquema de url rewriting no apache. Precisamos estabelecer regras que devem ser colocadas no arquivo .htaccess, na raiz do diretório www (o arquivo .htaccess também pode vir em qualquer subdiretório, estabelecendo regras próprias para aquele diretório específico). As regras são definidas através de expressões regulares. A imagem abaixo explica como é feito o processamento após a requisição vinda do usuário:

 

a requisição

 

Vamos supor que temos o diretório www como a raiz do site meusite.com . Imagine que dentro dessa pasta www, nós temos o diretório “abc/def/ghi” (acessando via http, a url ficaria http://meusite.com/abc/def/ghi ). Mas gostaríamos que todos os arquivos dessa pasta fossem acessíveis através de um caminho diferente e mais simples: /xyz . Ou seja, ao invés de acessar pelo endereço http:/meusite.com/abc/def/ghi/arquivo.html, eu quero usar http://meusite.com/xyz/arquivo.html (onde o diretório /xyz na verdade não existe).

Nosso arquivo .htaccess ficaria assim:

RewriteEngine On

RewriteBase   /

RewriteRule  ^/xyz(.*) /abc/def/ghi$1

Para maiores detalhes sobre todas as regras possíveis, e o que cada item significa, é bom dar uma olhada na documentação do Apache sobre o mod_rewrite:  http://httpd.apache.org/docs/current/mod/mod_rewrite.html . Esse post aqui também tem umas dicas básicas muito boas: http://php.refulz.com/201105/url-rewriting-with-apache/ (ambos em inglês).

Passo 1 – .htaccess

Podemos criar várias regras no htaccess para nossos scripts, porém, existe uma maneira mais simples de trabalharmos com o url rewriting. Através de uma regra geral, podemos deixar o processamento a cargo de um script php, ao invés de encher o arquivo .htaccess de regras. Esse é o esquema utilizado pelo WordPress. Abaixo está o conteúdo de um arquivo .htaccess padrão utilizado por essa plataforma:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

# END WordPress

Basicamente, o que esse .htaccess especifica é que: toda requisição, tendo como diretório base o “/”, que não for um arquivo nem um diretório (que jogariam um erro 404 normalmente, pois não existem), deve ser repassada para o script /index.php, que ficará responsável por tratar essas requisições da maneira que quiser. Ou seja, no arquivo index.php deve haver um processamento para obter a requisição feita e decidir o que deve ser chamado – um típico controlador.

É bom lembrar que diretórios existentes não serão afetados, já que a regra do url rewriting só irá redirecionar para o index quando não existir um arquivo ou diretório no caminho especificado.

Passo 2 – Controlador php e estrutura de diretórios

Utilizando o .htaccess exemplificado acima, o script index.php será responsável por definir o que deve ser chamado – faremos isso com uso de includes. Fica a seu critério a organização do seu framework, porém irei fazer aqui uma sugestão, que deixa o diretório de arquivos bem organizado e torna o desenvolvimento bem mais fácil. Primeiro, vamos dar uma olhada no arquivo index.php, que é o controlador do framework:

<?php
/* no config.php você pode iniciar sessão e conectar ao BD por exemplo */
require_once("includes/config.php");

$uri = $_SERVER['REQUEST_URI'];
//default = index
$pagina = "index";

if($uri != "/")
{
      /* faz o parsing do url rewriting */

        /* retira parametros de url*/
	$t = explode('?',$uri);
	$path = explode("/",$t[0]);

	$module = strtolower($path[1]);
	/* checagem extra para a existência de um diretório com esse nome */
	if(!is_dir($module))
	{
          /*verifica se existe o módulo requisitado*/
		if(is_dir("modules/$module"))
			$pagina = $module."/index";
		else if(is_file("modules/$module.php"))
			$pagina = $module;
		else
            /* caso não exista, incluir o módulo de 'not found' */
			$pagina = "404";

	}
}

require_once("modules/$pagina.php");

Como vocês podem ver, a lógica é bem simples. É importante verificar se o arquivo existe antes de tentar incluí-lo – verificamos se existe aquele “módulo”. Uma requisição feita para “/contato“, por exemplo, resultará na checagem/inclusão do arquivo “modules/contato/index.php” OU “modules/contato.php“.

E assim, para cada página que você quiser acrescentar, pode criar um arquivo ou diretório dentro da pasta “modules” (você poderia usar diretórios para organizar melhor quando houvesse “submódulos”). Dentro desse arquivo você ainda pode criar regras (um switch já serve) para testar um segundo,  terceiro nível de requisição (por exemplo: “/contato/orcamento” ). Nesse caso, a página que será incluída continuará sendo a “contato.php“, dentro dela é que você irá checar se existe um “submódulo”, o que pode ser feito facilmente com regex ou verificando o array $path. Nossa estrutura de diretórios/arquivos estaria mais ou menos assim:

/
/includes
   /includes/config.php
/modules
   /contato.php
   /404.php
/.htaccess
/index.php

Bom, acredito que a partir daí já dá pra desenvolver a idéia né? Adicionando a engine de templates Smarty, você já deixa seu framework mais elaborado e modulado, facilitando ainda mais a criação de novas páginas / módulos. Nesse caso, use os arquivos de módulo para obter as informações necessárias, e dar o display no template.

É importante ter um módulo “404″ para chamar quando não encontrar a página que o usuário pediu, já que não haverá mais o erro 404 padrão pois estamos pegando tudo o que “não existe” e tentando mapear no nosso framework. Nesse arquivo você deve exibir alguma mensagem indicando que o conteúdo não foi encontrado.