I wrote the code below to show something more "sophisticated", as the challenge proposes.
The first point that caught my attention was the following excerpt in the AP question
by clicking on this link I could use an echo and display the variable. Now
I’m trying to use the user friendly URL so technically there is no
plus the.php page? variavel=valuables.
This may not be the case for AP, but we should be aware that even a URL in the URL-friendly format (Rewrite URL), should allow access by normal mode.
Many systems mistakenly build their Urls by ignoring the normal way of mounting URL parameters. This is a problem because it does not allow the system to be used in environments that do not have a user-friendly URL feature.
From this script below, we highlight different points of most "solutions" to rescue parameters.
1. Subfolder support and relative URL basis
The "REQUEST_URI" key of the global variable $_SERVER
, returns the entire query of a URL. This may be a problem if the script runs inside a subfolder. It can also be a problem if the file name is explicitly invoked in the URL.
Example: http://localhost/pasta/parametro1/parametro2
$_SERVER['REQUEST_URI']
will return /pasta/parametro1/parametro2
.
If we do not identify the basis of the relative URL, we will have a conflict in the parameters.
The script below does this check and also checks the existence of the script file name, for the cases of Fake friendly URL.
Example: http://localhost/pasta/index.php/parametro1/parametro2
$_SERVER['REQUEST_URI']
will return /pasta/index.php/parametro1/parametro2
.
2. Normal URL, user-friendly URL, false friendly URL and Command line support (cli).
In the HTTP protocol, the standard and normal format of parameters in a URL is the traditional format using the parameter argument.
The parameter argumentator is represented by the question symbol (?).
Example: http://localhost/?p=foo/bar
We call this "normal URL".
In the user-friendly URL, also known as "URL rewriting", "rewrite URL" or "sugary URL", the parameters and the argumentator are omitted.
Example: http://localhost/foo/bar
For this to work, the environment web server must have URL rewriting support. The most popular web server is Apache. In this example, we will only talk about your use with Apache.
The fake friendly URL is a kind of gambiarra that allows you to create user-friendly Urls without using URL rewriting features like Apache’s mod_rewrite.
This technique arose due to market demand to use user-friendly URL on hosting servers without URL rewriting support.
Example: http://localhost/index.php/foo/bar
The command line, also known as CLI or CLI SAPI, in PHP, is an ignored or poorly supported execution medium for most applications. Usually the most popular frameworks on the market offer all the features described here, including command line executions.
Example: /caminho/do/compildor/php -f /caminho/do/script/index.php foo/bar
In the script below, there is support for command line interface (shell prompt).
For the command line, the parameters follow the same format as a friendly URL because the end result of any of the means of execution will be the same.
3. Friendly URL support by the POST method
It is recommended not to mix different request methods into a single request.
Example:
<form action="pagina.php?foo=bar" method="POST">
<input type="submit" name="test" value="ok" />
</form>
The "action" parameter of the tag form
has parameters in the format GET
. However, the method defined is "POST". To rescue this data on.php page, it will be necessary to invoke $_GET
to obtain the value of "foo" and $_POST
to get the value of "test"
Technically there are no serious problems like data conflict or anything like that. The problem in this is organization and also difficulty in implementing a way to rescue such data in a flexible and dynamic way.
In order to uncomplicate, it is recommended to adopt a data sending pattern by a single method.
In the case of sending data via the POST method, a user-friendly URL makes no sense because the parameters are not visible in the URL as in the GET method.
Therefore, it is recommended not to use a user-friendly URL for sending data using the POST method.
However, we must adapt to the demands of the market. Like the use of fake friendly URL, the script below also provides a means to allow URL friendly by the POST method. In this case, the friendly URL address is ignored and only the parameters sent by the POST method are extracted.
Magic Quotes!
It is a native PHP feature that, when enabled, adds escape characters to the values of the received parameters.
This feature was discontinued in PHP 5.3.0 and removed completely in version 5.4.0. http://php.net/manual/en/security.magicquotes.php
Currently many hosting servers have an environment with PHP 5.3 or even lower versions like 5.1 or 4 with Magic Quotes activated.
The script below has this check as a backward compatibility feature, allowing it to run on older versions of PHP.
<?php
date_default_timezone_set('Asia/Tokyo');
ini_set('error_reporting', E_ALL);
ini_set('log_errors',TRUE);
ini_set('html_errors',FALSE);
ini_set('display_errors',TRUE);
define('CHARSET', 'UTF-8');
ini_set('default_charset', CHARSET);
if (PHP_VERSION < 5.6)
{
ini_set('mbstring.http_output', CHARSET);
ini_set('mbstring.internal_encoding', CHARSET);
}
/**
Caminho base da URL relativa.
Exemplo, caso execute esse script sob um subolder: http://localhost/pasta/index.php
O valor de $path_base deve ser "/pasta/" ($path_base = '/pasta/';)
Caso execute na raíz do endereço, apenas defina com uma barra "/" ($path_base = '/';)
*/
$path_base = '/';
/**
Nome deste arquivo que executa os scripts.
*/
$index_file_name = basename($_SERVER['SCRIPT_FILENAME']);
/**
Verifica se está sendo executado por interface de linha de comando.
Caso a constante PHP_SAPI retorne a string "cli", retorna "true". Caso contrário, "false".
*/
$cli_mode = (strtolower(PHP_SAPI) == 'cli'? true : false);
/**
Caso $cli_mode for falso, resgatamos os parâmetros da chave "REQUEST_URI".
Caso $cli_mode for true, os parâmetros serão resgatados da chave "argv".
*/
$uri = (!$cli_mode? $_SERVER['REQUEST_URI'] : (isset($_SERVER['argv'][1])? $_SERVER['argv'][1] : ''));
/**
Remove o caminho base do parâmetro resgatado de $_SERVER['REQUEST_URI'] ou $_SERVER['argv'].
*/
if (!empty($uri))
{
$len = mb_strlen($path_base.$index_file_name);
if ($path_base.$index_file_name == substr($uri, 0, $len))
$uri = substr($uri, $len);
$len = mb_strlen($path_base);
if ($path_base == substr($uri, 0, $len))
$uri = substr($uri, $len);
}
/**
Caso não esteja sob interface de linha de comando (cli), executa os processos dentro da condicional.
*/
if (!$cli_mode)
{
/**
Resgata o método da requisição caso não esteja sob interface de linha de comando (cli).
*/
$method = (isset($_SERVER['REQUEST_METHOD'])? strtoupper($_SERVER['REQUEST_METHOD']) : null);
/**
true: Permite URL amigável pelo método POST.
false: Nega URL amigável pelo método POST.
Recomendável manter como false.
*/
$allow_mode_rewrite_by_post = false;
/**
Verifica se os parâmetros possuem formato normal ou formato de URL reescrita.
*/
if (substr($uri, 0, 1) == '?')
$mode_rewrite = false;
else{
if ($method == 'POST')
{
$mode_rewrite = ($allow_mode_rewrite_by_post? true : false);
}else{
$mode_rewrite = true;
}
}
/**
A query parece provir de uma URL normal.
*/
if (!$mode_rewrite)
{
/**
Nome do parâmetro padrão para recebimento de nomes de rotas.
Exemplo: http://localhost/?p=foo/bar
*/
$route_parameter = 'p';
/**
Nessa condição, resgatamos um parâmetro padrão que contém a rota.
O nome do parâmetro é definido na variável $route_parameter.
*/
$uri = (isset($GLOBALS['_'.$method][$route_parameter]) ? $GLOBALS['_'.$method][$route_parameter] : null);
/**
Suporte para servidores com magic_quotes ativado.
*/
if (!empty($uri) && get_magic_quotes_gpc())
$uri = stripslashes($uri);
}
}
/**
Exemplos de uso
URL normal: http://localhost/index.php?p=foo/bar ou http://localhost/?p=foo/bar
URL amigável falsa: http://localhost/index.php/foo/bar
URL amigável: http://localhost/foo/bar
Linha de comando: /caminho/do/compildor/php -f /caminho/do/script/index.php foo/bar
Para URL amigável sob o módulo Rewrite Module do Apache, o arquivo .htaccess deve conter o seguinte código:
DirectoryIndex index.php
RewriteEngine on
RewriteBase /
Options FollowSymLinks
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule (.+) /
*/
/**
Configura o ccharset no cabeçalho.
*/
header('Content-Type: text/html; charset='.CHARSET);
/**
Imprime "URI: foo/bar"
O output será sempre a parte relevante da URI.
Exemplo: localhost/foo/bar, localhost/?p=foo/bar e os outros meios, retornam "foo/bar"
*/
echo 'URI: '.$uri;
SEO, HTML link rel="Change"
For SEO purposes, it is important to be concerned about the URL information. If the system allows access to different URL formats, it is recommended to define link rel="alternate"
pointing to the "official URL".
This prevents search engines, such as google bot, from penalizing the page as a duplicate of some other previously indexed page.
In a practical example, we have the following URL http://localhost/foo/bar
which can also be accessed as http://localhost/?p=foo/bar
.
If the search bot has access to the normal URL, the system must identify that the request does not come from the default URL and add the HTML header to the tag <link>
whose attribute rel is set to "Alternate". For the attribute href
, set the default (official) URL where the bot should actually go and ignore penalties. Example:
<link rel="alternate" href="http://localhost/foo/bar" hreflang="en" />
It’s been A long time since I’ve rewritten the URL (routing is much better) but assuming it’s working,
$_GET['variavel']
does not echo valuables?– Bruno Augusto
Implementing Router-Friendly URL
– marcusagm