php[world] 2015 Schedule Announced

Utilizando o PHP

Esta seção reúne vários erros comuns que você pode encontrar enquanto estiver escrevendo scripts PHP.

  1. Não consigo me lembrar da ordem dos parâmetros das funções PHP. Eles são aleatórios?
  2. Eu gostaria de escrever um script PHP genérico que fosse capaz de manipular dados provenientes de qualquer formulário. Como eu sei quais variáveis do método POST estão disponíveis?
  3. Preciso converter todas as aspas simples (') para uma barra invertida seguida por uma aspa simples (\'). Como eu posso fazer isso utilizando expressões regulares? Gostaria de converter também " para \" e \ para \\.
  4. Todas as minhas aspas duplas (") viraram \" e minhas aspas simples (') viraram \', como eu faço para me livrar destas barras invertidas indesejadas? Como e por que elas apareceram lá?
  5. Como a diretiva register_globals do PHP me afeta?
  6. Quando eu faço o seguinte, a saída é exibida na ordem errada: <?php function myfunc($argument) { echo $argument + 10; } $variable = 10; echo "myfunc($variable) = " . myfunc($variable); ?> o que está acontecendo?
  7. Ei, o que aconteceu com as minhas novas linhas? <pre> <?php echo "Esta deve ser a primeira linha."; ?> <?php echo "Esta deveria ser uma nova linha."; ?> </pre>
  8. Recebi a mensagem 'Warning: Cannot send session cookie - headers already sent...' ou 'Cannot add header information - headers already sent...'.
  9. Preciso acessar informações no cabeçalho de requisição diretamente. Como eu faço isso?
  10. Quando eu tento utilizar autenticação com o IIS eu recebo a mensagem 'No Input file specified'.
  11. Windows: Não consigo acessar arquivos compartilhados em outro computador utilizando IIS.
  12. Como faço para misturar XML e PHP? Ele reclama das minhas tags <?xml!
  13. Onde posso encontrar uma lista completa das variáveis que estão disponíveis para mim no PHP?
  14. Como posso gerar arquivos PDF sem utilizar bibliotecas não-livres e comerciais como PDFLib? Eu gostaria de alguma que fosse livre e não precisasse de bibliotecas PDF externas.
  15. Estou tentando acessar uma das variáveis padrões do CGI (como $DOCUMENT_ROOT ou $HTTP_REFERER) em uma função definida pelo usuário e não consigo encontrá-la. O que está errado?
  16. Algumas diretivas PHP podem receber valores em bytes de forma abreviada (1K), ao contrário de apenas valores inteiros. Quais são todas as opções disponíveis de bytes de forma abreviada? Posso usá-las fora do php.ini?
  17. Windows: Estou recebendo timeouts de conexão quando utilizo localhost ao passo que "127.0.0.1" funciona?
Não consigo me lembrar da ordem dos parâmetros das funções PHP. Eles são aleatórios?

O PHP é uma "cola" que reúne centenas de bibliotecas externas, então às vezes isso fica desorganizado. No entanto, uma regra simples é a seguinte:

Os parâmetros de funções de Array são ordenados como "needle, haystack" ao passo que funções de String são o contrário, logo "haystack, needle".

Eu gostaria de escrever um script PHP genérico que fosse capaz de manipular dados provenientes de qualquer formulário. Como eu sei quais variáveis do método POST estão disponíveis?

O PHP disponibiliza muitas variáveis predefinidas, como a superglobal $_POST. Você pode iterar através de $_POST, já que ele é um array associativo com todos os valores enviados com o método POST. Por exemplo, vamos iterar através de POST com foreach, verificar se há valores vazios com empty() e imprimi-los na tela.

<?php
$empty 
$post = array();
foreach (
$_POST as $varname => $varvalue) {
    if (empty(
$varvalue)) {
        
$empty[$varname] = $varvalue;
    } else {
        
$post[$varname] = $varvalue;
    }
}

print 
"<pre>";
if (empty(
$empty)) {
    print 
"Nenhum dos valores enviados com POST estão vazios, enviado:\n";
    
var_dump($post);
} else {
    print 
"Temos " count($empty) . " valores vazios\n";
    print 
"Enviado:\n"var_dump($post);
    print 
"Vazio:\n"var_dump($empty);
    exit;
}
?>

Nota: Disponibilidade das superglobais:

Arrays superglobais como $_GET, $_POST, e $_SERVER, etc. estão disponíveis desde o PHP 4.1.0. Para mais informação, leia a seção do manual em superglobals

Preciso converter todas as aspas simples (') para uma barra invertida seguida por uma aspa simples (\'). Como eu posso fazer isso utilizando expressões regulares? Gostaria de converter também " para \" e \ para \\.

Considerando que isso seja para um banco de dados, utilize o mecanismo de escape que vem com o banco de dados. Por exemplo, utilize mysql_real_escape_string() com MySQL e pg_escape_string() com PostgreSQL. Existem também as funções genéricas addslashes() e stripslashes(), que são mais comuns com códigos PHP antigos.

Nota: Nota sobre a diretiva magic_quotes_gpc:

A diretiva magic_quotes_gpc tem por padrão on. Ela essencialmente utiliza addslashes() em todos os dados postados por GET, POST e COOKIEs. stripslashes() pode ser usado para reverter isso.

Todas as minhas aspas duplas (") viraram \" e minhas aspas simples (') viraram \', como eu faço para me livrar destas barras invertidas indesejadas? Como e por que elas apareceram lá?

O mais provável é que as barras invertidas apareceram porque a diretiva magic_quotes_gpc do PHP está ativada. Esta é uma funcionalidade antiga do PHP e deve ser desabilitada e não utilizada. Além disso, a função stripslashes() do PHP também pode ser utilizada para remover as barras invertidas de uma string.

Nota: Nota sobre a diretiva magic_quotes_gpc:

A diretiva magic_quotes_gpc tem por padrão on. Ela essencialmente utiliza addslashes() em todos os dados postados por GET, POST e COOKIEs. stripslashes() pode ser usado para reverter isso.

Como a diretiva register_globals do PHP me afeta?
Aviso

Esta funcionalidade tornou-se OBSOLETA desde o PHP 5.3.0 e foi REMOVIDA desde o PHP 5.4.0.

Primeiramente, uma explicação sobre o que esta configuração faz. Vamos dizer que a seguinte URL é utilizada: http://example.com/foo.php?animal=cat e no arquivo foo.php temos o seguinte código PHP:

<?php
// É preferível utilizar $_GET aqui
echo $_GET['animal'];

// Para a variável $animal existir, register_globals deve ser on
// NÃO FAÇA ISSO
echo $animal;

// Isto é aplicado a todas as variáveis, inclusive a variável $_SERVER
echo $_SERVER['PHP_SELF'];

// Novamente, para a variável $PHP_SELF existir, register_globals deve ser on
// NÃO FAÇA ISSO
echo $PHP_SELF;
?>

O código acima demonstra como register_globals cria várias variáveis. Durante anos, esta abordagem foi desencorajada e por anos ela foi desabilitada por padrão. Embora a maioria das empresas de hospedagem web tenham desabilitado register_globals, existem ainda artigos, tutoriais e livros desatualizados que exigem que ela esteja habilitada.

Veja também os seguintes recursos para informações adicionais:

Nota:

No exemplo acima, utilizamos uma URL que contém uma QUERY_STRING. A passagem da informação é feita através de uma requisição GET do HTTP, por este motivo a variável superglobal $_GET foi utilizada.

Quando eu faço o seguinte, a saída é exibida na ordem errada:
<?php
function myfunc($argument)
{
    echo 
$argument 10;
}
$variable 10;
echo 
"myfunc($variable) = " myfunc($variable);
?>
o que está acontecendo?

Para ser capaz de utilizar os resultados de suas funções em uma expressão (como concatenar com uma string no exemplo acima), você precisa utilizar return para retornar o valor e não echo.

Ei, o que aconteceu com as minhas novas linhas?
<pre>
<?php echo "Esta deve ser a primeira linha."?>
<?php 
echo "Esta deveria ser uma nova linha."?>
</pre>

No PHP, um bloco de código é fechado com "?>" ou "?>\n" (onde \n significa uma nova linha). Logo, no exemplo anterior, as sentenças serão exibidas na mesma linha porque o PHP omite o caractere de nova linha após o final do bloco de código. Isso significa que você precisa inserir uma nova linha depois de cada bloco de código PHP para exibi-las em uma nova linha.

Por que o PHP faz isso? Porque quando está formatando HTML, isto normalmente torna sua vida mais fácil porque não se quer esta nova linha, senão você teria que criar linhas extremamente longas ou tornar o código fonte ilegível para alcançar este efeito.

Recebi a mensagem 'Warning: Cannot send session cookie - headers already sent...' ou 'Cannot add header information - headers already sent...'.

As funções header(), setcookie() e as funções de sessão precisam adicionar os cabeçalhos ao stream de saída, mas os cabeçalhos só podem ser enviados antes de qualquer outro conteúdo. Não pode haver nenhuma saída antes de utilizar estas funções como HTML. A função headers_sent() irá verificar se o seu script já enviou cabeçalhos e veja também as funções de Controle de Saída.

Preciso acessar informações no cabeçalho de requisição diretamente. Como eu faço isso?

A função getallheaders() fará isso se você estiver rodando o PHP como um módulo do Apache. Logo, o fragmento de código abaixo sempre exibirá todos os cabeçalhos de requisição:

<?php
$headers 
getallheaders();
foreach (
$headers as $name => $content) {
    echo 
"headers[$name] = $content<br />\n";
}
?>

Veja também apache_lookup_uri(), apache_response_headers() e fsockopen()

Quando eu tento utilizar autenticação com o IIS eu recebo a mensagem 'No Input file specified'.

O modelo de segurança do IIS é o culpado aqui. Este é um problema comum a todos os programas CGI rodando no IIS. A solução é criar um arquivo HTML (não parseado pelo PHP) como uma página de entrada para o diretório autenticado. Então utilizar a tag META para redirecionar para a página PHP ou fornecer um link para a página PHP. O PHP irá então reconhecer a autenticação corretamente. Com o módulo ISAPI, este não é um problema. Isto não deve afetar outros servidores web NT. Para mais informações veja: » http://support.microsoft.com/kb/q160422/ e a seção do manual em Autenticação HTTP .

Windows: Não consigo acessar arquivos compartilhados em outro computador utilizando IIS.

Você terá que alterar o Go to Internet Information Services. Localize o arquivo PHP e vá até suas propriedades. Vá até a aba File Security, Edit -< Anonymous access and authentication control.

Pode-se corrigir o problema desabilitando Anonymous Access e deixando Integrated Window Authentication habilitado, ou habilitando Anonymous Access e editando o usuário para que ele não possa ter o direito de acesso.

Como faço para misturar XML e PHP? Ele reclama das minhas tags <?xml!

Para utilizar <?xml diretamente no seu código PHP, você terá que desabilitar as short tags definindo a diretiva PHP short_open_tags como 0. Você não pode configurar esta diretiva com a função ini_set(). Independentemente de short_open_tags estar ativada ou não, você pode fazer algo como: <?php echo '<?xml'; ?>. O padrão para esta diretiva é On.

Onde posso encontrar uma lista completa das variáveis que estão disponíveis para mim no PHP?

Leia a página do manual variáveis predefinidas dado que ele inclui uma lista parcial das variáveis predefinidas disponíveis para o seu script. Uma lista completa das variáveis disponíveis (e muito mais informação) pode ser vista chamando a função phpinfo(). Não deixe de ler a seção do manual variáveis de fontes externas uma vez que descreve cenários comuns para variáveis externas como aquelas originadas de um formulário HTML, cookie ou da URL.

Nota: Nota importante sobre register_globals:

Desde o PHP 4.2.0, o valor padrão para a diretiva register_globals é off e foi completamente removida a partir do PHP 6.0.0. A comunidade do PHP desencoraja desenvolvedores a confiar nesta diretiva, e encoraja o uso de outros meios, como em superglobals.

Como posso gerar arquivos PDF sem utilizar bibliotecas não-livres e comerciais como PDFLib? Eu gostaria de alguma que fosse livre e não precisasse de bibliotecas PDF externas.

Existem algumas poucas alternativas escritas em PHP como » FPDF e » TCPDF.

Existe também a extensão Haru que utiliza a biblioteca externa livre libHaru.

Estou tentando acessar uma das variáveis padrões do CGI (como $DOCUMENT_ROOT ou $HTTP_REFERER) em uma função definida pelo usuário e não consigo encontrá-la. O que está errado?

É importante notar que a diretiva PHP register_globals também afeta as variáveis de ambiente e do servidor. Quando register_globals = off (o padrão é desativado desde o PHP 4.2.0), $DOCUMENT_ROOT não existirá. Em vez disso, use $_SERVER['DOCUMENT_ROOT'] . Se register_globals = on então as variáveis $DOCUMENT_ROOT e $GLOBALS['DOCUMENT_ROOT'] também existirão.

Se você tem certeza que register_globals = on e se pergunta por que $DOCUMENT_ROOT não está disponível dentro das funções, é porque elas são como quaisquer outras variáveis e irão exigir global $DOCUMENT_ROOT dentro da função. Veja também a página do manual sobre escopo de variáveis. É preferível codificar com register_globals = off.

Nota: Disponibilidade das superglobais:

Arrays superglobais como $_GET, $_POST, e $_SERVER, etc. estão disponíveis desde o PHP 4.1.0. Para mais informação, leia a seção do manual em superglobals

Algumas diretivas PHP podem receber valores em bytes de forma abreviada (1K), ao contrário de apenas valores inteiros. Quais são todas as opções disponíveis de bytes de forma abreviada? Posso usá-las fora do php.ini?

As opções disponíveis são K (para Kilobytes), M (para Megabytes) e G (para Gigabytes; disponíveis desde o PHP 5.1.0), eles são sensíveis a maiúsculas e minúsculas. Qualquer outra coisa é tratada como bytes. 1M é igual a um Megabyte ou 1048576 bytes. 1K é igual a um Kilobyte ou 1024 bytes. Você não poderá utilizar esta notação abreviada fora do php.ini, em vez disso utilize um valor inteiro de bytes. Veja a documentação de ini_get() para um exemplo sobre como converter estes valores.

Nota: kilobyte versus kibibyte

A notação do PHP descreve um kilobyte equivalente a 1024 bytes, enquanto que o padrão IEC considera que este deve ser um kibibyte. Resumindo: k e K = 1024 bytes.

Windows: Estou recebendo timeouts de conexão quando utilizo localhost ao passo que "127.0.0.1" funciona?

Antes do PHP 5.3.4, existia um bug no código de resolução de rede dentro do PHP que causava erros usando localhost em todas as situações relacionadas a stream se o IPv6 estivesse habilitado. Para solucionar este problema você pode utilizar tanto "127.0.0.1" como desabilitar a resolução IPv6 no arquivo hosts.

add a note add a note

User Contributed Notes 4 notes

up
2
kjn
8 years ago
64.16 Byte Values

The number that precedes K, M, or G should be an integer.

E.g. this php.ini directive:
   post_max_size = 0.25M
is interpreted as 0, and thus prevents all POSTs.

It is particularly unhelpful that phpinfo() reports the string value assigned to post_max_size (0.25M), and not the numerical value that PHP extracts from that string (0M).
up
2
thierrybo
1 month ago
Using php 5.4.27 memory_limit = -1 does not give unlimited memory but actually 10485760 bytes (or 10M)
up
1
info at zankmusic dot com
6 years ago
Just spent a couple days on this one...
As previously posted, if you set
upload_max_filesize = 0.25M, the value reads correctly in phpinfo(), BUT it is effectively ZERO when implemented.

Note that the following also give ZERO bytes:

upload_max_filesize =  10M  (note the two white spaces before 10M), but the phpinfo() reads '10M' and everything looks ok.

I removed all white spaces in my php.ini file and viola...working fine again.
up
0
greenie2600 at yahoo dot com
7 years ago
Here's a simple function that will convert the shorthand values described in point 64.16 to a number of bytes.

I use this to display the maximum size of file uploads to the user, so they don't waste time uploading a huge file only to find that it's too big. (I've been unable to find any browsers that actually support the MAX_FILE_SIZE technique described in chapter 38, and it's certainly not part of any W3C spec, so this is the next best thing.)

Here's how you'd use my function for that purpose (though you might want to abstract this to a function of its own):

<?php
echo 'Maximum file size: ' . convertBytes( ini_get( 'upload_max_filesize' ) ) / 1048576 . 'MB';
?>

And here's the function:

<?php
/**
* Convert a shorthand byte value from a PHP configuration directive to an integer value
* @param    string   $value
* @return   int
*/
function convertBytes( $value ) {
    if (
is_numeric( $value ) ) {
        return
$value;
    } else {
       
$value_length = strlen( $value );
       
$qty = substr( $value, 0, $value_length - 1 );
       
$unit = strtolower( substr( $value, $value_length - 1 ) );
        switch (
$unit ) {
            case
'k':
               
$qty *= 1024;
                break;
            case
'm':
               
$qty *= 1048576;
                break;
            case
'g':
               
$qty *= 1073741824;
                break;
        }
        return
$qty;
    }
}
?>
To Top