View on GitHub

apunts

Apunts DWES

Formularis i fitxers

Formularis

Video

Pas de paràmetres

Una petició http és la sol·licitud d’un recurs al servidor:

Petició GET

Accedir a les dades de la petició GET
echo $_GET['nom'] . ' ' . $_GET['cognom'];
Evitar el CSRF

Video](https://youtu.be/qywV3Im17kk)

En tota pàgina que reba paràmetres GET has de comprovar el HTTP referer del navegador, i que aquest siga de dins de la teua web. En php el referer que envia el navegador s’emmagatzema en $_*SERVER[‘HTTP_REFERER’]

Seria tal com:

 if( parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST) != $_SERVER['HTTP_HOST']) die('Anti-CSRF'); 

NOTA IMPORTANT Amb aquest codi estem obligant al fet que el navegador envie un referer si o sí. Per tant només ha d’utilitzar-se en pàgines a les quals el navegador accedisca des d’una altra pàgina de la nostra web. Òbviament no podem col·locar-ho en la primera pàgina a la qual s’accedeix a la nostra web (index.php o similar), ja que si l’usuari a escrit l’adreça a mà en la barra del navegador no s’enviarà referer cap i saltarà el sistema.

Petició POST

Accedir a les dades de la petició POST
var_dump($_POST);
echo $_POST['nom']; echo $_POST['cognom'];

Al crear un formulari li assignem un metode (habitualment POST) i una destinació (pàgina que tractarà el formulari)

<form method='POST' action='pagina.php'>

Enviar les dades al mateix script que mostra el formulari

És habitual que la pàgina que tracta el formulari siga la mateixa que la que el conté. Per poder fer-ho:

Verificar que el formulari s’ha enviat
<?php
/* si va bien redirige a principal.php si va mal, mensaje de error */
	if ($_SERVER["REQUEST_METHOD"] == "POST") {  
		if($_POST['usuario'] === "usuario" and $_POST["clave"] === "1234"){		header("Location: principal.php");
		}else{
			$err = true;
		}	
	}
?>
<!DOCTYPE html>
<html>
	<head>
		<title>Formulario de login</title>		
		<meta charset = "UTF-8">
	</head>
	<body>			
		<?php if(isset($err)){
			echo "<p> Revise usuario y contraseña</p>";
		}?>
		<form action = "<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>" method = "POST">
			<label for = "usuario">Usuario</label> 
			<input value = "<?php if(isset($usuario))echo $usuario;?>"
			id = "usuario" name = "usuario" type = "text">				
			
			<label for = "clave">Clave</label> 
			<input id = "clave" name = "clave" type = "password">			
			
			<input type = "submit">
		</form>
	</body>
</html>
Accedir a paràmetres no existents

Validació del formulari

Video

Valors buits
Espais en blanc
Filtrar l’entrada

Video

Comprovar l’email
Dates

Mostrar els errors en el formulari

Video

El errors de validació s’han de guardar en una variable per a mostrar-los a l’usuari junt al formulari per tal que torne a picar-los bé. També he de guardar els valors anteriors per mostrar-los també.

function isRequired($nomCamp,&$errors){
        if (!empty($_POST[$nomCamp])) {
            return trim(htmlspecialchars($_POST[$nomCamp]));
        }
        else {
            $errors[$nomCamp] = "El $nomCamp és requerit";
            return null;
        }
    }

guarde en l’array errors el possible error.

 function isValidClass($nomCamp,$errors){
         if (!isset($errors)) {
             return '';
         }
         if (isset($errors[$nomCamp])) {
             return 'is-invalid';
         }
         return 'is-valid';
     }
 
     function showError($nomCamp,$errors){
         if (!isset($errors)) {
             return '';
         }
         if (isset($errors[$nomCamp])) {
             return "<div class='invalid-feedback'>$errors[$nomCamp]</div>";
         }
         return "<div class='valid-feedback'>All correct</div>";
     }

funcions per a retornar el html necesari per a pintar els errors en bootsrap

    extract($_POST,EXTR_PREFIX_SAME,'old');

genere variables old_nomdeCamp per als valors anterior

<div class="form-group">
    <label for="assigned_to">Assignada a:</label>
    <input name="assigned_to" type="text" class="form-control <?= isValidClass('assigned_to',$errors) ?>" id="assigned-to" aria-describedby="assignedHelp" placeholder="Enter person assigned to" value="<?= $old_assigned_to??'' ?>">
    <small id="assignedHelp" class="form-text text-muted">Task's assigned to.</small>
    <?= showError('assigned_to',$errors) ?>
</div>

mostre els errors utilitzant les funcions anterior i el camp old_title

Pujada de fitxers

Video

Es un cas especial. En primer lloc en el formulari cal utilitzar l’atribut enctype=”multipart/form-data” i el metode POST. Per al fitxer s’utilitza una etiqueta <input type=”file”>.

<!DOCTYPE html>
<html>
	<body>
		<form action="procesar_subida.php" method="post" enctype="multipart/form-data">    
			Escoja un fichero
			<input type="file" name="fichero">
			<input type="submit" value="Subir fichero">
		</form>
	</body>
</html>

En l’script que reb el fitxer la variable global $_FILES conté la informació sobre el fitxer en un array bidimensional.

Elements del array del fitxer pujat

