PHP - Alcides Maya
Transcrição
PHP - Alcides Maya
PHP ESCOLA Linguagem de Programação II (PHP) 1 Escola Alcides Maya - Segundo Módulo 1. INTRODUÇÃO 1.1. O QUE É PHP? PHP significa: Hypertext Preprocessor. Realmente, o produto foi originalmente chamado de “Personal Home Page Tools”; mas como se expandiu em escopo, um nome novo e mais apropriado foi escolhido por votação da comunidade. Você pode utilizar qualquer extensão que desejar para designar um arquivo PHP, mas os recomendados foram .php , .phtml. O PHP está atualmente na versão 5, chamado de PHP5 ou, simplesmente de PHP. PHP é uma linguagem de criação de scripts embutida em HTML no servidor. Os produtos patenteados nesse nicho do mercado são as Active Server Pages da Microsoft, o Coldfusion da Allaire e as Java Server Pages da Sun. Exploraremos a criação de script no servidor, mais profundamente, nos próximos capítulos, mas, no momento, você pode pensar no PHP como uma coleção de supertags de HTML que permitem adicionar funções do servidor às suas páginas da Web. Por exemplo, você pode utilizar PHP para montar instantaneamente uma complexa página da Web ou desencadear um programa que automaticamente execute o débito no cartão de crédito quando um cliente realizar uma compra. Falando estritamente, o PHP tem pouca relação com layout, eventos ou qualquer coisa relacionada à aparência de uma página da Web. De fato, a maior parte do que o PHP realiza é invisível para o usuário final. Alguém visualizando uma página de PHP não será capaz de dizer que não foi escrita em HTML, porque o resultado final do PHP é HTML. O PHP é um módulo oficial do servidor HTTP Apache, o líder do mercado de servidores Web livres que constitui aproximadamente 55% dos sites da Internet. Isso significa que o mecanismo de script do PHP pode ser construído no próprio servidor Web, tornando a manipulação de dados mais rápida. Assim como o servidor Apache, o PHP é compatível com várias plataformas, o que significa que ele executa em seu formato original em várias versões do UNIX e do Windows. Todos os projetos sob a égide da Apache Software Foundation – incluindo o PHP – são software de código-fonte aberto. História do PHPRasmus Lerdorf – engenheiro de software, membro da equipe Apache e o homem misterioso do ano – é o criador e a força motriz original por trás do PHP. A primeira parte do PHP foi desenvolvida para utilização pessoal no final de 1994. Tratava-se de um wrapper de PerlCGI que o auxiliava a monitorar as pessoas que acessavam o seu site pessoal. No ano seguinte, ele montou um pacote chamado de Personal Home Page Tools (também conhecido como PHP Construction Kit) em resposta à demanda de usuários que por acaso ou por relatos falados depararam-se com o seu trabalho. A versão 2 foi logo lançada sob o título de PHP/FI e incluía o Form Interpreter, uma ferramenta para analisar sintaticamente consultas de SQL. Em meados de 1997, o PHP estava sendo utilizado mundialmente em aproximadamente 50.000 sites. Obviamente estava se tornando muito grande para uma única pessoa administrar, mesmo para alguém concentrado e cheio de energia como Rasmus. Agora uma pequena equipe central de desenvolvimento mantinha o projeto sobre o modelo de “junta benevolente” do código-fonte aberto, com contribuições de desenvolvedores e usuários em todo o mundo. Zeev Suraski e Andi Gutmans, dois programadores israelenses que desenvolveram os analisadores de sintaxe PHP3 e PHP4, também generalizaram e estenderam seus trabalhos sob a rubrica de Zend.com (Zeev, Andi, Zend, entendeu?).O quarto trimestre de 1998 iniciou um período de crescimento explosivo para o PHP, quando todas as tecnologias de código-fonte aberto ganharam uma publicidade intensa. Em outubro de 1998, de acordo com a melhor suposição, mais de 100.000 domínios únicos utilizavam PHP de alguma maneira. Um ano depois, o PHP quebrou a marca de um milhão de domínios. Enquanto escrevo esta apostila, o número explodiu para cerca de dois milhões de domínios. 1.2. O que pode ser feito com php? Basicamente, qualquer coisa que pode ser feita por algum programa CGI pode ser feita também com PHP, como coletar dados de um formulário, gerar páginas dinamicamente ou enviar e receber cookies. PHP também tem como uma das características mais importantes o suporte a um grande número de bancos de dados, como dBase, Interbase, mSQL, mySQL, Oracle, Sybase, PostgreSQL e vários outros. Construir uma página baseada em um banco de dados torna-se uma tarefa extremamente simples com PHP. Além disso, PHP tem suporte a outros serviços através de protocolos como IMAP, SNMP, NNTP, POP3 e, logicamente, HTTP. Ainda é possível abrir sockets e interagir com outros protocolos. 2 PHP 2. SINTAXE BÁSICA DO PHP 2.1. Introdução O PHP empresta um pouco de sua sintaxe de outras linguagens como o C, shell, Perl e até mesmo Java. É realmente um linguagem híbrida, pegando as melhores características de outras liguagens, criando uma linguagem de script fáil de usar. Ao término deste capítulo, você terá aprendido: · A estrutura básica do PHP · Como o PHP pode ser embutido no HTML · Como escrever comentários · Trabalhar com variáveis e tipos básicos de dados · Definir constantes para valores simples · As estruturas de controle mais comuns, a maioria das quais estão disponíveis em outras linguagens de programação · Funções pré definidas ou definidas pelo usuário. 2.2 misturando php e html A primeira coisa que se deve saber é como utilizar o PHP dentro do HTML. <HTML> <HEAD>Sample PHP Script</HEAD> <BODY> The following prints “Hello, World”: <?php print “Olá, Mundo”; ?> </BODY> </HTML> Neste exemplo, vê-se que o código PHP se encaixa no seu HTML. Toda a vez que o Interpretador PHP encontra uma tag de abertura PHP <?php, ele executa o código dentro da tag até o delimitador ?>. O PHP então substitui o código com a sua saída (se houver alguma) enquanto quaisquer textos não-PHP (como o HTML) é passado do jeito que está para o cliente web. Assim sendo, o script do exemplo levaria a sequinte saída: <HTML> <HEAD>Sample PHP Script</HEAD> <BODY> A seguir, escreve “ Olá, Mundo”: Olá, Mundo </BODY> </HTML> Dica: Pode-se utilizar a abreviação <? como tag de abertura para um código PHP se a opção short_open_tags do arquivo php.ini for habilitada; entretanto, esse tipo de abreviação não é recomendada e está desabilitada por padrão, apesar de que na maioria dos serviços de hospedagem esta opção está habilitada. 2.2. Comentários O próximo tópico a ser abordado é como escrever comentários, pois a maioria dos exemplos deste capítulo possui comentários. Pode-se escrever comentários de 3 maneiras diferentes: · Padrão C /* Este é um comentário no padrão C 3 Escola Alcides Maya - Segundo Módulo * que pode ser separado em multiplas * linhas até chegar a tag de fechamento */ · Padrão C++ // Este é um comentário no padrão C++ que termina ao fim da linha · Padrão shell # Este é um comentário no padrão shell que termina ao fim da linha 2.3. Variáveis Variáveis no PHP são bem diferentes daquelas em linguagens compiladas como C e Java. A razão disto é a natureza fraca de tipagem do PHP, que em resumo significa que não existe a necessidade de declarar variáveis antes de usá-las, não é necessário declarar seu tipo e, como resultado, uma variável pode mudar o tipo de seu valor tanto quanto necessário. Variáveis no PHP são precedidas com sinal de $, e de modo similar a maioria das linguagens modernas, elas podem iniciar com uma letra (A-Za-z) ou _ (underline) e podem conter tantos caracteres alfanuméricos quantos forem necessários. Exemplos de nomes válidos de variáveis: $count $_Obj $A123 Exemplos de nomes inválidos de variáveis incluem: $123 $*ABC Como mencionado anteriormente, não existe a necessidade de declarar variáveis ou seus tipos antes de utilizá-las em PHP. O código abaixo exemplifica o uso de variáveis: $PI = 3.14; $raio = 5; $circunferencia = $PI * 2 * $raio; Pode-se ver que nenhuma das variáveis foi declarada antes de serem usadas. Além disso, o fato de que $PI é um número decimal, e $raio (um inteiro) não são declarados antes de serem inicializadas. PHP não oferece suporte como muitas outras linguagens de programação (exceto para algumas variáveis especiais prédefinidas, que serão discutidas posteriormente). Variáveis são locais a seu escopo, e se forem criadas em uma função, elas estarão disponíveis apenas durante o tempo de vida da função. Variáveis que são criadas no script principal (não estão em uma função) não são variáveis globais; não podem ser vistas dentro de funções, mas você pode acessá-las utilizando o array especial $GLOBALS[], utilizando o nome da variável como índice do vetor. O exemplo anterior poderia ser reescrito da seguinte forma: $PI = 3.14; $raio = 5; $circunferencia = $GLOBALS[“PI”] * 2 * $GLOBALS[“raio”]; Pode-se perceber que mesmo estando este código dentro do escopo principal (não utilizou-se nenhuma função), ainda pode-se fazer uso de $GLOBALS[], apesar de que neste caso não trazer vantagem alguma. 2.3.1. REFERÊNCIAS INDIRETAS A VARIÁVEISUma característica extremamente útil do PHP é que você pode acessar variáveis utilizando referências indiretas, ou para ser mais claro, você pode criar e acessar variáveis em tempo de execução. Considere o seguinte exemplo: $nome = “Rafael”; $$nome = “Usuário registrado”; print $Rafael; Este código resulta na escrita de “Usuário Registrado”. A linha em negrito utiliza um $ adicional para acessar a variável com o nome especificado pelo valor de $name (“Rafael”) e muda o seu valor para “Usuário registrado”. Assim sendo, uma variável chamada $Rafael é criada. 4 PHP Pode-se utilizar quantos níveis de ações indiretas forem desejados apenas colocando um símbolo $ adicional na frente de uma variável. 2.3.2. Gerenciando variáveis Três construtores de linguagem são utilizados para gerenciar variáveis. Eles permite checar se determinada variável existe, remover variáveis, e verificar os valores reais de variáveis. 2.3.2.1. Isset() Isset() determina se uma certa variável já foi declarada pelo PHP. Retorna um valor booleano true caso a variável já tenha sido setada, e false em caso contrário ou se o valor da variável é NULL. Considere o seguinte script: If (isset($primeiro_nome)) { print ‘$primeiro_nome está setada’; } Este código verifica se a variável $primeiro_nome está definida. Se $primeiro_nome está definida, isset() retorna true, oq vai acarretar em mostrar ‘$primeiro_nome está setada’. Caso contrário, nenhuma saída é gerada. l Checking an array element: if (isset($arr[“offset”])) { ... } l Checking an object property: if (isset($obj->property)) { ... } Nota-se que nos dois exemplos acima, $arr ou $obj não foram testados para sua existência (antes de verificar ‘offset’ ou propriedade, respectivamente). A função isset() retorna false automaticamente se eles não estiverem setados. isset() é a única dos 3 construtores de linguagem que aceita uma quantidade arbitrária de parâmetros. O seu protótipo mais exato está descrito abaixo: isset($var1, $var2, $var3, ...); Somente retorna true se todas as variáveis foram definidas; de outro modo, retorna false. Isto é útil quando deseja-se verificar se as variáveis de entrada de um script foram realmente enviadas para o cliente, “economizando” assim uma série de verificações isset() separadas. 2.3.2.2 unset() unset() “desdeclara” uma variável previamente setada, e libera quaisquer memória que foi utilizada por, desde que nenhuma outra variável referencie o seu valor. Uma chamada para isset() em uma variável em que se utilizou unset() retorna false. Por exemplo: $name = “John Doe”; unset($name); if (isset($name)) { print ’$name is set’; } Este exemplo não gera nenhuma saída, pois isset() retorna false. unset() também pode ser utilizada em arrays e propriedades de objetos de modo similar a isset(). 5 Escola Alcides Maya - Segundo Módulo 2.3.2.3 empty() empty() pode ser utilizado para verificar se uma variável não foi declarada ou o seu valor é false. Este construtor de linguagem é utilizado normalmente para verificar se uma variável de formulário não foi enviada ou não contém dados. Ao verificar pelo valor verdadeiro da variável, o valor da mesma é primeiramente convertido para um Boolean de acordo com as regras na seguinte secção de código, e então é verificado por true/false. Por Exemplo: if (empty($name)) { print ‘Error: Forgot to specify a value for $name’; } Este código imprime uma mensagem de erro se $name não contém um valor que possa retornar true. 2.3.3 superglobals Como regra geral, o PHP não suporta variáveis globais (variáveis que podem ser acessadas em qualquer escopo). Porém, certas variáveis internas especiais comportam-se como variáveis globais similares em outras linguagens. Essas variáveis são chamadas superglobais e são predefinidas pelo PHP para o programador poder utilizar. Alguns exemplos dessas superglobais são: l $_GET[] - Um array que inclui todas as variáveis GET que o PHP recebe do navegador do cliente, sendo essas vindas de formulários ou links. l $_POST[] - Um array que inclui todas as variáveis POST que o PHP recebe do navegador do cliente. l $_COOKIE[] - Um array que inclui todos os COOKIES que o PHP recebe do navegador do cliente. l $_SESSION[] - Um array que contém todas as variáveis de sessão, definidas pelo programa. l $_REQUEST[] - Um array que contém todas as variáveis dos métodos anteriores, sem fazer distinção da origem. l $_ENV[] - Um array com as variáveis de ambiente. l $_SERVER[] - Um array com os valores das variáveis do servidor WEB. É importante lembrar que você pode acessar essas variáveis em qualquer lugar do script em qualquer função, método ou escopo global. Não é necessário usar o array $_GLOBALS[], que permite o acesso a variáveis globais sem a necessidade de pré-declaração ou usando a palavra-chave ultrapassada globals. 2.4 tipos básicos de dados Existem oito tipos diferentes de dados em PHP, cinco dos quais são escalares e cada um dos três tipos diferentes tem suas próprias características. As variáveis previamente discutidas podem conter valores de cada um desses tipos de dados sem declarar explicitamente o tipo. As variáveis comportam-se de acordo com o tipo de dado que contém. 2.4.1 integer Integers são números inteiros equivalentes em amplitude ao tipo long em C. Na maioria dos computadores comuns isto significa um número signed de 32bits com uma amplitude entre -2.147.483.648 até +2.147.483.647. Inteiros podem ser escritos nas notações decimal, hexadecimal (prefixo 0x), e notação octal (prefixo 0), e podem incluir sinais de + ou -. Alguns exemplos de inteiros incluem: 240000 0xABCD 007 -100 2.4.2 números floating-point. Números floating-point (também conhecidos como números reais) representam números reais e são equivalentes ao tipo de dado double em C. Na maioria das plataformas, o tamanho do tipo de dado é 8 bytes e sua amplitude é aproximadamente 2.2E-308 até 1.8E-308. Números de ponto flutuante incluem um ponto decimal e podem incluir um sinal +/- e um sinal de exponenciação. 6 PHP Exemplos de números de ponto flutuante incluem: 3.14 +0.9e-2 -170000.5 54.6E42 2.4.3 strings Strings em PHP são uma cadeia de caracteres que são terminadas internamente em null. Entretanto, diferentemente de outras liguagens, como o C, o PHP não se baseia no null final para calcular o tamanho de uma string, mas memoriza o tamanho internamente. Isto permite uma manipulação mais fácil de dados binários em PHP – por exemplo, criar uma imagem “on-the-fly” e mostrá-la no navegador. O tamanho máximo de strings varia de acordo com a plataforma e compilador C, mas você pode esperar que suporte pelo menos 2GB. Não escreva programas para testar este limite, pois você provavelmente vai atingir o limite de memória. Quando da escrita de valores string no código-fonte, pode-se utilizar aspas duplas (“), aspas simples (‘) ou “here-docs” para delimitá-las. Cada método é explicado abaixo. 2.4.3.1 EXEMPLOS DE USO DAS ASPAS DUPLAS “PHP: Hypertext Pre-processor” “GET / HTTP/1.0\n” “1234567890” Strings podem conter praticamente todos os caracteres. Alguns caracteres não podem ser escritos como são e necessitam uma notação especial: \n Nova linha \t Tabulação \” Aspa dupla \\ Contra-barra \0 ASCII 0 (nulo) \r Nova linha \$ Escapa o sinal $ para que assim ele não seja tratado como uma variável, mas como o caracter $. \{Octal #} O caracter representado pelo octal especificado em # - Por exemplo, \70 representa a letra 8. \x{Hexadecimal #} O caracter representado pelo hexadecimal especificado em # - por exemplo, \0x32 representa a letra 2. Uma característica adicional das strings com aspas-duplas é que certas notações de variáveis e expressões podem ser embutidas diretamente dentro delas. Sem entrar em detalhes, seguem alguns exemplos de strings válidas que possuem variáveis embutidas. As referências para variáveis são automaticamente substituídas com os valores das variáveis, e se esses valores não são strings, eles são convertidos para as suas representações correspondentes como strings (por exemplo, o integer 123 seria primeiramente convertido para a string “123”). “O resultado é $resultado\n” “O índice $i do array contém $arr[$i]” Em certos casos, onde há necessidade de concatenar strings com valores (assim como variáveis e expressões) e essa sintaxe não for suficiente, você pode usar o operador . (ponto) para concatenar duas ou mais strings. 2.4.3.2 ASPAS SIMPLES Além das aspas duplas, aspas simples também podem ser utilizadas para delimitar strings. Entretanto, em contraste com as aspas duplas, aspas simples não suportam todas as expressões de escape e de substituição de variáveis das aspas duplas. A tabela abaixo mostra as duas únicas expressões de escape suportadas pelas aspas simples. \’ Aspa simples \\ Contrabarra utilizada quando existe a necessidade de representar uma contrabarra seguida por uma aspa simples – por exemplo, \\’ 7 Escola Alcides Maya - Segundo Módulo Exemplos: ‘Olá, Mundo’ ‘É uma linda queda d\’água’ 2.5.3.3 HERE-DOCS Here-docs possibilitam que o programador utilize grandes quantidades de texto embutida em seus scripts, o que pode incluir muitas aspas duplas e simples, sem a necessidade de estar constantemente escapando-as. O trecho aseguir é um exemplo de here-doc: <<<O_FIM O ornitorrinco (Ornithorhynchus anatinus) é um mamífero monotremado, endémico da Austrália. É um animal semiaquático e nocturno que habita rios e cursos de água. O_FIM A string inicia com <<<, seguida pela string que o programador sabe que não aparece no texto. É encerrada escrevendo essa string no início da linha, seguida por um ponto-e-vírgula (;) opcional, a então uma nova linha obrigatória (\n). O escape de caracteres e substituição de variáveis in here-docs é idêntica as strings em aspas duplas exceto que não é necessário o escape de aspas duplas. 2.4.4 booleans Booleans foram introduzidos pela primeira vez no PHP4 e não existiam em versões anteriores. Um valor boolean pode ser tanto true ou false. Como mencionado anteriormente, o PHP automaticamente converte tipos quando necessário. Boolean é provavelmente o tipo que outros tipos são mais convertidos por detrás da cena. Isto acontece por que, em qualquer código condicional como construção if, laços e assim por diante, tipos são convertidos para este tipo de valor escalar para verificar se a condição é satisfeita. O resultado de operadores de comparação também é um valor boolean. Considerando o seguinte fragmento de código: $numerador = 1; $denominador = 5; if ($denominador == 0) { print “O denominador deve ser um valor diferente de 0”; } O resultado do operador “igual a” é um boolean; neste caso, seria false e, assim sendo, a construção if() não seria acessada. Agora, considando-se o seguinte fragmento de código: $numerador = 1; $denominador = 5; if ($denominador) { /* Realiza o cálculo */ } else { print “O denominador deve ser uma valor diferente de 0\n”; } Pode-se ver que nenhuma comparação foi utilizada nesse exemplo; como sempre, o PHP automaticamente converteu internamente $denominador ou, para ser mais exato, o valor 5 para o seu equivalente boolean, true, para executar a construção if() e, assim sendo, realizando o cálculo. Mesmo que todos os tipos ainda não tenham sido vistos, a tabela abaixo mostra os “valores-verdade” para os seus valores. Recomenda-se voltar a esta tabela para verificar os valores boolean equivalentes para cada tipo, conforme eles forem sendo explicados 8 PHP Tipo de dado Integer Floating-point Strings Null Array Valores false 0 0.0 Strings vazias “” Sempre Se estiver vazia Valores true Todos os valores diferentes de 0 Todos os valores diferentes de 0 Todas as outras strings Nunca Se contiver pelo menos um elemento. 2.4.5 Null Null é um tipo de dados com apenas um valor possível: o valor NULL. Ele marca variáveis como estando vazias, e é especialmente útil para diferenciar entre a string vazia e valores null vindos de bancos de dados. O operador do PHP isset($variavel) retorna false para NULL, e true para quaisquer outros tipos de dados, desde que a variável que esteja sendo testada exista. Exemplo: $exemplo = NULL; 2.4.6 Resources Resources, um tipo especial de dado, representando um recurso de uma extensão PHP como uma consulta em um banco de dados, um arquivo aberto, uma conexão ao banco de dados, e muitos outros tipos externos. As variáveis deste tipo nunca são tocadas pelo programador, mas passadas para as funções relevantes que sabem como interagir com o recurso especificado. 2.4.7 ARRAYS Um array em PHP é uma coleção de pares chave/valor. Isto significa que ele mapeia chaves (ou índices) para valores. Índices de arrays podem ser integers ou strings enquanto valores podem ser de qualquer tipo (incluindo outros arrays). Dica: Arrays em PHP são implementados usando tabelas mistas, o que significa que acessar um valor tem uma média de complexibilidade de 0. 2.4.7.1 CONSTRUTOR ARRAY() Arrays podem ser declarados utilizando o construtor de linguagem array(), que geralmente possui a seguinte forma (elementos dentro de colchetes, [], são opcionais): array([chave =>] valor, [chave =>] valor, ...) A chave é opcional, e quando não é especificada, a chave automaticamente recebe o maior valor da chave anterior + 1 (começando em 0). Pode-se intercalar o uso com declaração ou não de chaves mesmo sendo na mesma declaração de array. O valor em sí pode ser de qualquer tipo do PHP, incluíndo um array. Arrays contendo arrays fornecem um resultado similar a arrays multidimensionais em outras linguagens de programação. Seguem alguns exemplos: l array(1, 2, 3) é o mesmo que o mais explícito array(0 => 1, 1 => 2, 2 => 3). l array(“nome” => “Petrônio”, “idade” => 28) l array(1 => “UM”, “DOIS”, “TRES”) é equivalente a array(1 => “UM”, 2 => “DOIS”, 3 => “TRES”). l array() um array vazio. E um exemplo de arrays aninhados l array(array(“nome” => “João”, “idade” => 28), array(“nome” => “Bárbara”, “idade” => 67)) O exemplo anterior demonstra um array com dois elements: cada um com uma coleção (array) de informações de uma pessoa. 2.4.7.2 ACESSANDO ELEMENTOS DO ARRAY Elementos do array podem ser acessados utilizando a notação $arr[key], onde key é tanto uma expressão integer ou string. Quando do uso de uma constante string como chave, deve-se lembrar as aspas simples ou duplas, como em $arr[“key”]. Esta notação pode ser usada tanto para ler elementos de um array e modificá-los ou criar novos elementos. 9 Escola Alcides Maya - Segundo Módulo 2.5.7.3 MODIFICANDO/CRIANDO ELEMENTOS DE UM ARRAY $arr1 = array(1, 2, 3); $arr2[0] = 1; $arr2[1] = 2; $arr2[2] = 3; print_r($arr1); print_r($arr2); A função print_r() ainda não foi vista, mas quando recebe um array, ela escreve o conteúdo do array de uma maneira legivel. Pode-se usar essa função quando da depuração dos scripts. O exemplo anterior escreve Array ( [0] => 1 [1] => 2 [2] => 3 ) Array ( [0] => 1 [1] => 2 [2] => 3 ) Então, vê-se que podem ser utilizados tanto o construtor array() e a notação $arr[key] para criar arrays. Normalmente, array() é utilizado para declarar arrays cujos elementos são conhecidos na compilação do código, e a notação $arr[key] é utilizada quando os elementos são computados em tempo de execução. O PHP também suporta uma notação especial, $arr[], onde a chave não é especificada. Quanto cria novos offsets de arrays utilizando essa notação (por exemplo, utilizando ela como o valor l), a chave é automaticamente setada como o valor diretamente posterior a maior chave anterior. Assim sendo, o exemplo anterior pode ser reescrito como: $arr1 = array(1, 2, 3); $arr2[] = 1; $arr2[] = 2; $arr2[] = 3; O resultado é o mesmo que no exemplo anterior. O mesmo é verdade quando utilizamos arrays com chaves string: $arr1 = array(“name” => “John”, “age” => 28); $arr2[“name”] = “John”; $arr2[“age”] = 28; if ($arr1 == $arr2) { print ‘$arr1 e $arr2 são iguais’ . “\n”; } A mensagem confirmando a igualdade dos dois arrays é escrita. 2.4.7.4 Lendo valores de arrays Pode-se utilizar a notação $arr[key] para ler valores de array. Os próximos exemplos foram construídos no exemplo anterior: print $arr2[“name”]; if ($arr2[“age”] < 35) { print “ é jovem\n”; 10 PHP } Este exemplo escreve John é jovem Nota: Como mencionado anteriormente, utilizar a sintaxe $arr[] não é suportado quando se lê índices de array, mas apenas ao escrevê-los. 2.4.7.5 Acessando arrays aninhados (ou arrays multi-dimensionais) Quando se acessa arrays aninhados, pode-se adicionar quantos colchetes quanto necessário para alcançar o valor relevante. Segue um exemplo de como declarar arrays aninhados: $arr = array(1 => array(“name” => “John”, “age” => 28), array(“name” => “Barbara”, “age” => 67)) Pode-se obter o mesmo resultado com as seguintes construções: $arr[1][“name”] = “John”; $arr[1][“age”] = 28; $arr[2][“name”] = “Barbara”; $arr[2][“age”] = 67; A leitura de um array aninhado é trivial quando se utiliza a mesma notação. Por exemplo, se você quer imprimir na tela a idade de John, a seguinte construção faz o truque: print $arr[1][“age”]; 2.4.7.6 Atravessando arrays utilizando foreach() Existem algumas maneiras diferentes de realizar uma iteração por um array. A mais elegante é o construtor do laço foreach(). A sintaxe padrão deste laço é foreach($array as [$chave =>] [&] $valor) ... $chave é opcional, e quando especificada, ela contém o valor da chave correntemente iterado do valor da chave, dependendo do tipo da chave. Ao especificar & para o valor também é opcional, e deve ser especificado caso se planeje modificar $valor e quer propagar isso para $array. Na maioria dos casos, não se quer modificar o $valor quando iterando sobre um array e então, assim sendo, não há necessidade de especificá-lo. Temos aqui um exemplo simples de um laço foreach(): $players = array(“John”, “Barbara”, “Bill”, “Nancy”); print “The players are:\n”; foreach ($players as $key => $value) { print “#$key = $value\n”; } A saída deste exemplo é: The players are: #0 = John #1 = Barbara #2 = Bill #3 = Nancy Agora temos um exemplo mais complicado que realizada uma iteração sobre um array de pessoas e marca qual pessoa é considerada idosa e qual é considerada jovem: $people = array(1 => array(“name” => “John”, “age” => 28), array(“name” => “Barbara”, “age” => 67)); foreach ($people as &$person) { if ($person[“age”] >= 35) { $person[“age group”] = “3ª idade”; } else { 11 Escola Alcides Maya - Segundo Módulo $person[“age group”] = “Jovem”; } } print_r($people); Novamente, este código faz uso da função print_r(). A saída do código anterior é a seguinte: Array ( [1] => Array ( [name] => John [age] => 28 [age group] => Jovem ) [2] => Array ( [name] => Barbara [age] => 67 [age group] => 3ª idade ) ) 2.5.8 Constantes No PHP, pode-se definir nomes, chamados constantes, para valores simples. Como o nome implica, esses valores não podem ser mudados, uma vez que representam um determinado valor. Os nomes para constantes seguem as mesmas regras que variáveis PHP exceto que constantes não possuem um sinal de cifrão na frente ($). Uma prática comum em muitas linguagens de programação – incluíndo o PHP – é utilizar letras maiúsculas para nomes de constantes, mas não é obrigatório. Se for o desejado, mas não é recomendado, pode-se definir constantes para não diferenciar maísculas/minúsculas, assim não requerendo um código para corrigir o nome se fizer referência a uma constante. Dica: Utilize apenas constantes com diferenciação de maiúsculas/minúsculas tanto para ser consistente com padrões de desenvolvimento e também por ser incerto se constantes sem diferenciação continuarão tendo suporte em versões futuras do PHP. Diferentemente de variáveis, constantes, quando definidas, são acessiveis globalmente. Não se deve (e não se pode) redeclará-las em cada nova função e/ou arquivo PHP. Para definir uma constante, utiliza-se a seguinte função: define(“NOME_DA_CONSTANTE”, valor [, diferenciar]) Onde: l “NOME_DA_CONSTANTE” é uma string. l valor é qualquer expressão PHP válida, exceto arrays e objetos. l diferenciar é um Boolean (true, false) e é opcional. O padrão é true Um exemplo para uma constante pré-definida é o valor Boolean true, que é registrado sem diferenciar maíscula/ minúscula. Segue um exemplo simples de como definir e utilizar uma constante: define(“MY_OK”, 0); define(“MY_ERROR”, 1); ... if ($error_code == MY_ERROR) { print(“There was an error\n”); } 12 PHP 2.6 OPERADORES O PHP contém 3 tipos de operadores: unários, binários e um operador ternário. Operadores binários são utilizados em dois operadores: 2+3 14 * 3.1415 $i – 1 Estes são simples exemplos de expressões. PHP pode fazer operações binárias em dois operadores que possuam o mesmo tipo. Entretanto, se os dois operandos possuírem tipos diferentes, o PHP automaticamente converte um deles para o tipo do outro, seguindo as seguintes regras (exceto se especificado diferentemente, como no operador de concatenação). Type of One of the Operands Type of the Other OperandConversion Performed Integer Floating point O operando integer é convertido para o tipo floating point. Integer String A string é convertida para um número. Se o tipo da string convertida for um número real, o operando integer é convertido para um número real também. RealString A string é convertida para Real Booleans, nulls e resources agem como integers, e são convertidos do seguinte modo: l Boolean: False = 0, True = 1 l Null = 0 l Resource = O nº (id) do resource 2.6.1 Operadores Binários 2.6.1.1 Operadores Numéricos Todos os operadores binários (exceto pelo operador de concatenação) trabalham com operandos numéricos. Se um ou os dois dos operandos são strings, Booleans, nulls ou resources, eles são automaticamente convertidos para o seu equivalente numérico antes do cálculo ser realizado. Operador Nome Valor + Soma A soma entre dois operandos - SubtraçãoA diferença entre dois operandos * Multiplicação O produto de dois operandos / Divisão O quociente de dois operandos % Módulo O resto da divisão inteira. 2.6.1.2 Operador de concatenação (.) O operador de concatenação concatena duas strings. Este operador trabalha apenas em strings; entretanto, qualquer operando que não seja string, é primeiramente convertido para uma. O seguinte exemplo deve escrever “O ano é 2000”: $ano = 2000; print “O ano é “.$ano; O valor integer $ano é internamente convertido para a string “2000” antes de ser concatenado com o prefixo da string, “O ano é”. 2.6.2 OPERADOR DE ATRIBUIÇÃO Operadores de atribuição permitem ao programador escrever um valor para uma variável, O primeiro operando (aquele na esquerda do operador de atribuição) deve ser uma variável. O valor de uma atribuição é o valor final atribuído para a variável; por exemplo, a expressão $var = 5 tem o valor 5 (e atribui 5 para $var). Adicionalmente ao operador regular de atribuição =, diversos outros operadores de atribuição são compostos de um 13 Escola Alcides Maya - Segundo Módulo operador, seguido por um sinal de igual. Esses operadores compostos aplicam o operador pegando a variável na esquerda como o primeiro operando e o valor na direita como o segundo operando, e atribui o resultado da operação para a variável na esquerda. Por exemplo: $counter += 2; // Isto é identido a $counter = $counter + 2; $offset *= $counter; // Isto é idêntico a $offset = $offset * $counter A lista seguinte mostra os operadores de atribuição compostos: +=, -=, *=, /=, %=, ^=, .=, &=, |=, <<=, >>= 2.6.3 Operadores de comparação Operadores de comparação permitem ao programador determinar os relacionamentos entre dois operandos. Quando ambos os operandos são strings, a comparação é realizada da forma léxica. A comparação resulta em um Boolean. Para os seguintes operadores de comparação, conversões automáticas de tipo são realizadas, se necessário. Operador Nome Valor ==Igual a Verifica pela igualdade entre dois argumentos executando conversão de tipo quando necessário:1 == “1” resulta em true1 == 1 resulta em true != Diferente de O oposto de == > Maior queVerifica se o primeiro operando é maior que o segundo < Menor que Verifica se o primeiro operando é menor que o segundo >=Maior ou igual queVerifica se o primeiro operando é maior ou igual que o segundo <=Menor ou igual que Verifica se o primeiro operando é menor ou igual que o segundo Para os dois operadores seguintes, conversão automática de tipos não são permitidas e, assim sendo, ambos os tipos e valores são comparados. Operador Nome Valor ===Idêntico a O mesmo que == mas os tipos dos operandos devem ser os mesmos. Não ocorre conversão automática de tipos:1 === “1” resulta em false1 === 1 resulta em true !== Não identico a O oposto de === 2.6.4 Logical operators Operadores lógicos primeiramente convertem seus operandos para valores boolean e então executam a respectiva comparação. Operador &&, and ||, or Nome E lógico OU lógico xor XOR lógico Valor O resultado da operação lógica E entre os dois operandos O resultado da operação lógica OU entre os dois operandos O resultado da operação lógica XOR entre os dois operandos 2.6.5 Operadores unários Operadores unários agem em um operando. 14 PHP 2.6.7 OPERADOR DE NEGAÇÃO O operador de negação aparece antes do seu operando – por exemplo, !$var (! é o operador, $var o operando). Operador Nome Valor ! Negação lógica true se o valor testado do operando é false.false se o valor testado do operando é true. 2.6.8 OPERADORES DE INCREMENTO/DECREMENTO Operadores de incremento/decremento são únicos no sentido que eles operam apenas nas variáveis e não em qualquer valor. A razão disto é que além de calcular o valor resultante, o valor da variável muda também. Operador $var++ ++$var Nome Pós-incremento Pré-incremento Efeito em $var $var é incrementada em 1 $var é incrementada em 1 $var---$var Pós-decremento Pré-decremento $var é decrementada em 1 $var é decrementada em 1 Valor da expressão O valor anterior de $var. O novo valor de (incrementado em 1). O valor anterior de $var. O novo valor de (decrementado em 1). $var $var Como pode ser visto na tabela anterior, existe uma diferença no valor de pós e pré incremento. Entretanto, nos dois casos, $var é incrementada em 1. A única diferença é o valor para qual é avaliada e expressão incremental. Exemplo 1: $num1 = 5; $num2 = $num1++; // pós-incremento, $num2 igual o valor original de $num1 print $num1; // escreveu o valor de $num1, que agora é 6 print $num2; // escreveu o valor de $num2, que é o valor original de $num1, 5 Exemplo 2: $num1 = 5; $num2 = ++$num1; // pré-incremento, $num2 recebe o valor incremental de $num1 print $num1; // escreveu o valor de $num1, que agora é 6 print $num2; // escreveu o valor de $num2, que é o mesmo valor de $num1, 6 As mesmas regras se aplicam a pré- e pós-decremento. 2.6.9 O primeiro e único. operador ternário Um dos operadores mais elegante é o operador ?: (ponto de interrogacao). Seu formato é expressao_verdade ? expr1 : expr2 O operador avalia a expressao_verdade e verifica se retorna true. Se assim for, o valor da expressão avalia para o valor de expr1 (expr2 não é avaliada). Se o retorno for false, o valor da expressão avalia para o valor de expr2 (expr1 não é avaliado). Por exemplo, o trecho de código a seguir verifica se $a está setada (usando isset()) e mostra a mensagem de acordo: $a = 99; $mensagem = isset($a) ? ‘$a está setada’ : ‘$a não está setada’; print $message; Este exemplo, escreve o seguinte: $a está setada 15 Escola Alcides Maya - Segundo Módulo 2.7 Estruturas de controle O PHP dá suporte a uma variedade das mais comuns estruturas de controle disponíveis em outras linguagens de programação. Elas podem ser divididas basicamente em dois grupos: Estruturas de controle condicionais e estruturas de controle de laço. As estruturas de controle condicionais afetam o fluxo do programa e pulam determinadas partes do código de acordo com certos critérios, enquanto estruturas de controle de laços executam certo código um número arbitrário de vezes de acordo com o critério especificado. 2.7.1 Estruturas de controle condicionais Estruturas de controle condicionais são cruciais ao permitir que o programa tome diferentes caminhos na execução baseado naas decisões que são tomadas em tempo de execução. O PHP suporta os controles condicionais if e switch. 2.7.1.1 Comandos if O mais trivial dos comandos condicionais é o if. Ele testa a condição e executa o comando indicado se o resultado for true (valor diferente de zero). Ele possui duas sintaxes: if (expressão) comando; if (expressão): comando; ... comando; endif; Para incluir mais de um comando no if da primeira sintaxe, é preciso utilizar um bloco, demarcado por chaves. O else é um complemento opcional para o if. Se utilizado, o comando será executado se a expressão retornar o valor false (zero). Suas duas sintaxes são: if (expressão) comando; else comando; if (expressão): comando; ... comando; else comando; ... comando; endif; A seguir, temos um exemplo do comando if utilizado com else: if ($a > $b) $maior = $a; else $maior = $b; O exemplo acima coloca em $maior o maior valor entre $a e $b Em determinadas situações é necessário fazer mais de um teste, e executar condicionalmente diversos comandos ou blocos de comandos. Para facilitar o entendimento de uma estrutura do tipo: if (expressao1) comando1; else if (expressao2) comando2; else 16 PHP if (expressao3) comando3; else comando4; Foi criado o comando, também opcional elseif. Ele tem a mesma função de um else e um if usados sequencialmente, como no exemplo acima. Num mesmo if podem ser utilizados diversos elseif’s, ficando essa utilização a critério do programador, que deve zelar pela legibilidade de seu script. O comando elseif também pode ser utilizado com dois tipos de sintaxe. Em resumo, a sintaxe geral do comando if fica das seguintes maneiras: if (expressao1) comando; [ elseif (expressao2) comando; ] [ else comando; ] if (expressao1) : comando; ... comando; [ elseif (expressao2) comando; ... comando; ] [ else comando; ... comando; ] endif; 2.7.1.2 Comandos switch O comando switch atua de maneira semelhante a uma série de comandos if na mesma expressão. Frequentemente o programador pode querer comparar uma variável com diversos valores, e executar um código diferente a depender de qual valor é igual ao da variável. Quando isso for necessário, deve-se usar o comando switch. O exemplo seguinte mostra dois trechos de código que fazem a mesma coisa, sendo que o primeiro utiliza uma série de if’s e o segundo utiliza switch: if ($i == 0) print “i é igual a zero”; elseif ($i == 1) print “i é igual a um”; elseif ($i == 2) print “i é igual a dois”; switch ($i) { case 0: print “i é igual a zero”; break; case 1: print “i é igual a um”; break; case 2: print “i é igual a dois”; 17 Escola Alcides Maya - Segundo Módulo break; } É importante compreender o funcionamento do switch para não cometer enganos. O comando switch testa linha a linha os cases encontrados, e a partir do momento que encontra um valor igual ao da variável testada, passa a executar todos os comandos seguintes, mesmo os que fazem parte de outro teste, até o fim do bloco. por isso usa-se o comando break, quebrando o fluxo e fazendo com que o código seja executado da maneira desejada. Veremos mais sobre o break mais adiante. Veja o exemplo: switch ($i) { case 0: print “i é igual a zero”; case 1: print “i é igual a um”; case 2: print “i é igual a dois”; } No exemplo acima, se $i for igual a zero, os três comandos “print” serão executados. Se $i for igual a 1, os dois últimos “print” serão executados. O comando só funcionará da maneira desejada se $i for igual a 2. Em outras linguagens que implementam o comando switch, ou similar, os valores a serem testados só podem ser do tipo inteiro. Em PHP é permitido usar valores do tipo string como elementos de teste do comando switch. O exemplo abaixo funciona perfeitamente: switch ($s) { case “casa”: print “A casa é amarela”; break; case “arvore”: print “a árvore é bonita”; break; case “lampada”: print “joao apagou a lampada”; } 18 2.7.2 ESTRUTURA DE CONTROLE DE LAÇOS PHP Estruturas de controle de laços são usadas para repetir determinadas tarefas no programa, como iterar sobre um resultset de uma consulta ao banco de dados. 2.7.2.1 WHILE O while é o comando de repetição (laço) mais simples. Ele testa uma condição e executa um comando, ou um bloco de comandos, até que a condição testada seja falsa. Assim como o if, o while também possui duas sintaxes alternativas: while (<expressao>) <comando>; while (<expressao>): <comando>; ... <comando>; endwhile; A expressão só é testada a cada vez que o bloco de instruções termina, além do teste inicial. Se o valor da expressão passar a ser false no meio do bloco de instruções, a execução segue até o final do bloco. Se no teste inicial a condição for avaliada como false, o bloco de comandos não será executado. O exemplo a seguir mostra o uso do while para imprimir os números de 1 a 10: $i = 1; while ($i <=10) print $i++; 2.7.2.2 Do... while O laço do..while funciona de maneira bastante semelhante ao while, com a simples diferença que a expressão é testada ao final do bloco de comandos. O laço do..while possui apenas uma sintaxe, que é a seguinte: do { <comando> ... <comando> } while (<expressao>); O exemplo utilizado para ilustrar o uso do while pode ser feito da seguinte maneira utilizando o do.. while: $i = 0; do { print ++$i; } while ($i < 10); 2.7.2.3 For O tipo de laço mais complexo é o for. Para os que programam em C, C++ ou Java, a assimilação do funcionamento do for é natural. Mas para aqueles que estão acostumados a linguagens como Pascal, há uma grande mudança para o uso do for. As duas sintaxes permitidas são: for (<inicializacao>;<condicao>;<incremento>) <comando>; for (<inicializacao>;<condicao>;<incremento>) : <comando>; ... <comando>; endfor; As três expressões que ficam entre parênteses têm as seguintes finalidades: 1. Inicialização: comando ou sequencia de comandos a serem realizados antes do inicio do laço. Serve para inicializar 19 Escola Alcides Maya - Segundo Módulo variáveis. 2. Condição: Expressão booleana que define se os comandos que estão dentro do laço serão executados ou não. Enquanto a expressão for verdadeira (valor diferente de zero) os comandos serão executados. 3. Incremento: Comando executado ao final de cada execução do laço. Um comando for funciona de maneira semelhante a um while escrito da seguinte forma: <inicializacao> while (<condicao>) { comandos ... <incremento> } 2.7.3 Quebra de fluxo 2.7.3.1 BREAK O comando break pode ser utilizado em laços de do, for e while, além do uso já visto no comando switch. Ao encontrar um break dentro de um desses laços, o interpretador PHP para imediatamente a execução do laço, seguindo normalmente o fluxo do script. while ($x > 0) { ... if ($x == 20) { echo “erro! x = 20”; break; ... } } No trecho de código acima, o laço while tem uma condição para seu término normal ($x <= 0), mas foi utilizado o break para o caso de um término não previsto no início do laço. Assim o interpretador seguirá para o comando seguinte ao laço. 2.7.3.2 Continue O comando continue também deve ser utilizado no interior de laços, e funciona de maneira semelhante ao break, com a diferença que o fluxo ao invés de sair do laço volta para o início dele. Vejamos o exemplo: for ($i = 0; $i < 100; $i++) { if ($i % 2) continue; echo “ $i “; } O exemplo acima é uma maneira ineficiente de imprimir os números pares entre 0 e 99. O que o laço faz é testar se o resto da divisão entre o número e 2 é 0. Se for diferente de zero (valor lógico true) o interpretador encontrará um continue, que faz com que os comandos seguintes do interior do laço sejam ignorados, seguindo para a próxima iteração. 2.8 FUNÇÕES 2.8.1 Definindo funções A sintaxe básica para definir uma função é: function nome_da_função([arg1, arg2, arg3]) { Comandos; ... ; [return <valor de retorno>]; 20 PHP } Qualquer código PHP válido pode estar contido no interior de uma função. Como a checagem de tipos em PHP é dinâmica, o tipo de retorno não deve ser declarado, sendo necessário que o programador esteja atento para que a função retorne o tipo desejado. É recomendável que esteja tudo bem documentado para facilitar a leitura e compreensão do código. Para efeito de documentação, utiliza-se o seguinte formato de declaração de função: tipo function nome_da_funcao(tipo arg1, tipo arg2, ...); Este formato só deve ser utilizado na documentação do script, pois o PHP não aceita a declaração de tipos. Isso significa que em muitos casos o programador deve estar atento ao tipos dos valores passados como parâmetros, pois se não for passado o tipo esperado não é emitido nenhum alerta pelo interpretador PHP, já que este não testa os tipos. 2.8.2 Valor de retorno Toda função pode opcionalmente retornar um valor, ou simplesmente executar os comandos e não retornar valor algum. Não é possível que uma função retorne mais de um valor, mas é permitido fazer com que uma função retorne um valor composto, como listas ou arrays. 2.8.3 Argumentos É possível passar argumentos para uma função. Eles devem serdeclarados logo após o nome da função, entre parênteses, e tornam-se variáveis pertencentes ao escopo local da função. A declaração do tipo de cada argumento também é utilizada apenas para efeito de documentação. Exemplo: function imprime($texto){ echo $texto; } imprime(“teste de funções”); 2.8.3.1 Passagem de parâmetros por referência Normalmente, a passagem de parâmetros em PHP é feita por valor, ou seja, se o conteúdo da variável for alterado, essa alteração não afeta a variável original. Exemplo: function mais5($numero) { $numero += 5; } $a = 3; mais5($a); //$a continua valendo 3 No exemplo acima, como a passagem de parâmetros é por valor, a função mais5 é inútil, já que após a execução sair da função o valor anterior da variável é recuperado. Se a passagem de valor fosse feita por referência, a variável $a teria 8 como valor. O que ocorre normalmente é que ao ser chamada uma função, o interpretador salva todo o escopo atual, ou seja, os conteúdos das variáveis. Se uma dessas variáveis for passada como parâmetro, seu conteúdo fica preservado, pois a função irá trabalhar na verdade com uma cópia da variável. Porém, se a passagem de parâmetros for feita por referência, toda alteração que a função realizar no valor passado como parâmetro afetará a variável que o contém. Há duas maneiras de fazer com que uma função tenha parâmetros passados por referência: indicando isso na declaração da função, o que faz com que a passagem de parâmetros sempre seja assim; e também na própria chamada da função. Nos dois casos utiliza-se o modificador “&”. Vejamos um exemplo que ilustra os dois casos: function mais5(&$num1, $num2) { $num1 += 5; $num2 += 5; } $a = $b = 1; mais5($a, $b); /* Neste caso, só $num1 terá seu valor alterado, pois a passagem por referência está definida na declaração da função. */ mais5($a, &$b); /* Aqui as duas variáveis terão seus valores alterados. */ 2.8.3.2 ARGUMENTOS COM VALORES PRÉ-DEFINIDOS (DEFAULT) 21 Escola Alcides Maya - Segundo Módulo Em PHP é possível ter valores default para argumentos de funções, ou seja, valores que serão assumidos em caso de nada ser passado no lugar do argumento. Quando algum parâmetro é declarado desta maneira, a passagem do mesmo na chamada da função torna-se opcional. function teste($vivas = “testando”) { echo $vivas; } teste(); // imprime “testando” teste(“outro teste”); // imprime “outro teste” É bom lembrar que quando a função tem mais de um parâmetro, o que tem valor default deve ser declarado por último: function teste($figura = circulo, $cor) { echo “a figura é um “, $figura, “ de cor “ $cor; } teste(azul); /* A função não vai funcionar da maneira esperada, ocorrendo um erro no interpretador. A declaração correta é: */ function teste2($cor, $figura = circulo) { echo “a figura é um “, $figura, “ de cor “ $cor; } teste2(azul); /* Aqui a funcao funciona da maneira esperada, ou seja, imprime o texto: “a figura é um círculo de cor azul” */ 2.8.4 Contexto O contexto é o conjunto de variáveis e seus respectivos valores num determinado ponto do programa. Na chamada de uma função, ao iniciar a execução do bloco que contém a implementação da mesma é criado um novo contexto, contendo as variáveis declaradas dentro do bloco, ou seja, todas as variáveis utilizadas dentro daquele bloco serão eliminadas ao término da execução da função. 2.8.5 Escopo O escopo de uma variável em PHP define a porção do programa onde elapode ser utilizada. Na maioria dos casos todas as variáveis têm escopo global. Entretanto, em funções definidas pelo usuário um escopo local é criado. Uma variável de escopo global não pode ser utilizada no interior de uma função sem que haja uma declaração. Exemplo: $vivas = “Testando”; function Teste() { echo $vivas; } Teste(); O trecho acima não produzirá saída alguma, pois a variável $vivas é de escopo global, e não pode ser referida num escopo local, mesmo que não haja outra com nome igual que cubra a sua visibilidade. Para que o script funcione da forma desejada, a variável global a ser utilizada deve ser declarada. Exemplo: $vivas = “Testando”; function Teste() { global $vivas; echo $vivas; } Teste(); Uma declaração “global” pode conter várias variáveis, separadas por vírgulas. Uma outra maneira de acessar variáveis de escopo global dentro de uma função é utilizando um array pré-definido pelo PHP cujo nome é $GLOBALS. O índice para a variável referida é o proprio nome da variável, sem o caracter $. O exemplo acima e o abaixo produzem o mesmo resultado: Exemplo: $vivas = “Testando”; 22 PHP function Teste() { echo $GLOBALS[“vivas”]; // imprime $vivas echo $vivas; // não imprime nada } Teste(); 2.8.6 Variáveis estáticas Tal qual o C, PHP suporta a declaração de variáveis locais à função como estáticas (static). Esse tipo de variável permanece intácta entre chamadas de funções, mas são acessiveis apenas dentro da função em que são declaradas. Variáveis estáticas podem ser inicializadas, e essa inicialização ocorre apenas na primeira vez que a declaração da variável estática é alcançada. Segue um exemplo para o uso de uma variável estática que é inicializada apenas na primeira vez que a função é executada: function faz_algo() { static first_time = true; if (first_time) { /* Executa este código apenas na primeira vez a função é chamada. */ ... } /* Executa a lógica principal toda a vez que a função é chamada */ ... } 3. MANIPULANDO DADOS DE FORMULÁRIOS 3.1 - Introdução Um formulário HTML é apenas um “rosto bonito” para onde os usuários poderão inserir informações que serão interpretadas de alguma maneira por algum script do lado do servidor. E no nosso caso, esse script é um script PHP. Primeiro: antes para poder enviar as informações, seu formulário deve conter um botão “submit”, isso se consegue através do comando: <input type=submit value=”Texto do Botão”> Segundo: todos os campos que serão tratados no script PHP devem conter o parâmetro “NAME”, caso contrário, os dados não serão passados para o script PHP. Ex: <input type=text name=nome_do_campo> Como as informações do formulário são passadas para esse script PHP e como as informações do formulário enviado são tratadas, dependem de você. Existem 2 métodos como as informações podem ser passadas: GET e POST. O recomendável sempre, para todos os formulários é usar o método POST, onde os dados enviados não são visíveis nas URLs, ocultando possíveis importantes informações e permitindo o envio de longas informações. O GET é totalmente o contrário disso. 3.2. Como as informações chegam para o script php? Assuma o seguinte formulário: <form action=”script.php” method=”post”> Campo 1: <input type=text name=campo1><br> Campo 2: <input type=text name=campo2><br> 23 Escola Alcides Maya - Segundo Módulo <input type=submit value=”OK”> </form> Esse formulário usa o método POST para envio das informações, então em “script.php”: <?php echo “O valor de CAMPO 1 é: “ . $_POST[“campo1”]; echo “<br>O valor de CAMPO 2 é: “ . $_POST[“campo2”]; ?> Se o formulário tivesse sido enviado usando o método GET, você simplesmente usaria $_GET no lugar de $_POST. Dica: Em vez de usar $_GET ou $_POST você pode escrever a variável com o mesmo nome do campo do formulário (no exemplo, $campo1 e $campo2). Mas, esse uso não é recomendado, pois se a diretiva “register_globals” na configuração do seu PHP estiver desativada, as variáveis com nome dos campos dos formulários, terão um valor vazio. Uma solução para isso é usar a função import_request_variables no começo dos seus scripts que interpretam formulários. Essa função aceita 3 letras como argumentos: P, G e C, referentes a $_POST, $_GET e $_COOKIE respectivamente. Exemplo de uso: <?phpimport_ request_variables(“gP”);?>O que acontece? Exemplo: Você possui formulário com os campos “nome”, “endereço” e “idade”. Assuma que a diretiva “register_globals” do seu PHP esteja desligada, mas, você já havia programado o script usando as variáveis no escopo global, no lugar de $_POST. Adicionando aquela função no começo do script, as variáveis do seu formulário postado: $_POST[“nome”], $_POST[“endereco”] e $_POST[“idade”] serão extraídas cada para uma variável diferente: $nome, $endereco e $idade. 3.3 Elementos do formulário 3.3.1 Campos hidden Os campos hidden são usados para passar informações que não podem ser alteradas pelo usuário que estará inserindo informações no formulário. Por exemplo: você tem um site com sistema de login e o usuário quer alterar as informações de login dele. O script que irá manipular esse formulário, precisa saber o ID do usuário para poder alterar as informações no banco de dados, então esse ID é um campo hidden. Exemplo: hidden.html <form action=”hidden.php” method=”post”> <input type=hidden name=escondido value=”valor do escondido”> <input type=hidden name=id value=”111”> <input type=submit> </form> hidden.php <?php echo “Campo Hidden: “ . $_POST[“escondido”]; echo “<br>Oi, seu ID é: “ . $_POST[“id”]; ?> 3.3.2 CAMPOS TEXT E TEXTAREA Os campos text e textarea são os tipos mais simples, onde há somente um possível valor por campo. Dispensam maiores explicações. Exemplo: texts.html <form action=”texts.php” method=”post”> Nome: <input type=text name=nome><br> Email: <input type=text name=email><br><br> Mensagem: <textarea name=mensagem cols=8 rows=3></textarea><br> <input type=submit> </form> texts.php 24 <?php echo “Olá “ . $_POST[“nome”] . “ (email: “ . $_POST[“email”] . “)<br><br>”; echo “Sua mensagem: “ . $_POST[“mensagem”]; ?> PHP 3.3.3 CAMPOS RADIO Campos Radio permitem um relacionamento de um para muitos entre identificador e valor, ou seja, eles têm múltiplos possíveis valores, mas somente um pode ser pré-exibido ou selecionado. Por exemplo: você tem um sistema de “quiz”. Cada pergunta possui 5 possíveis respostas. Cada resposta é um radio, onde os 5 radios dessa pergunta possuem o mesmo identificador, mas cada com valores diferentes. Exemplos: radio.html <form action=”radio.php” method=”post”> <B>Qual seu sistema operacional?</B><br> <input type=radio name=sistema value=”Windows 98”> Win 98 <input type=radio name=sistema value=”Windows XP”> Win XP <input type=radio name=sistema value=”Linux”> Linux <input type=radio name=sistema value=”Mac”> Mac<br><br> <B>Qual a marca de seu monitor?</B><br> <input type=radio name=monitor value=”Samsung”> Samsung <input type=radio name=monitor value=”LG”> LG <input type=radio name=monitor value=”Desconhecido”> Desconhecido<br><br> <input type=submit> </form> radio.php <?php echo “Seu sistema operacional é: “ . $_POST[“sistema”]; echo “<br>Seu monitor é: “ . $_POST[“monitor”]; ?> 3.3.4 Campos checkbox O tipo Checkbox tem somente um possível valor por entrada: on value (marcado) ou no value (desmarcado). No script você deve fazer a verificação para saber se o campo foi marcado ou não. Se é possível também utilizar grupos de checkbox com o mesmo nome. Para você deve adicionar “[]” no final do nome, para o PHP interpretar como array, veja o código exemplo. Exemplo: checkbox.html <form action=”checkbox.php” method=”post”> <B>Escolha os numeros de sua preferência:</B><br> <input type=checkbox name=”numeros[]” value=10> 10<br> <input type=checkbox name=”numeros[]” value=100> 100<br> <input type=checkbox name=”numeros[]” value=1000> 1000<br> <input type=checkbox name=”numeros[]” value=10000> 10000<br> <input type=checkbox name=”numeros[]” value=90> 90<br> <input type=checkbox name=”numeros[]” value=50> 50<br> <input type=checkbox name=”numeros[]” value=30> 30<br> <input type=checkbox name=”numeros[]” value=15> 15<br><BR> <input type=checkbox name=”news” value=1> <B>Receber Newsletter?</B><br><BR> <input type=submit> 25 Escola Alcides Maya - Segundo Módulo </form> checkbox.php <?php // Verifica se usuário escolheu algum número if(isset($_POST[“numeros”])) { echo “Os números de sua preferência são:<BR>”; // Faz loop pelo array dos numeros foreach($_POST[“numeros”] as $numero) { echo “- “ . $numero . “<BR>”; } } else { echo “Você não escolheu número preferido!<br>”; } // Verifica se usuário quer receber newsletter if(isset($_POST[“news”])) { echo “Você deseja receber as novidades por email!”; } else { echo “Você não quer receber novidades por email...”; } ?> 3.3.5 Campos select Os campos select permitem tratar uma variedade de opções, onde o usuário pode selecionar apenas uma opção ou múltiplas opções. Quando você permite múltiplas seleções, deve adicionar “[]” no final do nome, para o PHP interpretar como array. Nos exemplos, mostro o funcionamento e tratamento de ambas. Exemplo: select.html <form action=”select.php” method=”post”> <B>Qual seu processador?</B><br> <select name=processador> <option value=”Pentium”>Pentium</option> <option value=”AMD”>AMD</option> <option value=”Celeron”>Celeron</option> </select><BR><BR> <B>Livros que deseja comprar?</B><br> Obs: segure “CTRL” para selecionar mais de um.<BR> <select name=”livros[]” multiple> <option value=”Biblia do PHP 4”>Biblia do PHP 4</option> <option value=”PHP Professional”>PHP Professional</option> <option value=”Iniciando em PHP”>Iniciando em PHP</option> <option value=”Novidades do PHP 5”>Novidades do PHP 5</option> <option value=”Biblia do MySQL”>Biblia do MySQL</option> </select><BR><BR> <input type=submit> </form> select.php <?php echo “Seu processador é: “ . $_POST[“processador”] . “<BR>”; // Verifica se usuário escolheu algum livro 26 PHP if(isset($_POST[“livros”])) { echo “O(s) livro(s) que você deseja comprar:<br>”; // Faz loop para os livros foreach($_POST[“livros”] as $livro) { echo “- “ . $livro . “<br>”; } } else { echo “Você não escolheu nenhum livro!”; } ?> 3.4 Upload de arquivos 3.4.1 ASPECTOS DOS FORMULÁRIOS DE UPLOAD Todo formulário de upload deve: 1. Ser declarado com o método de envio POST. 2. Conter a diretiva enctype=”multipart/form-data”, para “dizer” ao navegador que está se enviando arquivos e não somente os textos dos campos dos formulário 3. Conter pelo menos 1 campo “file”. Isso em prática fica: <form action=”script.php” method=”POST” enctype=”multipart/form-data”> Seu arquivo: <input name=”arquivo” type=”file”><BR> [... outros campos do formulário ...] <input type=”submit” value=”Enviar”> </form> 3.4.2 Manipulando com o script php os arquivos enviados Assume-se que o formulário acima foi postado enviando um arquivo. Automaticamente em “script.php” (o action do formulário exemplo), será criado as seguintes variáveis: l $_FILES[‘arquivo’][‘name’] O nome original do arquivo no computador do usuário. l $_FILES[‘arquivo’][‘type’] O tipo mime do arquivo, se o navegador deu esta informação. Exemplo: caso uma imagem GIF tenha sido enviada, o mime será: “image/gif”. l $_FILES[‘arquivo’][‘size’] O tamanho em bytes do arquivo. l $_FILES[‘arquivo’][‘tmp_name’] O nome temporário do arquivo, como está guardado no servidor. l $_FILES[‘arquivo’][‘error’] O código de erro associado a este upload de arquivo. Essa opção foi adicionada 3.4.3 OBSERVAÇÕES l Em versões anteriores do PHP a 4.1.0 use a variável $HTTP_POST_FILES e não a variável superglobal $_FILES que foi introduzida na versão 4.1.0; l No lugar de ‘arquivo’ use o nome do seu campo “file” do formulário; l Se a opção de configuração do PHP register_globals estiver como “on”, você pode usar uma variável com o nome do campo de formulário, exemplo: $arquivo_name, $arquivo_size, etc. Mas, usar dessa maneira não é o recomendável, procure sempre usar a superglobal $_FILES. O preferível no começo de “script.php” é passar a $_FILES para outra variável, por exemplo: 27 Escola Alcides Maya - Segundo Módulo $arquivo = isset($_FILES[‘arquivo’]) ? $_FILES[‘arquivo’] : FALSE; $arquivo2 = isset($_FILES[‘arquivo2’]) ? $_FILES[‘arquivo2’] : FALSE; [... etc ...] Os arquivos enviados pelo formulário serão guardados no diretório temporário do servidor, a menos que outro lugar seja especificado com a opção upload_tmp_dir no php.ini. E o caminho e nome de cada arquivo, são ditos na $_ FILES[‘arquivo’][‘tmp_name’]. Para mover o arquivo para um diretório desejado deve-se usar a função move_uploaded_file() (em versões anteriores a 4.0.3 use a função copy). Vamos então ao que interessa! O código de “script.php”: <?php // Repassa a variável do upload $arquivo = isset($_FILES[‘arquivo’]) ? $_FILES[‘arquivo’] : FALSE; // Caso a variável $arquivo contenha o valor FALSE, esse script foi acessado // diretamente, então mostra um alerta para o usuário if(!$arquivo) { echo “Não acesse esse arquivo diretamente!”; } // Imagem foi enviada, então a move para o diretório desejado else { // Diretório para onde o arquivo será movido $diretorio = “./arquivos/”; // Move o arquivo /* Lembrando que se $arquivo não fosse declarado no começo do script, você estaria usando $_ FILES[‘arquivo’][‘tmp_name’] e $_FILES[‘arquivo’][‘name’] */ if (move_uploaded_file($arquivo[‘tmp_name’], $diretorio . $arquivo[‘name’])) { echo “Arquivo Enviado com sucesso!”; } else { echo “Erro ao enviar seu arquivo!”; } } ?> Esse é o código mínimo que seu script de upload deve conter. Mas, o mesmo ainda não é seguro, pois não faz nenhuma verificação no arquivo, seja de tamanho, nome, tipo, etc. 3.4.4 Verificando e limitando os arquivos enviados 3.4.4.1 Tamanho dos arquivos Existem várias formas de verificar o tamanho de arquivo enviado. A primeira limitação que você pode impor nos uploads é colocar o seguinte campo em seu formulário: <input type=”hidden” name=”MAX_FILE_SIZE” value=”30000”> Essa diretiva diz ao navegador o tamanho máximo de arquivo que pode ser enviado, onde o valor fornecido deve ser em bytes. Mas, é fácil contornar este limite, então não conte que o navegador irá obedecer a sua vontade. Mas você deve adicionar MAX_FILE_SIZE em qualquer caso, já que salva os usuarios que escapam do problema de esperar por um grande arquivo ser transferido e somente depois de tudo descobrir que ele é muito grande. Verificando com a variável $_FILES[‘arquivo’][‘size’], onde no seu script haverá por exemplo um if: <?php // Tamanho máximo do arquivo em bytes $maximo = 50000; // Verificação if($_FILES[‘arquivo’][‘size’] > $maximo) { echo “Erro! O arquivo enviado por você ultrapassa o “; echo “limite máximo de “ . $maximo . “ bytes! Envie outro arquivo”; 28 PHP } ?> Verificando com a variável $_FILES[‘arquivo’][‘error’]: Ao enviar um formulário de upload, a variável $_FILES[‘arquivo’][‘error’] poderá conter os seguintes valores: l UPLOAD_ERR_OK Valor: 0; não houve erro, o upload foi bem sucedido. l UPLOAD_ERR_INI_SIZE Valor 1; O arquivo no upload é maior do que o limite definido em upload_max_filesize no php.ini. l UPLOAD_ERR_FORM_SIZE Valor: 2; O arquivo ultrapassa o limite de tamanho em MAX_FILE_SIZE que foi especificado no formulário html. l UPLOAD_ERR_PARTIAL Valor: 3; o upload do arquivo foi feito parcialmente. l UPLOAD_ERR_NO_FILE Valor: 4; Não foi feito o upload do arquivo. Então, assuma que seu formulário de upload seja: <form action=”script2.php” method=”POST” enctype=”multipart/form-data”> <input type=”hidden” name=”MAX_FILE_SIZE” value=”30000”> Arquivo: <input name=”arquivo” type=”file”><BR> <input type=”submit” value=”Enviar”> </form> E o visitante faça um upload de um arquivo maior que o especificado em MAX_FILE_SIZE e maior que o da configuração upload_max_filesize. Seu script PHP (no caso script2.php), conterá as seguintes verificações: <?php // Tamanho ultrapassa o MAX_FILE_SIZE do formulario if($_FILES[“arquivo”][“error”] == UPLOAD_ERR_FORM_SIZE) { echo “O tamanho de seu arquivo ultrapassa o limite dado! Envie outro arquivo”; exit; } /* Tamanho ultrapassa o limite da configuração upload_max_filesize do php.ini */ if($_FILES[“arquivo”][“error”] == UPLOAD_ERR_INI_SIZE) { echo “O tamanho de seu arquivo ultrapassa o limite de tamanho de arquivo do PHP! “; echo “Envie outro arquivo”; exit; } ?> 3.4.4.2 Tipo dos arquivos Assuma que você possui um site com a área de usuários, onde os mesmos possam enviar suas fotos. O tipo de imagem aceita seria apenas PNG. Mas, como sempre tem os “engraçadinhos” que possam acabar enviando arquivos não-imagem, você então deve verificar se o arquivo é uma imagem. Para isso, você pode verificar a extensão do nome de arquivo ou o tipo de arquivo. Mas, conforme expliquei em meu artigo, “Upload de Imagens com Segurança”, verificar a extensão do nome de arquivo não é seguro (leia o artigo citado para mais informações), então o melhor é sempre verificar o mime tipo do arquivo. Para isso, usa-se então a variável $_FILES[‘arquivo’][‘type’] criada no upload de um arquivo. No nosso exemplo, onde aceitamos apenas imagens PNG o mime tipo é: image/png. O script que verificaria isso: <?php // Verifica se o mime-type é de imagem PNG if($_FILES[‘arquivo’][‘type’] !== “image/png”) { echo “O arquivo enviado por você não é uma imagem PNG! Envie outro!”; 29 Escola Alcides Maya - Segundo Módulo } ?> Obs: Caso aceite mais tipos de arquivos, use expressões regulares na verificação. Há um exemplo disso no meu artigo “Upload de Imagens com Segurança”. 3.4.4.3 Nome dos arquivos Vamos continuar com o nosso exemplo onde os usuários enviam suas fotos. Usuários podem acabar enviando arquivos com nomes com espaços, várias letras maiúsculas e minúsculas, etc... É recomendável você definir um padrão para os nomes de arquivos e o melhor é sempre colocar underscores ( _ ) no lugar de espaços e que todas as letras sejam minúsculas. Assuma também que todas as fotos são salvas no mesmo diretório. Isso tem a falha de fotos de usuários acabarem ficando com o mesmo nome e se sobrescreverem, então 2 usuários diferentes tendo a mesma foto! Você pode verificar se o arquivo com mesmo nome já existe no diretório ou usar uma função que gera nomes únicos para a imagem. <?php // Repassa a variável do upload $arquivo = isset($_FILES[‘arquivo’]) ? $_FILES[‘arquivo’] : FALSE; // Código acima... com as demais verificaçoes... // Diretório para onde o arquivo será movido $diretorio = “./arquivos/”; // Substitui espaços por underscores no nome do arquivo $nome = str_replace(“ “, “_”, $arquivo[“name”]); // Todas as letras em minúsculo $nome = strtolower($nome); // Caminho completo do arquivo $nome = $diretorio . $nome; // Verifica se o arquivo existe no diretório dado if(file_exists($nome)) { echo “Um arquivo com esse nome já foi enviado! Envie outro arquivo!”; exit; } // Tudo ok! Então, move o arquivo if(move_uploaded_file($arquivo[‘tmp_name’], $nome)) { echo “Arquivo Enviado com sucesso!”; } else { echo “Erro ao enviar seu arquivo!”; } ?> Obs: Alguns textos e códigos foram pegos do Manual Oficial do PHP:http://www.php.net/manual/pt_BR/features.fileupload.php Obs2: Há uma lista ampla de Mime-Types aqui:http://www.auriumsoft.com.br/mime_types.html 30 PHP 4 ENVIANDO E-MAILS Para enviar e-mail através de um script PHP é bastante simples. Basta utilizar a função mail: mail(string to, string subject, string message, string [headers]); onde: l to – string contendo o e-mail do destinatário; l subject – assunto da mensagem; l message – o corpo da mensagem. l headers – outras informações de cabeçalho, como por exemplo “from”, “reply-to”, “bcc”, etc. Para facilitar a compreensão dos scripts, os argumentos (como geralmente são strings grandes) devem ser atribuídos a variáveis antes da chamada da função mail 31