PHP Paso de datos con formularios
Sumario
- 1 Introdución
- 2 Método GET
- 3 Método POST
- 4 Comprobando se hai datos
- 5 Función para validar / corrixir campos
- 6 Validación de datos utilizando arrays
- 7 Seguridade no uso dos formularios
- 8 Obtendo variables de formularios (post/get) e filtrado ao mesmo tempo
- 9 Redireccionamento de páxinas
- 10 Gardando imaxes no servidor
Introdución
- Sabemos que a través da etiqueta <form> podemos enviar datos dunha páxina a outra.
- Dentro de esta etiqueta temos o atributo method que pode tomar os valores get ou post.
Método GET
- Neste caso os datos son enviados na URL e pasan a páxina indicada polo etiqueta action do formulario no seguinte formato: http://paxinadestino.php?param1=valor¶m2=valor&.....
- Se vos fixades cando facedes unha busca en google (por exemplo buscade 'php') na url aparecerá algo coma isto: https://www.google.es/search?q=php&ie=utf-8&oe=utf-8&client=firefox-b&gfe_rd=cr&ei=a1XgV4CmOu6s8wfuibOQAQ
- Os datos que aparecen despois do signo '?' son parámetros:?q=php&ie=utf-8&oe=utf-8
- Desvantaxes:
- Calquera persoa pode ver os valores das variables polo que dito método non é moi seguro.
- O usuario pode cambiar o valor de ditas variables polo que pode suceder que o sitio amose ou faga algo diferente do permitido.
- O usuario pode obter información non actual se usa unha URL con datos non actualizados.
- O tamaño do que podemos enviar na URL está limitado (depende de cada navegador, pero pode estar entre 2KB-8KB)
- Vantaxes:
- A través da URL podemos pasar datos dunha páxina a outra sen necesidade de ter un formulario por medio.
- As variables que se pasan desta forma poden ser referenciadas en PHP a través da matriz global $_GET['param'].
- Vexamos agora un exemplo utilizando un formulario:
Arquivo: UD2_Form_Ex1_eleccion_pelicula.php
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 2 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 3 <html xmlns="http://www.w3.org/1999/xhtml" lang="es" xml:lang="es"> 4 <head> 5 <meta charset="utf-8" /> 6 <title>Formulario</title> 7 <style> 8 .formularios{ 9 width: 30%; 10 margin: 0px auto; 11 } 12 .etiqueta{ 13 float: left; 14 width: 190px; 15 } 16 .botonesformularios{ 17 width: 50%; 18 margin: 30px auto; 19 text-align: center; 20 } 21 select { 22 width:50%; 23 } 24 </style> 25 </head> 26 <body> 27 <form id="frmPelicula" class="formularios" method="get" action="UD2_Form_Ex1_datos_pelicula.php"> 28 <div> 29 <div class='etiqueta'>Película preferida:</div> 30 <select name="lstPelicula"><option>E.T. El extraterrestre</option><option>Supermán</option></select> 31 </div> 32 <div> 33 <div class='etiqueta'>Xénero preferido:</div> 34 <select name="lstXenero"><option>Acción</option><option>Ciencia ficción</option></select> 35 </div> 36 <div class="botonesformularios"> 37 <input type='submit' value="ENVIAR" /> 38 </div> 39 </form> 40 41 </body> 42 </html> 43 </php>
- Fixarse que enviamos os datos utilizando o método get.
Arquivo: UD2_Form_Ex1_datos_pelicula.php
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 2 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 3 4 <html> 5 <head> 6 <meta charset="UTF-8"> 7 <title></title> 8 </head> 9 <body> 10 <?php 11 echo 'Os datos que escolliches son:<br/><br/>'; 12 13 $pelicula = $_GET['lstPelicula']; 14 $xenero = $_GET['lstXenero']; 15 16 printf("PELICULA:%s<br/>XÉNERO:%s",$pelicula,$xenero); 17 ?> 18 19 </body> 20 </html>
Método POST
- No método post de envío de datos, os mesmos van 'dentro' da páxina web e polo tanto non son visibles para o usuario.
- Tamén está limitado o tamaño do que se pode enviar (por exemplo se enviamos un arquivo adxunto) a un tamaño de 8MB.
- Podemos cambiar dito límite:
- Modificando a directiva post_max_size do arquivo php.ini de PHP.
- Modificando o arquivo .htaccess do noso sitio web e engadindo a directa: php_value post_max_size 20M (isto é necesario no caso de aloxamentos compartidos ou se non temos acceso ao arquivo php.ini).
- Nota: No caso de subir arquivos tamén pode ser necesario modificar a directiva upload_max_filesize do arquivo php.ini
- Podedes ver neste enlace como aumentar o tamaño dos arquivos subidos nun aloxamento compartido.
- As variables que se pasan desta forma poden ser referenciadas en PHP a través da matriz global $_POST['param'].
- Modificamos o exemplo anterior para que envíe os datos con POST:
Arquivo: UD2_Form_Ex2_eleccion_pelicula.php
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 2 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 3 <html xmlns="http://www.w3.org/1999/xhtml" lang="es" xml:lang="es"> 4 <head> 5 <meta charset="utf-8" /> 6 <title>Formulario</title> 7 <style> 8 .formularios{ 9 width: 30%; 10 margin: 0px auto; 11 } 12 .etiqueta{ 13 float: left; 14 width: 190px; 15 } 16 .botonesformularios{ 17 width: 50%; 18 margin: 30px auto; 19 text-align: center; 20 } 21 select { 22 width:50%; 23 } 24 </style> 25 </head> 26 <body> 27 <form id="frmPelicula" class="formularios" method="post" action="UD2_Form_Ex2_datos_pelicula.php"> 28 <div> 29 <div class='etiqueta'>Película preferida:</div> 30 <select name="lstPelicula"><option>E.T. El extraterrestre</option><option>Supermán</option></select> 31 </div> 32 <div> 33 <div class='etiqueta'>Xénero preferido:</div> 34 <select name="lstXenero"><option>Acción</option><option>Ciencia ficción</option></select> 35 </div> 36 <div class="botonesformularios"> 37 <input type='submit' value="ENVIAR" /> 38 </div> 39 </form> 40 41 </body> 42 </html> 43 </php>
- Fixarse que enviamos os datos utilizando o método post.
Arquivo: UD2_Form_Ex2_datos_pelicula.php
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 2 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 3 4 <html> 5 <head> 6 <meta charset="UTF-8"> 7 <title></title> 8 </head> 9 <body> 10 <?php 11 echo 'Os datos que escolliches son:<br/><br/>'; 12 13 $pelicula = $_POST['lstPelicula']; 14 $xenero = $_POST['lstXenero']; 15 16 printf("PELICULA:%s<br/>XÉNERO:%s",$pelicula,$xenero); 17 ?> 18 19 </body> 20 </html>
Comprobando se hai datos
- Normalmente a páxina que recibe os datos vai facer algún tipo de tratamento con eles (por exemplo, facer unha alta nunha táboa dunha base de datos, consultar en base aos criterios recibidos,...)
- Polo tanto será necesario realizar algún tipo de validación para comprobar se se envían os datos necesarios e estes teñen un formato correcto.
- Lembrar repasar as funcións que comproban se un campo ten datos e as funcións que comproban o tipo de dato dunha variable.
- O primeiro que teríamos que comprobar é se o formulario recibe datos. Para iso utilizaremos as funcións vistas nunha sección anterior da wiki.
1 if (empty($_POST)) die('Non se enviaron datos');
Nota: A función die ao igual que a función exit finaliza a páxina php.
- O tratamento que queiramos darlle á páxina cando non se envíen datos será decidido polo programador, pudendo enviarlle un aviso ao usuario en enviando de novo a páxina do formulario.
- Tede que ter en conta que aínda que fagades unha validación dos campos utilizando javascript, isto pódese saltar, xa que a páxina está no cliente. Ademais un usuario podería cargar a páxina de tratamento da información (a que está indicada no action do formulario) sen pasar polo formulario.
- O segundo será verificar que os campos teñan algún valor (se é obrigatorio) e que o tipo de dato sexa o correcto. Para verificar o tipo de dato coas funcións is_XXXXX (coma por exemplo is_string) non se poden utilizar con datos que veñan a través dun formulario, xa que todos eles son avaliados como de tipo String.
- É dicir, un dato que garde a idade, por exemplo, se teño a variable $idade=3; e aplico a función is_string($idade) vai devolver false, pero se o dato da idade (valor 3) ven dun formulario e aplico a mesma función is_string($_POST['txtIdade']) vai devolver true.
1 if (empty($_POST['txtNome'])) echo('Campo nome non ten datos');
- IMPORTANTE: Todos os datos que veñen no array global $_POST son de tipo String. Teremos que facer un 'cast' ao tipo de dato ou ven utilizar a función filter_var que será explicada a continuación.
- Facendo o cast podemos saber se é un número ou non da seguinte forma:
1 if (ctype_digit($_POST['txtIdade'])){ 2 $idade = (int)$_POST['txtIdade']; 3 } 4 else { 5 echo 'Non é numérico integer'; 6 }
- Usamos a función ctype_digit para comprobar se temos díxitos numéricos no dato enviado.
- O cast (int) vai devolver 0 en caso de que non poida convertelo a Integer.
Comprobando se chegan datos de varios formularios diferentes á mesma páxina
- Imaxinemos o caso de que temos unha páxina de nome primeira.php. Dita páxina ten un formulario cuxo 'action' apunta a unha segunda páxina de nome: segunda.php
- Imaxinemos que dita páxina segunda.php ten a súa vez un formulario cuxo action apunta a ela mesma.
- Neste caso temos que identificar 3 posibles casos cando carguemos a páxina segunda.php:
- A páxina se carga vindo do primeiro formulario. Para identificar este caso podemos facer uso do botón de tipo 'submit' e definilo da seguinte maneira:
- <input name='btnEnviar1' type='submit' value='Envía datos páxina 1' />
- Na páxina segunda.php podemos poñer a seguinte condición para saber se ven da primeira.php:
- if (!empty($_POST['btnEnviar1'])) { } => Sabemos que vimos da primeira
- A páxina se carga vindo de segunda.php
- Podemos facer algo parecido á anterior e definir un name para o botón que fai o submit dende a segunda:
- <input name='btnEnviar2' type='submit' value='Envía datos páxina 1' />
- Na páxina segunda.php podemos poñer a seguinte condición para saber se ven da segunda.php:
- if (!empty($_POST['btnEnviar2'])) { } => Sabemos que vimos da segunda páxina.
- Se cargamos a páxina segunda.php directamente, o sabemos porque:
- if (empty($_POST['btnEnviar1']) && empty($_POST['btnEnviar2'])) { } => Sabemos que cargamos a páxina directamente sen vir dende primeira.php nin de segunda.php
Función para validar / corrixir campos
- O proceso de validación-corrección de campos dun formulario soe ser dar bastante traballo.
- Para facernos a vida un pouco máis doada, temos unha extensión en PHP que permite a validación de campos dunha forma moi sinxela.
- A función que fai dita validación chámase función filter_var()
- A función filter_var permítenos filtrar unha variable segundo o filtro indicado.
- Parámetros:
- $var: Variable que se quere filtrar
- $filter: Filtro que se desexa aplicar. Será una constante numérica (indicadas a continuación)
- $options: Conxunto de opcións que modifican o funcionamento do filtro. Pode ser unha constante numérica ou un array
- Valor devolto:
- O dato filtrado ou false se o filtro faia.
Filtros para a validación
- FILTER_VALIDATE_BOOLEAN => Valida a variable coma un booleano.
- FILTER_VALIDATE_EMAIL => Valida a variable coma unha dirección de correo electrónico correcta.
- FILTER_VALIDATE_FLOAT => Valida que a variable sexa do tipo float.
- FILTER_VALIDATE_INT => Valida a variable coma un número enteiro.
- FILTER_VALIDATE_IP => Valida a variable coma unha dirección IP.
- FILTER_VALIDATE_REGEXP => Valida a variable contra unha expresión regular enviada na variable de opcións.
- FILTER_VALIDATE_URL => Valida o valor coma unha URL de acordo coa RFC 2396.
Filtros para a corrección
- FILTER_SANITIZE_EMAIL => Elimina tódolos caracteres execepto letras, números e !#$%&’*+-/=?^_`{|}~@.[].
- FILTER_SANITIZE_ENCODED => Codifica a cadea coma unha URL válida.
- FILTER_SANITIZE_MAGIC_QUOTES => Aplica a función addslashes.
- FILTER_SANITIZE_NUMBER_FLOAT => Elimina tódolos caracteres excepto números, +- e opcionalmente ,.eE Se non poñemos un flag, non admitirá números decimais.
- FILTER_SANITIZE_NUMBER_INT => Elimina tódolos caracteres excepto números e os signos + -
- FILTER_SANITIZE_SPECIAL_CHARS => Escapa caracteres HTML e caracteres con ASCII menor a 32.
- FILTER_SANITIZE_STRING => Elimina etiquetas, opcionalmente elimina ou codifica caracteres especiais. Pode levar como terceiro parámetro algún destes flag´s:
- FILTER_FLAG_NO_ENCODE_QUOTES - Non codifica as comillas simples ou dobres (non as substitúe por códigos ' => ' por exemplo)
- FILTER_FLAG_STRIP_LOW - Elimina caracteres cun código ASCII < 32
- FILTER_FLAG_STRIP_HIGH - Elimina caracteres cun código ASCII > 127
- FILTER_FLAG_ENCODE_LOW - Codifica caracteres cun código ASCII < 32
- FILTER_FLAG_ENCODE_HIGH - Codifica caracteres cun código ASCII > 127
- FILTER_FLAG_ENCODE_AMP - Codifica o carácter "&" con &
- Nota: Pódense combinar varios flag´s con |
- FILTER_SANITIZE_STRIPPED => Alias do filtro anterior.
- FILTER_SANITIZE_URL => Elimina tódolos caracteres excepto números, letras y $-_.+!*’(),{}|\\^~[]`<>#%”;/?:@&=
Exemplos
Validando
- Validando un número enteiro
1 <?php 2 $var = 123; 3 echo filter_var($var, FILTER_VALIDATE_INT); 4 ?>
- Devolve o número xa que é un enteiro.
- Validando un número enteiro
1 <?php 2 $var = -2.343; 3 if(filter_var($var, FILTER_VALIDATE_INT) === false){ 4 echo 'Valor incorrecto'; 5 }else{ 6 echo 'Valor correcto'; 7 } 8 ?>
- Devolve 'Valor incorrecto' xa que non é un enteiro e polo tanto a función devolve false.
- Validando un número enteiro
1 <?php 2 $var = '-2'; 3 if(filter_var($var, FILTER_VALIDATE_INT) === false){ 4 echo 'Valor incorrecto'; 5 }else{ 6 echo 'Valor correcto'; 7 } 8 ?>
- Devolve 'Valor correcto'.
- Validando un número flotante
1 <?php 2 $var = '-1.45'; 3 if(filter_var($var, FILTER_VALIDATE_FLOAT) === false){ 4 echo 'Valor incorrecto'; 5 }else{ 6 echo 'Valor correcto'; 7 } 8 ?>
- Devolve 'Valor correcto'.
- Validando un email
1 <?php 2 $var = 'casa@hotmail'; 3 if (!filter_var($var,FILTER_VALIDATE_EMAIL)){ 4 echo "Valor incorrecto"; 5 }else{ 6 echo 'Valor correcto'; 7 } 8 ?>
- Devolve 'Valor incorrecto'.
Corrixindo os valores
- Cunha serie de filtros (SANITIZE) podemos eliminar aqueles caracteres que non queremos que aparezan nun determinado campo.
- Eliminando etiquetas dentro dun text-area.
1 <?php 2 $var = '<isto non está permitido> Isto si aparece'; 3 echo filter_var($var,FILTER_SANITIZE_STRING);
- Devolve 'Isto si aparece'.
- Corrixindo un número flotante.
1 <?php 2 $number="53.3pp"; 3 4 var_dump(filter_var($number, FILTER_SANITIZE_NUMBER_FLOAT, 5 FILTER_FLAG_ALLOW_FRACTION)); // Este flag fai que o caracter 'punto' sexa válido (separador de decimais) 6 ?>
- Devolve '53.3'.
Establecendo criterios
- Podemos indicar que rango de valores son aceptables polo filtro.
- Validando un número enteiro dentro dun rango
1 <?php 2 $var = -200; 3 $opciones = array( 4 'options' => array( 5 'min_range' => 10, 6 'max_range' => 100 7 )); 8 9 if(filter_var($var, FILTER_VALIDATE_INT, $opciones) === false){ 10 echo 'Valor incorrecto'; 11 }else{ 12 echo 'Valor correcto'; 13 } 14 ?>
- Devolve 'Valor incorrecto'
- Podemos facer unha modificación para que en caso incorrecto devolva sempre un valor 'por defecto':
1 <?php 2 $var = -200; 3 $opciones = array( 4 'options' => array( 5 'default' => 3, // valor a retornar se o filtro faiaa 6 'min_range' => 10, 7 'max_range' => 100 8 )); 9 10 $var = filter_var($var, FILTER_VALIDATE_INT, $opciones); 11 echo $var; 12 13 ?>
- Neste caso $var valerá '3' en caso de que non se cumpra o filtro.
- No caso dun número flotante podemos indicar cal é o carácter separado dos díxitos decimais.
1 <?php 2 $var = '1,23'; 3 $opciones = array( 4 'options' => array( 5 'decimal' => ',' 6 )); 7 8 if(filter_var($var, FILTER_VALIDATE_FLOAT, $opciones) === false){ 9 echo 'Valor incorrecto'; 10 }else{ 11 echo 'Valor correcto'; 12 } 13 ?>
- Devolve 'Valor correcto'
- Nota: Podemos facer uso da función filter_input que permite obter un dato dun formulario e validar ao mesmo tempo.
Validación de datos utilizando arrays
- Cando vexamos os arrays, podemos comprobar como facer unha validación de campos dunha forma máis rápida.
Seguridade no uso dos formularios
- Cando manexamos formularios temos que ter precaución co manexo de datos, xa que un usuario malintencionado podería poñer en risco o noso sitio web.
Inxección de CSS
- Este problema aparece normalmente cando temos unha caixa de texto / textarea no que imos a engadir/consultar, cos datos que veñen, a unha táboa dunha base de datos.
- Unha consulta clásica de validación de usuario podería ser:
- $_POST['usuarios'] = 'angel'
- $_POST['password'] = '12345678'
1 <?php 2 $nome=$_POST['usuarios']; 3 $password=$_POST['password']; 4 5 printf("select count(*) from USUARIOS where nome='%s' and password='%s'",$nome,$password); 6 ?>
- Neste caso se a consulta devolve 1 entón é un usuario da nosa base de datos.
- A consulta a executar no xestor de base de datos sería: select count(*) from USUARIOS where nome='angel' and password='12345678'
- Agora modifiquemos o campo password e imaxinemos que o usuario pon isto:
- $_POST['password'] = "' or password like '%";
- O resultado da consulta sería: select count(*) from USUARIOS where nome='angel' and password=' ' or password like '%'
- Como vemos estamos saltándonos a seguridade debido a que:
- O usuario pode engadir máis texto do permitido (incluso poñendo restricións de javascript, estas poden ser saltadas).
- O usuario pode engadir 'texto' que non debería estar permitido.
Nota: En vez de modificar unha consulta (como no exemplo) podería executar ordes SQL como de inserción, borrado ou modificación de rexistros.
Solución a inxección de CSS
- A mellor solución é utilizar procedementos almacenados. Sempre que o xestor o permite.
- Vexamos un exemplo en Mysql:
1 DELIMITER // 2 CREATE PROCEDURE country_hos 3 (IN log VARCHAR(20),IN pass VARCHAR(30)) 4 BEGIN 5 SELECT count(*) FROM USUARIOS 6 WHERE login = log and password = pass; 7 END // 8 DELIMITER ;
- Nesta solución temos:
- O usuario aínda que envíe máis información so se vai coller 20 caracteres para o login e 30 para o password.
- Aínda que engada 'código SQL' non se vai a executar xa que dito código vai ir todo na campo password.
- Loxicamente isto non quita que busquemos formas de validar os datos introducidos.
- Outra opción que temos é a de utilizar os filtros de corrección vistos anteriormente como por exemplo FILTER_SANITIZE_MAGIC_QUOTES que fai un escape dos caracteres como as cominllas simples ou dobres.
- Outra opción é a de utilizar funcións que provea o S.X.B.D. utilizado.
- No caso de mysql temos a función mysqli_real_escape_string. O veremos cando cheguemos a sección de acceso a datos.
- Tamén podemos empregar a función mysqli::prepare como veremos posteriormente en acceso a datos.
Cross-Site Scripting (XSS)
- Máis información neste enlace.
- Este tipo de ataque é debido a que un usuario engade código script (coma javascript) á información que imos amosar na páxina web.
- Polo tanto teremos que vixiar os datos que VISUALICEMOS na páxina.
- Un exemplo sería se introducimos dentro dun text-area este código:
1 <script>window.location="http://www.google.es";</script>
- O que vai pasar é que o navegador cando cargue a páxina vai cargar a páxina de google indicada no código javascript.
- Fixarse no perigo que supón xa que un atacante pode levar a un usuario a outro sitio web diferente.
- Outro exemplo de ataque por URL:
- http://localhost/PhpOlaMundo/Formularios/datosFormulario.php?texto=<script>window.location="http://www.google.es";</script>
- Se amosamos o dato: $_GET['texto'] teremos o mesmo problema que o anterior.
- Este código pode vir embebido nunha folla de estilos CSS, nun atributo dunha etiqueta HTML, dentro do corpo da páxina,na URL...
Importante: Fixarse que neste tipo de ataques temos que evitar que o que visualizamos leve código de script embebido. É diferente ao anterior no que supoñía un ataque á base de datos.
- Outro exemplo é se empregamos a variable $_SERVER['PHP_SELF'] como parámetro nun action dun formulario da forma:
1 <form method="post" action="<?php echo $_SERVER['PHP_SELF']); ?>" name="formulario_perfumes"> 2 3 ...... 4 5 </form>
Solucións ao ataque Cross-Site Scripting (XSS)
- Igual que no caso anterior podemos utilizar a función filter_var cos filtros FILTER_SANITIZE_MAGIC_QUOTES ou FILTER_SANITIZE_STRING para eliminar dita posibilidade.
- En PHP podemos facer uso das seguintes funcións:
- Función strip_tags: Dita función fai o mesmo que FILTER_SANITIZE_STRING e ademais podemos indicar cales etiquetas son permitidas.
- Función htmlentities: Dita función substitúe os caracteres das etiquetas en códigos HTML para a súa visualización.
- Se aplicamos dita función ao exemplo anterior teríamos esta saída coma código fonte de páxina: & lt;script& gt;window.location=& quot;http://www.google.es& quot;;& lt;/script& gt;
- Fixarse que os caracteres < e > son substituídos por & lt; e & gt; respectivamente.
- (Hai posto un espazo en branco entre & e o código xa que se non a wiki o visualizará como html)
- No caso do formulario poderíamos poñer:
<form method="post" action="<?php echo htmlentities($_SERVER['PHP_SELF']); ?>" name="formulario_perfumes">
......
</form> </syntaxhighlight>
Obtendo variables de formularios (post/get) e filtrado ao mesmo tempo
- En PHP , a partires da versión 5, podemos recuperar o valor dun campo dun formulario e aplicarlle un filtro ao mesmo tempo.
- A función que permite facer isto é filter_input.
- Sintaxe:
1 mixed filter_input ( int $type , string $variable_name [, int $filter = FILTER_DEFAULT [, mixed $options ]] )
- Parámetros:
- type: INPUT_GET, INPUT_POST, INPUT_COOKIE, INPUT_SERVER o INPUT_ENV.
- variable_name: Nome da variable, ven ser o nome da control html en caso dun formulario.
- filter: O ID do filtro a aplicar. Xa os vimos neste mesmo punto da wiki.
- options: Array asociativo de opcións. Se o filtro acepta opcións, se poden engadir nun array asociativo baixo la clave "flags".
- Valores devoltos:
- En caso de éxito, valor da variable pedida, FALSE se o filtro faia ou NULL se a variable variable_name non está definida.
- Por exemplo:
1 <?php 2 $buscar_html = filter_input(INPUT_GET, 'buscar', FILTER_SANITIZE_SPECIAL_CHARS); 3 $buscar_url = filter_input(INPUT_GET, 'buscar', FILTER_SANITIZE_ENCODED); 4 echo "Has buscado $buscar_html.\n"; 5 echo "<a href='?buscar=$buscar_url'>Buscar de nuevo</a>"; 6 ?>
- Información obtida de php.net.
Redireccionamento de páxinas
- Pode ser interesante cando realizamos un tratamento cos datos que veñen dun formulario ter a posibilidade de mandar ao usuario a unha páxina concreta.
- Imaxinemos o caso de que intentamos cargar a páxina de tratamento dun formulario previo ou que enviamos datos que non están completos. Neses casos queremos volver a enviar ao usuario á páxina de entrada de datos.
- Para facelo podemos usar a función header de PHP.
- Dita función serve para enviar encabezados ao navegador do cliente. Uns destes encabezados serve para redireccionar a páxina do clienta. A forma de facelo é:
1 <?php 2 header('Location: http://www.nova_paxina.es/'); 3 exit; 4 ?>
Importante: É NECESARIO QUE A CHAMADA Á FUNCIÓN header SE FAGA ANTES DE ENVIAR NINGÚN DATO AO CLIENTE.
- Quere isto dicir que ao cliente non lle pode chegar ningunha etiqueta HTML antes de facer o header-location. Non vale se temos un echo/printf de calquera cousa ou código HTML enviado antes da orde header.
- Un complemento interesante para visualizar a cabeceira dunha páxina: https://addons.mozilla.org/es/firefox/addon/live-http-headers/
- Ao instalalo teremos a posibilidade de capturar os datos de cabeceira da páxina se imos ao menú Herramientas => Live HTTP Headers.
- Coa función header imos poder manipular os datos enviados ao cliente dende o servidor.
Gardando imaxes no servidor
- Nos formularios temos a posibilidade de subir arquivos ao servidor.
- Un uso típico pode ser o de gardar documentos ou dar de alta produtos con imaxes asociadas. Neste último caso, o que gardaremos na base de datos será o nome do arquivo da imaxe (por exemplo 'imaxe.jpg') e cando recuperemos os datos da base de datos 'construiremos' unha etiqueta <img src='http://www.meusitio.es/IMAXES/imaxe.jpg' /> sendo IMAXES o cartafol onde están gardadas as imaxes no meu servidor web que atende a peticións coa URL: http://www.meusitio.es
- O primeiro que teremos que facer é crear un cartafol onde queiramos deixar as imaxes no noso servidor web.
- Como vimos na wiki nun punto anterior, o servidor web Apache 'apunta' fisicamente por defecto a '/var/www/html'.
- Crearemos (podedes comprobar a onde apunta mirando o arquivo de configuración /etc/apache2/sites-available/000-default.conf, como está explicado na wiki) un cartafol de nome IMAXES e darémoslle permiso de escritura ao usuario que utiliza o servidor Apache para acceder ao sistema de arquivos (www-data). Isto último está explicado no seguinte punto da wiki.
- Supoñemos que document_root apunta a /var/www/html e que estades a utilizar como servidor web Apache instalado de forma independente (sen XAMPP)
- Supoñemos que estades a utilizar Apache como servidor web e que o usuario-grupo que utiliza é www-data
1 cd /var/www/html 2 mkdir IMAXES 3 chown www-data:www-data IMAXES 4 chmod 755 IMAXES
- Se estiverades a utilizar XAMPP, teredes que mirar o arquivo de configuración do Apache que no caso de XAMPP é o httpd.conf que se atopa no cartafol /opt/lampp/etc
1 <IfModule unixd_module> 2 # 3 # If you wish httpd to run as a different user or group, you must run 4 # httpd as root initially and it will switch. 5 # 6 # User/Group: The name (or #number) of the user/group to run httpd as. 7 # It is usually good practice to create a dedicated user and group for 8 # running httpd, as with most system services. 9 # 10 User daemon 11 Group daemon 12 </IfModule>
- Nas liñas 10 e 11 se indica o usuario e grupo que utiliza o Apache de XAMPP para acceder aos cartafoles.
- Deberedes cambiar a liña do script anterior de chown www-data:www-data IMAXES a chown daemon:daemon IMAXES
Páxina do formulario
- A páxina onde se atopa o formulario para subir entre outros campos o campo imaxe debe ter as seguintes características.
- Información obtida de www3schools.
1 <!DOCTYPE html> 2 <html> 3 <body> 4 5 <form action="GardaCampos.php" method="post" enctype="multipart/form-data"> 6 Selecciona unha imaxe para subir: 7 <input type="file" name="fileToUpload" id="fileToUpload"> 8 <input type="submit" value="Subir Imaxe" name="btnSubirImaxe"> 9 </form> 10 11 </body> 12 </html>
IMPORTANTE:
- Liña 5: Debemos de escribir enctype="multipart/form-data" na etiqueta form en caso de querer subir arquivos a un servidor.
- Liña 7: O elemento HTML para poder seleccionar unha imaxe debe ser de tipo file
- Agora o Action do formulario pode 'apuntar' á mesma páxina ou a outra para procesar a subida do arquivo.
Páxina que procesa os datos
- Pode ser a mesma do formulario ou outra diferente. No exemplo se chama 'GardaCampos.php'.
1 <?php 2 $uploadOk=0; 3 4 // Enviamos datos 5 if(isset($_POST["btnSubirImaxe"])) { 6 $target_dir = $_SERVER['DOCUMENT_ROOT'] . "/IMAXES/"; // Gardaremos a imaxe no cartafol a onde apunta o servidor web máis /IMAXES => /var/www/html/IMAXES 7 $target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]); // Colle o nome da imaxe. Isto é necesario se a imaxe ten unha ruta posta no seu nome. 8 9 $uploadOk = 1; 10 $imageFileType = pathinfo($target_file,PATHINFO_EXTENSION); 11 $check = getimagesize($_FILES["fileToUpload"]["tmp_name"]); 12 if($check !== false) { 13 echo "O arquivo é unha imaxe - " . $check["mime"] . "."; 14 $uploadOk = 1; 15 } else { 16 echo "O arquivo non é unha imaxe."; 17 $uploadOk = 0; 18 } 19 20 if ($uploadOk == 0) { 21 echo "A imaxe non foi subida."; 22 } else { 23 if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file)) { 24 echo "O arquivo ". basename( $_FILES["fileToUpload"]["name"]). " foi subido ao servidor."; 25 } else { 26 echo "Houbo un erro subido o arquivo."; 27 } 28 } 29 } 30 31 32 ?>
- Liña 5: Preguntamos se veñen datos do formulario anterior
- Liña 7: A función basename devolve a última parte dunha ruta. Así se teño c:\carpeta1\carpeta2\arquivo.jpg devolverá 'arquivo.jpg'.
- Liña 10: A función pathinfo garda a extensión do arquivo a subir.
- Liña 11: A función getimagesize devolve un array con información da imaxe. En caso de que non sexa unha imaxe devolve false.
- Liña 23: En caso de que todo estea correcto movemos a imaxe que se atopa non cartafol temporal no servidor ao cartafol indicado por nos na variable $target_file
- Debemos ter en conta que podemos subir outro tipo de arquivos, como documentos,...iso dependerá da nosa aplicación.
- Podemos mellorar o noso código introducindo novas condicións.
- Verificar se o arquivo existe antes de subilo:
1 <?php 2 if (file_exists($target_file)) { 3 echo "Ese arquivo xa existe."; 4 $uploadOk = 0; 5 } 6 ?>
- Limitar o tipo do arquivo:
1 <?php 2 if($imageFileType != "jpg" && $imageFileType != "png" && $imageFileType != "jpeg" 3 && $imageFileType != "gif" ) { 4 echo "Soamente arquivos JPG, JPEG, PNG & GIF están permitidos."; 5 $uploadOk = 0; 6 } 7 ?>
- Limitar o tamaño do arquivo:
1 <?php 2 // Check file size 3 if ($_FILES["fileToUpload"]["size"] > 500000) { 4 echo "O arquivo ten máis de 500KB. Non se pode subir"; 5 $uploadOk = 0; 6 } 7 ?>
- Comentar que o referente ao tamaño dos arquivos, imos ter a limitación imposta polo propio PHP.
- Se estades non aloxamento compartido non ides poder modificar o arquivo de configuración para permitir subir arquivos de máis de 8MB.
- Existen dúas entradas no arquivo de configuración php.ini que son:
- upload_max_filesize = 2M;
- post_max_size = 8M;
- Estas directivas indican o tamaño máximo dun arquivo a subir e o tamaño máximo dun formulario incluíndo todos os seus campos.
- Lembrar que o arquivo de configuración de PHP se atopa en:
- /etc/php5/apache2/php.ini se estados a utilizar un servidor web Apache instalado independentemente.
- /etc/php5/cli/php.ini se estados a utilizar XAMPP.
- Se queredes aumentar o tamaño deberedes cambiar ambas directivas aos valores desexados.
- Tedes no meu Blog unha entrada do que hai que facer no caso de estar nun aloxamento compartido.
- No blog se explica os pasos para aplicar no Moodle, pero podería aplicarse en outros escenarios.
- Teríamos varias opcións, sempre supoñendo que o aloxamento compartido deixe crear arquivos php.ini ou .htaccess que sobrescriban a configuración do servidor web Apache (isto normalmente é así).
- Opción a)
- Crear un arquivo php.ini no cartafol raíz do noso sitio web e poñer:
1 upload_max_filesize = 64M 2 post_max_size = 64M 3 max_execution_time = 300
- No exemplo estamos a limitar en 64MB o tamaño da subida e o tempo de execución en 5 minutos.
- Crear un arquivo php.ini no cartafol raíz do noso sitio web e poñer:
- Teríamos varias opcións, sempre supoñendo que o aloxamento compartido deixe crear arquivos php.ini ou .htaccess que sobrescriban a configuración do servidor web Apache (isto normalmente é así).
- Opción b)
- Crear un arquivo .htaccess no cartafol raíz do noso sitio web e poñer:
1 php_value upload_max_filesize 64M 2 php_value post_max_size 64M 3 php_value max_execution_time 300 4 php_value max_input_time 300
- No exemplo estamos a limitar en 64MB o tamaño da subida e o tempo de execución en 5 minutos.
- Crear un arquivo .htaccess no cartafol raíz do noso sitio web e poñer:
-- Ángel D. Fernández González -- (2016).