<?php
	$tam = $_FILES["fichero"]["size"];
	if($tam > 256 *1024){
		echo "<br>Demasiado grande";
		return;
	}
	echo "Nombre del fichero: " . $_FILES["fichero"]["name"];
	echo "<br>Nombre temporal del fichero en sel servidor: " . $_FILES["fichero"]["tmp_name"];	
	$res = move_uploaded_file($_FILES["fichero"]["tmp_name"],"subidos/" . $_FILES["fichero"]["name"]);
    if($res){
		echo "<br>Fichero guardado";
    } else {
        echo "<br>Error";
    }

Video

Grandària del fitxer a pujar

<input type="hidden" name="MAX_FILE_SIZE" value="1000000">

Ruta temporal del fitxer pujat

Problemes més habituals

Codis d’error
Comprovació del tipus de fitxer
if ($_FILES['imatge']['type'] !== 'image/gif') {
	echo 'Error: No es tracta d'un fitxer .GIF.'; 
	exit; 
 }
Evitar atacs
Moure l’arxiu pujat
Evitar sobrescritures

Fitxers

Obrir un arxiu

Els arxius en PHP s’obrin amb la funció fopen(), que requereix dos paràmetres: l’arxiu que es vol obrir i la manera en què obrir l’arxiu. La funció retorna un punter en l’arxiu si és satisfactòria o zero si no ho és. Els arxius s’obrin per a realitzar operacions de lectura o escriptura.

$fp = fopen("miarchivo.txt", "r");

Si no és possible obrir l’arxiu, retorna zero, per això és freqüent utilitzar aquesta funció en una condició:

if (!$fp = fopen("miarchivo.txt", "r")){
    echo "No se ha podido abrir el archivo";
}

Es pot obrir un arxiu però també una URL externa, ja que fopen() realment el que fa és crear una connexió, per això cal tancar-la posteriorment.

$fp = fopen("http://localhost:8000", "r");

Les maneres d’accés existents per a fopen és poden trobrar a la documentació oficial.

Llegir un arxiu

Una vegada obert l’arxiu, el llegirem i guardar els seus continguts en una variable amb fread():

$file = "miarchivo.txt";
$fp = fopen($file, "r");
$contents = fread($fp, filesize($file));

La variable contents guardarà el contingut que obtinguem amb la funció fread(). Aquesta funció requereix dos paràmetres, l’arxiu obert i la longitud que volem llegir d’aquest arxiu (en bytes). En aquest cas hem emprat la funció filesize() per a obtindre la grandària de l’arxiu i així retornar tot el seu contingut.

Tancar un arxiu

Finalment, tancarem l’arxiu (no és obligatori però es recomana):

fclose($fp);

Escriure en un arxiu

Igual que per a llegir un arxiu, hi ha més d’una manera d’escriure en un. La forma més bàsica és utilitzar la funció fwrite() (o fputs(), que és el seu àlies):

$file = "miarchivo.txt";
$texto = "Hola que tal";
$fp = fopen($file, "w");
fwrite($fp, $texto);
fclose($fp);

Aquesta vegada hem emprat la manera w, que permet escriure sobreescrivint l’arxiu.

Podem limitar la longitud de dades que volem escriure (totes les dades que hi havia en l’arxiu s’esborraran per complet igualment):

$file = "miarchivo.txt";
$texto = "Hola que tal";
$fp = fopen($file, "w");
fwrite($fp, $texto, 4); // Escribirá sólo: Hola

Si l’arxiu *^miarchivo.txt^^ no existeix, es crearà automàticament amb la manera w de la funció fopen.

Punter d’arxiu

Un punter d’arxiu (file pointer o handle) és una variable que fa referència a un arxiu. És una variable que apunta a un arxiu en concret, i normalment s’obté quan s’obri amb fopen().

PHP i la seua recol·lecció de fems tanca tots els punters d’arxius al final de l’execució del script, encara que es considera una bona pràctica tancar els arxius manualment amb fclose().

A més d’apuntar a un arxiu, apunta a una posició concreta en aqueix arxiu. En la majoria dels casos quan s’obri un arxiu el punter apunta al principi (posició 0) o al final de l’arxiu.

La funció feof() és utilitzada amb freqüència en el maneig d’arxius en PHP. Aquesta funció comprova si el punter es troba al final de l’arxiu. S’utilitza quan es recorre un arxiu línia per línia o per a la lectura de grans arxius, mitjançant un condicional:

$archivo = "miarchivo.txt";
// Abrimos el archivo
$fp = fopen($archivo, "r");
// Loop que parará al final del archivo, cuando feof sea true:
while(!feof($fp)){
    echo fread($fp, 4092);
}

El codi anterior només carregarà 4kb de dades de vegada, la qual cosa redueix l’ús de memòria per a grans arxius.

Obtindre informació d’un arxiu

Es pot obtindre informació d’un arxiu a més del seu contingut: grandària, última vegada que s’ha accedit o modificat, nombre de links, etc. La funció principal per a obtindre aquesta informació és amb la funció stat(), en aquesta taula es poden veure els 12 elements que retorna el array.

$file = "miarchivo.txt";
$texto = "Todos somos muy ignorantes, lo que ocurre es que no todos ignoramos las mismas cosas.";

$fp = fopen($file, "w");
fwrite($fp, $texto);

$datos = stat($file);

echo $datos[3] . "<br>"; // Número de enlaces, 1
echo $datos[7] . "<br>"; // Tamaño en bytes, 85
echo $datos[8] . "<br>"; // Momento de último acceso, 1444138104
echo $datos[9] . "<br>"; // Momento de última modificación, 1444138251

Funcions de directoris

Les funcions de directoris vénen de l’extensió directories de PHP. Hi ha un total de 9 funcions disponibles que podeu consultar en la documentació