0% encontró este documento útil (0 votos)
167 vistas51 páginas

Guía Básica de PHP para Principiantes

El documento describe los conceptos básicos de PHP, incluyendo la sintaxis, variables, constantes, funciones, bucles, fechas, depuración de errores, tipos de datos, y variables superglobales. Explica cómo crear y acceder a arreglos, y cómo mostrar un solo post de usuario mediante operadores y estructuras de control en PHP.

Cargado por

diegodoy10
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOCX, PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
167 vistas51 páginas

Guía Básica de PHP para Principiantes

El documento describe los conceptos básicos de PHP, incluyendo la sintaxis, variables, constantes, funciones, bucles, fechas, depuración de errores, tipos de datos, y variables superglobales. Explica cómo crear y acceder a arreglos, y cómo mostrar un solo post de usuario mediante operadores y estructuras de control en PHP.

Cargado por

diegodoy10
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOCX, PDF, TXT o lee en línea desde Scribd

 Entorno de desarrollo: es un servidor que está en tu ordenador, permite ejecutar

php y un servidor.

SINTAXIS DE PHP

 Un archivo .php es una mezcla de código html y php.

 Para comenzar a escribir en php, primero debemos delimitar dónde empieza el


código y dónde termina. Para esto es necesario poner: <?php y ¿> al final

 En un archivo PURO de php, no hay que cerrar el código al final.

 Existen dos tipos de comentarios en php:

// una sola línea

/* muchas
Líneas*/

Variables, constantes y funciones

 Todas las variables deben comenzar con $. Ejemplo:

$nombre = “Ignacio”.

- Las variables son sensibles a mayúsculas y minúsculas, por lo tanto, hay que tener
ojo al momento de declararlas.

 Las constantes se utilizan siempre mayúsculas para nombrarlas. Las constantes


reciben dos parámetros (“tipo”, “valor”). Las constantes no se pueden cambiar, si
las declaramos de una forma quedará con ese valor por siempre. Por ejemplo

- define("TIPO", "coche" );
- define("MARCA", "Ford" );
 Cuando declaramos variables, podemos llamar esas variables en las etiquetas html:
<?php
$post_2_titulo = "OTRO TITULO";
$post_2_contenido = "contenido secundario contenido secundariocontenido
secundariocontenido secundario";

¿>

<div id = “contenido”>

<h2><?php echo $post_2_titulo; ?></h2>


<div><?php echo $post_2_contenido; ?></div>

</div>

 Las funciones son trozos de código que ejecutan acciones, pero primero debemos
llamarlas:

function nombreDeLaFuncion ($parametro1, $parametro2 ) {

}
- Existen funciones que no tienen parámetros:

function QueDiaEsHoy () {

echo "Today is " . date ("l");


}

- Para llamar las funciones en php se debe hacer después del código php pero antes
del html:
<?php

function suma3( $num1, $num2, $num3 ) {

echo $num1 + $num2 + $num3;


}

¿>

<h1><?php echo suma3(10,10,10); ?></h1>

<!DOCTYPE html>
 Las funciones en php también las podemos llamar a través de las etiquetas de
html:

function get_post_1_titulo () {

$post_1_titulo = "TITULOOOOOO";

return $post_1_titulo;

<h2><?php echo get_post_1_titulo(); ?></h2>

 El scope de variables en php funciona de la siguiente manera: Cuando tenemos


una función y dentro de ella hay una variable, se tendrá acceso a aquella variable
solo desde dentro de la función.

function prueba () {

$saludo = "hola amigos";


echo $saludo;
}

 Si la variable está fuera de función podríamos acceder a ella desde dentro, ya que
esa variable se transformaría en una global:
$otroSaludo = "hola pirinola";
function prueba() {

global $otroSaludo;
}

?>

<h1><?php prueba(); ?></h1>

DEPURACIÓN DE ERRORES

 Existen distintos tipos de errores que pueden salir en la programación con php:

- Notice: Pasa cuando, por ejemplo, una variable no tiene ningún valor o no está
definida. Este caso no es grave, por lo tanto, se sigue ejecutando lo demás.

- Syntax: Pasa cuando no está correcta la sintaxis en nuestro código (no estamos
escribiendo correctamente php). Este error se produce de manera global, por lo
tanto, para la ejecución (se pone la página en blanco). Para saber dónde tenemos
el error, debemos ir a la interfaz de xampp, cliquear en logs y luego [Link]:

Echo “hola” “mundo”  en este caso hay error de sintaxis porque la


concatenación está mala, debería ir un punto (en php se concatena con un punto).

- Error fatal: Pasa cuando, por ejemplo, llamamos una función y esta no existe. Se
pone la página en blanco con el error escrito. Se puede acceder a este error de la
misma forma que el anterior.
TIPOS DE DATOS

 Enteros: 1,2,3, 0, -1, -2

 Float: 1.123 (en php se escriben con punto y no coma)

 Strings: Es muy importante o usar comillas simples o dobles.

 Booleanos: true y false en la toma de decisiones.

 Arrays: Listado de tipos de datos (cualquiera). En php se declaran de la siguiente


manera:
$colores = [“azul”, “verde”, “rosa” ];
- Para acceder al array: var_dump ( $colores [0] );

- Para añadir elementos a los array:


$colores[] = “amarillo”;

 En php existen los arrays asociativos: son arreglos que tienen elementos con
valores asignados.

$edades = [ “pedro” => 55, “ana” => 98, “sammy” => 25 ];

- Para acceder a los elementos de este array no es necesario poner la posición, solo
el elemento.

var_dump ( $edades [“pedro”] );

var_dump ( $edades [“sammy”] );

- Para añadir elementos a los arrays asociativos:

$edades[ “juan” ] = 45 ;
 Existen valores que php de por sí los considera como FALSE:

- $cero = 0;
- $cadenaVacia = “ ”;
- $nulo = null;
- $arrayVacio = [ ];

LOOPS

 Son unas estructuras de control que nos sirven para recorrer una lista de cosas
(por ejemplo una lista de un array), una vez recorridas las podemos sacar por
pantalla.

 Existen 4 tipos de loops:

- While

- Do-while

- For

$longitud_posts = count ( $all_posts );

for ($i = 0; $i < $longitud_posts; $i++ ) {

echo $all_posts [ $i ] ["content"];


echo "</br>";

}
- Foreach (el más usado):

foreach ( $all_posts as $post ){

echo $post["title"];
echo "</br>";
}

FECHAS

 UNIX timestamp: es un estándar de tiempo de unix.

 Función date(): admite de primer formato una cadena y el timestamp:

Ejemplo: echo date ( ‘d/m/y’ ); //12/03/2020 (saca la hora actual del servidor)

echo date ( ‘d/m/y’, 123456789 ); //29/11/1973 (los códigos timestamp tienen


fechas como predeterminadas).

 Existen varios tipos de formato de fecha:

- d – días del 01 al 31.


- D – días de la semana
- m – meses del 01 al 12
- M – mes abreviado (jan to dec/ ene a dic)
- F – Mes completo (enero - diciembre)
- y – año con los dos últimos dígitos
- Y – año con todos los dígitos
Por ejemplo:
echo date ( ‘Y-m-d’ ); //2018-12-02
echo date ( ‘D,d M’ ); // Sun, 02 Dic
echo date ( ‘D,d \d\e F’ ); // Sun, 02 de Diciembre
echo date ( ‘D,d \d\e F \d\e Y’, 123456789 ); // Thu, 29 de November de 1973

 Existen también formatos para la hora:

- h – hora de 01 a 12
- H – hora de 01 a 23
- i – minutos con ceros delante si aplica (00 a 59)
- s – segundos con ceros delante si aplica (00 a 59)
- a – am o pm
- A – AM o PM

Por ejemplo:

echo date ( ‘h:i’ ); // 03:10


echo date ( ‘h:i A’ ) // 03:10 PM
echo date ( ‘H:i’ ); // 15:10 PM
echo date ( ‘H:i:s’ ); // [Link]

 Cómo traducir las fechas:

- Lo primero que debemos utilizar es la función setlocale (LC_TIME, 'es', 'spa', 'es_ES'
);. El primer parámetro es para hacer la traducción (se puede poner LC_ALL
también, pero en este caso solo estamos traduciendo los formatos de tiempo) y el
segundo es el idioma que se ponen tres por si acaso no encuentra alguno. ESTA
FUNCIÓN SE COLOCA AL PRINCIPIO DE TODO EL CÓDIGO PHP:
[Link] (códigos para el idioma)

[Link]
<?php
error_reporting( E_ALL );
ini_set( 'display_errors', 1 );
setlocale (LC_TIME, 'es', 'spa', 'es_ES' );
date_default_timezone_set( 'Australia/Sydney' );
¿>

 Luego para ya traducir se debe poner el método strtime:


[Link] con el código que corresponda
según las necesidades:

<span class="post-date">
Publicada en:

<?php echo strftime ( '%d %B %Y',strtotime ( $post['published_on'] ) ); ?>

</span>

 Por último, debemos establecer qué hora (según zona horaria) queremos para
nuestra página web:

- Al principio del código php debemos poner la función


date_default_timezone_set( 'Australia/Sydney' ); , con el parámetro de la zona
horaria que vamos a utilizar (en este caso el de Australia).
[Link] (lista de zonas horarias).
VARIABLES SUPERGLOBALES:

 Son variables que existen en php y sirven para recolectar información tanto del
usuario como del servidor.
 Estas variables SIEMPRE se escriben con mayúsculas.

- Algunas de esas variables son:

a) $_SERVER: es un array que contiene información como cabeceras, rutas y


ubicaciones de script. Dependiendo del servidor, algunos pueden omitir
algunos campos. Por ejemplo:

$_SERVER[HTTP_HOST] – “localhost:8888”;

b) $_GET: Es un array que contiene los datos que pasan por la URL.
- Por ejemplo, acá le decimos que busque todos los posts que contengan el nombre de
Ignacio.

c) $_POST: Es un array que contiene los datos que pasan a través de un request de tipo
POST (normalmente se utilizan en los formularios).

d) $_FILES: Es un array asociativo de archivos subidos a través de un formulario con


método POST.

e) $_COOKIE: Array de Cookies del usuario que visita el sitio.

f) $_SESSION: Array done se puede guardar información sobre un usuario. Al recargar,


dicha información no se pierde.

g) $_REQUEST: Es un array que contiene $_GET, $_POST Y $_COOKIE.

OPERADORES y ESTRUCTURAS DE CONTROL: MOSTRÁNDO UN


SOLO POST AL USUARIO

 Operadores: nos sirven para comprar variables:

- Operadores aritméticos: suma, resta, multiplicación y división (+ - * /).

- Operadores de asignación:

$z = 50;
$x = $z:
var_dump ( $x );
//suma y asigna

$x += $y;  A x súmale el valor de y, luego asígnalo a x. Es lo mismo que decir $x =


$x + $y
var_dump ( $x );

//resta y asigna

$x -= $y;  A x resta el valor de y, luego asígnalo a x. Es lo mismo que decir $x = $x


- $y
var_dump ( $x );

//multiplica y asigna

$x *= $y;  A x multiplícale el valor de y, luego asígnalo a x. Es lo mismo que decir


$x = $x * $y
var_dump ( $x );

//divide y asigna

$x /= $y;  A x divídele el valor de y, luego asígnalo a x. Es lo mismo que decir $x =


$x / $y
var_dump ( $x );

- Operadores de incremento y decremento:

$x++; //es lo mismo que $x = $x + 1


Var_dump: ( $x );

$x--; //es lo mismo que $x = $x - 1


Var_dump: ( $x );
- Operadores de comparación:

a) ==: Compara solo el valor entre variables.


$x = 10;
$y = “10”;
var_dump ( “ $x == $Y ” );
var_dump ( $x == $Y );

b) ===: Compara el valor, así como también el tipo de dato.

$y = 10;
var_dump ( “ $x === $Y ” );
var_dump ( $x === $Y );

c) <: menor que.

d) >: mayor que.

e) <=: menor o igual.

f) >=: mayor o igual.

g) ¡=: distinto de.

- Operadores de cadenas:

a) Para concatenar cadenas en php se debe hacer con un punto:


$cadena1 = “hola”;
$cadena2 = “mundo”;
var_dump ( $cadena1 . $cadena2 );
b) .= :

$cadena2 .= $cadena1;
var_dump ( $cadena2 );

- Operadores lógicos

a) && (and):

var_dump ( $x && $Y );

b) || (or):

var_dump ( $x || $Y );

c) ! (not):

var_dump ( “! $x” );  devuelve lo contrario, por ejemplo, si x es true y pasará a


ser false.

 Estructuras de control: Nos permiten mostrar una información u otra,


dependiendo de lo que queramos mostrar.

a) If

b) If else

c) If elseif else
d) Switch

$x = 'Lucía';
switch ( $x ) {
case 'Ignacio': {
var_dump('El nombre es Ignacio' );
break;
}
case 'Lucía': {
var_dump('El nombre es Lucía' );
break;
}
default: {
var_dump('No se conoce el nombre' );
}
}
//SI QUEREMOS MOSTRAR NUESTRA PÁGINA COMO YA UN BLOG

//DE PRINCIPIO NO LO ENCONTRAMOS:


$post_found = false;

/*LE PASAMOS LA FUNCIÓN isset PARA COMPROBAR SI EXISTE.


SI ES ASÍ, HAZ LO DEMÁS*/
if ( isset( $_GET["view"] ) ) {

//LUEGO RECORREMOS EL ARRAY CON LOS POST


foreach ($all_posts as $post) {

//SI ENCUENTRA EL POST, LO ASIGNO A UNA VARIABLE


if ( $post["id"] == $_GET["view"] ) {
$post_found = true;
$all_posts = [ $post ];

}
}

<div id="content" >


<div class="posts">
<?php foreach ( $all_posts as $post ): ?>
<article class="post">
<header>
<h2 class="post-title">
<!--POR ÚLTIMO AGREGAMOS ESE ENLACE PARA
REDIRIGIR AL LINK DEL CONTENIDO DEL POST-->
<a href="?view=<?php echo $post['id']; ?>"><?
php echo $post['title']; ?></a>
</h2>
</header>

<div class="post-content">
<!--AHORA QUE ENCONTRAMOS EL POST MOSTRAREMOS EL CONTENDO-->
<?php if ( $post_found ): ?>
<?php echo $post['content']; ?>
<!--SI NO LO ENCUENTRA MOSTRAMOS UN EXTRACTO-->
<?php else: ?>
<?php echo $post['excerpt']; ?>
<?php endif; ?>
</div>
<footer>
<span class="post-date">
Publicada en:
<?php echo strftime( '%d %b %Y',
strtotime( $post['published_on'] ) ); ?>
</span>
</footer>
</article>
<?php endforeach; ?>
</div>
</div>

FICHEROS EN PHP: HORA DE REORGANIZAR


 Los ficheros en php son para dividir nuestro código con diferentes funciones en
distintos archivos, que luego podemos reutilizar. (Por ejemplo, el header y el
footer se repiten en todas las páginas. Es por esto que debemos crear ficheros que
contengan esos extractos de código para no tener que copiar y pegar como
enfermo). También los ficheros nos sirven para mantener separadas distintas
funciones que luego podremos editar de manera más práctica, sin necesidad de
tener que buscar dentro de un extenso código.

 Para comenzar a crear ficheros debemos crear un nuevo [Link] y abrirlo en el


editor.

 Luego, el código que vamos a reutilizar lo pegamos en el nuevo archivo.

 Para poder reutilizar ese código, en la página que lo requiera se debe poner la
siguiente sentencia: <?php require ('[Link]'); ?> También puede ser con INCLUDE
(la diferencia es que el include no arroja errores fatales cuando el fichero no
existe).

 Cuando queramos crear un fichero solo para, en ese caso, los posts debemos crear
una función que guarde el array:

$all_posts = get_all_posts();

 EL INIT APARTE DE LAS CONFIGURACIONES, NOS VA A SERVIR PARA REQUERIR


ARCHIVOS QUE SEAN COMUNES PARA TODA LA APLICACIÓN.
 PARA TENER LOS POSTS EN FICHEROS SEPARADOS, SE DEBE:

- En primera instancia en el index debemos guardar el array asociativo de los posts


en una función que devuelva los posts: $all_posts = get_all_posts();

- Luego, hay que crear el fichero posts (el que contiene la función con los posts) y abajo
debemos crear una nueva función la cual va a buscar y devolver los posts.

function get_post( $post_id ) {


foreach ( get_all_posts() as $post ) { recorremos la función que guarda los post.
if ( $post['id'] == $post_id ) {
return $post;  si los encuentra los devuelve
}
}
return false;  si no los encuentra, no devuelve nada (muestra los demás posts).
}

- Ahora en el index debemos declarar una variable en falso que nos va a ayudar con la
comprobación de la existencia del post y, si existe, esa variable pasa a ser true y se guarda
en el array asociativo.

$all_posts = get_all_posts();

$post_found = false;

if ( isset( $_GET['view'] ) ) { comprobamos si el post existe

$post_found = get_post( $_GET['view'] );  la variable en falso pasa a guardar la función


del fichero post que busca y devuelve los post.

if ( $post_found ) {

$all_posts = [ $post_found ];  si encuentra los post, el array asociativo será igual


a la variable que declaramos en falso y que guarda la función que busca los post.
}}

- El fichero con los posts lo debemos requerir en el init. ¿Por qué en ese fichero y no en el
index? Porque el fichero init aparte de las configuraciones, nos sirve para requerir ficheros
que los vamos a utilizar en todas las páginas de nuestro proyecto.

- Finalmente, haciendo todos esos pasos podemos mostrar los posts por pantalla:
Creando entradas en el blog

 Después de haber creado todos los ficheros necesarios para nuestro sitio,
debemos configurar los formularios de entrada para que el usuario pueda mandar
posts.

 Para esto, debemos crear un nuevo fichero para la entrada de los posts:

- Dentro del fichero creamos el esqueleto del formulario con todo lo que
necesitemos. Cabe destacar que dentro de este nuevo fichero, debemos requerir
el init, header y footer. Este fichero no es requerido en ningún lado, pero sí
debemos agregar la página en el menú de navegación.

- Comenzamos declarando todas las variables necesarias:


$error = false;  nos va a ayudar con la validación del formulario
$title = '';  declaramos cadenas vacías para que puedan guardar lo que escribió el
usuario.
$excerpt = '';
$content = '';

- Después hacemos la comprobación de la existencia del post, a través del submit


con la variable superglobal $_POST.

if( isset( $_POST[ 'submit-new-post' ] ) ) {

- Dentro de esa misma comprobación, debemos hacer que las variables guarden los
datos insertados por el usuario a través del name de los inputs del formulario.
if( isset( $_POST[ 'submit-new-post' ] ) ) {

$title = $_POST[ 'title' ];


$excerpt = $_POST[ 'excerpt' ];
$content = $_POST[ 'content' ];
}

- Cuando los datos ya estén guardados en las variables, se debe crear un nuevo
array asociativo que guarde esos datos para después poder mostrarlos.

if( isset( $_POST[ 'submit-new-post' ] ) ) {

$title = $_POST[ 'title' ];


$excerpt = $_POST[ 'excerpt' ];
$content = $_POST[ 'content' ];

$new_post = [
'id' => 20,
'title' => $title,
'excerpt' => $excerpt,
'content' => $content,
];
}
- Luego de haber guardado los datos en el array asociativo, podemos comenzar a
hacer todas las validaciones que estimemos convenientes.

if( isset( $_POST[ 'submit-new-post' ] ) ) {


$title = $_POST[ 'title' ];
$excerpt = $_POST[ 'excerpt' ];
$content = $_POST[ 'content' ];

if( empty( $title ) || empty( $content ) ) {


$error = true;
}

else {
$new_post = [
'id' => 20,
'title' => $title,
'excerpt' => $excerpt,
'content' => $content,
];
die( 'vale choro' );
}

- Finalmente se debe mostrar el error y mostrar las variables para que cuando salga
algún error, el usuario no tenga que volver a rellenar todo de nuevo.
<h2>Crea tu entrada: </h2>

<?php if( $error ): ?>


<div class = "error">
DEBE RELLENAR LOS CAMPOS OBLIGATORIOS.
</div>
<?php endif; ?>

<form action="" method="post">


<label for="title">Título (requerido)</label>
<input type="text" name="title" id="title" value="<?php echo $title; ?> ">

<label for="excerpt">Extracto</label>
<input type="text" name="excerpt" id="excerpt" value="<?php echo
$excerpt; ?>">

<label for="content">Contenido (Requerido)</label>


<textarea name="content" id="content" cols="30" rows="30"> <?php echo
$content; ?></textarea>

<p>
<input type="submit" name="submit-new-post" value="Nuevo
post">
</p>
</form>
Conexión a sql

 Para poder conectar nuestra web a la base de datos debemos ir al init y escribir:

$host = 'localhost';
$user = 'root';
$password = ''; debemos declarar estas variables que nos ayudarán con la
conexión
$database = 'microcms';
$port = '3306';

$app_db = mysqli_connect( $host, $user, $password, $database, $port );  le


pasamos el recurso $app_db (si la conexión falla el recurso queda en falso), la
función mysqli_connect y las variables anteriores.
if( $app_db == false ){  comprobamos la conexión.
die( 'Error al conectar' );

- Hacemos la conexión en el init porque es requerido en todas las páginas.

 Ahora en el index, le decimos que el array asociativo será igual a una función que
obtiene y devuelve la lista de posts.

$all_posts = get_all_posts();

- Guardamos el array asociativo y en el fichero que contiene los posts creamos todas
las funciones necesarias.
function get_all_posts() {
global $app_db; llamamos a la conexión como una variable global.
$result = mysqli_query( $app_db, "SELECT * FROM posts" );  creamos una
variable que contendrá la conexión y la query que selecciona los posts de la bd.
if( ! $result ) {  si la query falla, lanza un error.
die( mysqli_error( $app_db ) );
}
return mysqli_fetch_all( $result, MYSQLI_ASSOC ); devolvemos el resultado con
la query como un array asociativo.
}

 Dentro del mismo fichero, ahora tenemos que crear la función que busca y
devuelve todos los posts. Con esta función mostramos los posts:

function get_posts( $post_id ) {


global $app_db;  llamamos a la conexión como una variable global.
$query = "SELECT * FROM posts WHERE id = ". $_GET[ 'view' ]; creamos la query
que va a seleccionar un solo post a través de su id. Le pasamos la variable super global
$_GET para luego hacer la comprobación de existencia de posts a través del enlace.
$result = mysqli_query( $app_db, $query );  creamos una nueva variable que
contiene la conexión y la ejecución de la query.
if( ! $result ) {
die( mysqli_error( $app_db) );  si es resultado falla, lanza error
}
return mysqli_fetch_assoc( $result ); devuelve la variable resultado como un
array asociativo
}
 Volvemos al index y escribimos:
$post_found = false;  declaramos una variable en falso
if( isset( $_GET['view'] ) ) { comprobamos la existencia de los posts a través del enlace.

$post_found = get_posts( $_GET[ 'view' ] );  la variable en falso pasa a ser igual a


la función que busca y devuelve un solo post.

if( $post_found ) { si la variable en falso es verdadera.

$all_posts = [ $post_found ];  el array asociativo pasa a ser igual a la


variable que contiene la función que busca y devuelve los posts.
}
}

- Ahora podemos mostrar los posts en la parte de html.


 En el fichero que contiene los posts, tenemos que crear la función que va a insertar
los posts a la bd y al sitio:

function insert_post( $title, $excerpt, $content ) { creamos la función y le damos como


parámetro los datos a insertar y que declaramos en el fichero del formulario.
global $app_db;  llamamos a la conexión como variable global
$published_on = date( 'Y-m-d H:i:s' ); creamos la variable que va a obtener la
fecha del sistema.
$query = "INSERT INTO posts ( title, excerpt, content, published_on ) VALUES ( '$title',
'$excerpt', '$content', '$published_on')"; creamos una variable que contendrá la
sentencia sql de inserción de datos.

$result = mysqli_query( $app_db, $query );  creamos una nueva variable


que contiene la conexión y la ejecución de la query.
if( ! $result ) {  si el resultado falla, lanza un error.
die( mysqli_error( $app_db ) );
}
}

 Por último, llamamos la función que inserta datos en el fichero del formulario.
$error = false;
$title = '';
$excerpt = '';
$content = '';

if ( isset( $_POST['submit-new-post'] ) ) {
// Se ha enviado el formulario
$title = $_POST['title'];
$excerpt = $_POST['excerpt'];
$content = $_POST['content'];
if ( empty( $title ) || empty( $content ) ) {
$error = true;
}
else {
insert_post( $title, $excerpt, $content );
}
}
?>

Redirecciones y cabeceras

 El usuario envía una petición (tipo get normalmente) al servidor con una seria de
cabeceras para que el servidor identifique de dónde viene la petición y el servidor
contesta con un código de estado (que ha pasado con la petición):

a) 200: está todo bien.


b) 404: no se ha encontrado.
c) 500: error interno del servidor
d) 403 (prohibido): si intentas acceder a un área que no tienes acceso tira este
error.

 El servidor envía el html por trozos (aunque php renderiza todo, el navegador lo
va a enviar por trozos). Cuando el navegador tiene todos los trozos, muestra la
página web. Una vez enviado cualquier trozo, las cabeceras de respuestas ya no se
pueden cambiar.

 Ejemplo de cabecera:

Header( ‘Location: [Link]


 Si enviamos algo de html nunca podremos redireccionar desde donde se nos
ocurra. La idea es redireccionar desde antes de mostrar el html. Siempre debemos
tratar la lógica de los formularios antes de hacer cualquier cosa en html, porque ya
no podremos redireccionar.
 Para poner código de status en el sitio:
<?php http_response_code( 404 ) ?>

 Es muy recomendable que cuando hagamos el redireccionamiento, paremos la


ejecución.

insert_post( $title, $excerpt, $content );


header( 'Location: [Link]');
die();

 Para enviar un mensaje cuando el post ha sido enviado, es necesario ir a new-post


y hacer lo siguiente:

insert_post( $title, $excerpt, $content );


header( 'Location: [Link]?success=true');  le pasamos el parámetro success para que
el navegador sepa que la redirección tuvo éxito.
die();

- Luego en el index después del php y antes del html:

<?php if( isset( $_GET[ 'success' ] ) ): ?>  comprobamos la existencia del post a través de
la url y le damos como parámetro del success.
<div class="success">El post ha sido creado exitósamente =) </div>  mostramos
el mensaje.
<?php endif;?>
 Para eliminar un post:

- Debemos crear un enlace en el index el cual nos redirija a la eliminación, en el


lugar que se estime conveniente, en este caso sería debajo de la fecha.

<div class="delete-post">
<a href="?delete-post=<?php echo $post[ 'id' ]; ?>">Eliminar post</a>  creamos el
enlace y le pasamos el id del post para que lo identifique.
</div>

- Luego, arriba del todo del index se debe:


<?php require( '[Link]' ); ?>
<?php require( 'templates/[Link]' ); ?>
<?php
if( isset( $_GET[ 'delete-post' ] ) )  comprobamos la existencia del post con el enlace que
creamos anteriormente.
{
$id = $_GET[ 'delete-post' ]; creamos la variable id y se lo pasamos al enlace.
delete_post( $id ); llamamos a la función que elimina
header( 'Location: [Link]' );  redireccionamos al index.
die();  paramos la ejecución.
}

- Por último, creamos la función en el fichero post para que elimine el post:
function delete_post( $id )
{
global $app_db;
$result = mysqli_query( $app_db, "DELETE FROM posts WHERE id = $id" );
if( ! $result ){
die( mysqli_error( $app_db ) );
}
}

 REORGANIZAR EL CÓDIGO PARA DESPUÉS PODER SUBIRLO A PRODUCCIÓN:

- En inc (la carpeta donde está el fichero que manipulamos los datos), debemos
crear un nuevo fichero llamado helpers. Ese fichero luego lo requerimos en el init.

- En el fichero helpers creamos una nueva función para redireccionar:

function redirect_to( $path ) le ponemos la ruta para redirigir.


{
header('Location: '. $path);  le pasamos la url del archivo.
die();
}

- Llamamos la función en todos los lugares que necesitemos redirigir


1) if( isset( $_GET[ 'delete-post' ] ) )
{
$id = $_GET[ 'delete-post' ];
delete_post( $id );
redirect_to( '[Link]' );
die();
}

2) if ( empty( $title ) || empty( $content ) ) {


$error = true;
}
else {
insert_post( $title, $excerpt, $content );
redirect_to( '[Link]?success=true' );
}
}

- Para ordenar aún más nuestro código, debemos crear un nuevo fichero que
contenga las configuraciones (configuraciones generales y las de base de datos).

// Configura la salida de errores por pantalla


error_reporting( E_ALL );
ini_set( 'display_errors', 1 );

--DEFINIMOS ESTAS CONSTANTES PARA HACER LA CONEXIÓN Y REDIRECCIÓN--


define( 'SITE_URL', '[Link] );
define( 'SITE_TIMEZONE', 'Australia/Sydney' );
define( 'SITE_LANG', [ 'es', 'spa', 'es_ES'] );

// Conexión a la base de datos


define( 'DB_HOST', 'localhost' );
define( 'DB_USER', 'root' );
define( 'DB_PASSWORD', '');
define( 'DB_DATABASE', 'microcms' );
define( 'DB_PORT', '3306' );
- En el init requerimos el fichero configuración

if( ! file_exists( '[Link]' ) ) comprobamos si el fichero existe arriba del todo del
fichero init
{
die( 'ERROR 20015' );

}
require '[Link]';  llamamos al fichero

setlocale( LC_TIME, SITE_LANG); pasamos la constante definida en config


date_default_timezone_set( SITE_TIMEZONE ); pasamos la constante definida en config

$app_db = mysqli_connect( DB_HOST, DB_USER, DB_PASSWORD, DB_DATABASE,


DB_PORT ); pasamos las constantes definidas en config
if ( $app_db == false ) {
die( 'Error al conectar con la base de datos' );
}

- Finalmente, en el fichero helpers:


function redirect_to( $path )
{
header('Location: '. SITE_URL. '/'. $path);
die();
}
SEGURIDAD BÁSICA

 Filtros de saneamiento: con esto nos preocupamos de que el usuario no pueda


ingresar scripts, html o css a los posts. Si no tenemos saneado el formulario, nos
pueden joder la página metiendo los elementos anteriormente mencionados. Acá
se van a sanear todos los inputs del formulario de ingreso de los posts.

 Para sanear la entrada de los posts:


- FILTER_SANITIZE_STRING:

$title = filter_input( INPUT_POST, 'title', FILTER_SANITIZE_STRING );  el primer


parámetro le dice de dónde viene( desde la variable superglobal POST), el segundo es el
name del input y por último cómo queremos sanearlo.

$excerpt = filter_input( INPUT_POST, 'excerpt', FILTER_SANITIZE_STRING );  lo mismo


para el extracto.

 Como en el contenido nos conviene que aparezca algo de html, debemos colocar
otra función:

-strip_tags:

$content = strip_tags($_POST[ 'content' ], '<br><p><a><img><div>');  con esta función


estamos permitiendo las etiquetas de html que pusimos.

 Para sanear la salida:

- Puede pasar que el título, el extracto y el contenido vengan desde base de datos
con algún script o cualquier cosa que nos pueda joder el sitio. Por eso debemos
sanear la salida.
- Htmlspecialchars: convierte caracteres especiales en entidades html, ósea, si nos
quieren colar cualquier cosa en js o css, lo va a convertir en un string de html, es
como si estuvieran dentro del value y fueran parte de él.

<input type="text" name="title" id="title" value="<?php echo htmlspecialchars( $title,


ENT_QUOTES ) ; ?>">
<input type="text" name="excerpt" id="excerpt" value="<?php echo
htmlspecialchars( $excerpt, ENT_QUOTES ) ; ?>">

<textarea name="content" id="content" cols="30" rows="30"><?php echo


htmlspecialchars( $content, ENT_QUOTES ) ; ?></textarea>

 Inyecciones de sql: se puede dar el caso de que los usuarios en los inputs puedan
meter sentencias sql válidas que nos pueden resultar peligrosas para nuestro sitio
(eliminar las tablas, mostrar los datos, cambiarlos, etc).

- mysqli_real_escape_string( objeto de base de datos, variable a sanear )

- Para poder sanear esto, debemos ir a la función que inserta los posts y poner:

$title = mysqli_real_escape_string( $app_db, $title );


$excerpt = mysqli_real_escape_string( $app_db, $excerpt );
$content = mysqli_real_escape_string( $app_db, $content );

- Otro caso puntual es que el id de los posts llegue con una sentencia sql que nos
joda. Como sabemos que el id es un número, se debe poner lo siguiente:

$post_id = intval( $post_id );  invalidamos cualquier query, porque el id lo


transforma a un número SIEMPRE. Este saneamiento lo debemos poner tanto como en la
función que obtiene y devuelve un solo post, como en la función que elimina posts ($id =
intval( $id ); ).

 CROSS-SITE REQUEST FORGERY: se puede dar el caso de que alguna persona de la


administración reciba algún link de un sitio. Dentro del sitio puede haber links con
sentencias sql que también nos pueden joder nuestro sitio, por eso debemos
sanearlo también:

- En el fichero helpers debemos crear una función que genera un hash:

function generate_hash( $action )  codifica una cadena en otra alfanumérica


{
return md5( $action ); función de seguridad
}

- Luego en el link donde eliminamos los posts ponemos:

<a href="?delete-post=<?php echo $post[ 'id' ]; ?>&hash=<?php echo


generate_hash( 'delete-post-'. $post[ 'id' ] ); ?>"> Eliminar post </a>

- En la condicional donde llamamos la función que elimina el post se debe poner:


if( isset( $_GET[ 'delete-post' ] ) )
{
$id = $_GET[ 'delete-post' ];
if( ¡ check_hash( 'delete-post-'. $id, $_GET[ 'hash' ] ) )
{
die( 'NO HAY MANO COMPA' );
}
delete_post( $id );
redirect_to( '[Link]' );
die();

}
- Por último, debemos crear una función que chequee el hash:
function check_hash( $action, $hash )
{
if( generate_hash( $action ) === $hash )
{
return true;
}
return false;
}

LOGIN MEDIANTE SISTEMA DE SESIONES

 La idea principal de hacer un login con sesiones, es que solo una persona
(administrador) pueda manipular las entradas del blog.

- Para esto, se debe crear el fichero login y crear un pequeño formulario con el
nombre de usuario, contraseña, un campo oculto y el botón submit. Obviamente
se debe comprobar la existencia del formulario ( isset( $_POST[ ‘submit-login’] ) y
verificar el hash que tenemos en el campo oculto.

- También debemos crear en el menú un nuevo login que nos lleve hasta este
fichero.

 Las sesiones guardan datos desde una página que se recarga hacia otra. Para esto,
php cuenta con una variable $_SESSION. Estas sesiones son solo para la persona
que ocupa la página y no para otra.

- Para usar las sesiones, debemos comenzar a usarlas con la función session_start();
pero hay que tener ojo con los espacios en blanco para no cargar nada antes de la
sesión.
 Abremos la sesión en el [Link]
if ( ! file_exists( '[Link]' ) ) {
die( 'ERROR:No existe [Link]' );
}
session_start(); sesión abierta

require '[Link]';

- Hacemos una validación de los datos:


if( ! login( $_POST[ 'username' ] , $_POST[ 'password' ] ) )  llamamos a la
función de logeo( está más adelante ). Si NO devuelve true, la variable error es
true.
{
$error = true;
}

- Luego de validar los datos, ponemos lo siguiente:


if( is_logged_in() ) llamamos a la función is_logged_in() (está más adelante) que
comprueba si el usuario se ha logeado.
{
redirect_to( '[Link]' );  esta condicional nos sirve para que cuando se
logee, redirija al index y si ya está logado que no pueda volver al fichero de login.
}

 Después de tener los datos del LOGIN, debemos hacer el LOGOUT.

- Primero creamos un nuevo enlace en el menú que diga logout y además le


pasamos un link: <li><a href="?logout=true">Logout</a></li>
- Vamos al [Link] y creamos 3 funciones nuevas:

a) Is_logged_in(): COMPRUEBA SI EL USUARIO HA HECHO LOGIN


function is_logged_in()
{
$is_user_logged_in = isset($_SESSION[ 'user' ] ) && $_SESSION[ 'user' ] ===
ADMIN_USER;
return $is_user_logged_in;
}

b) Login( $username, $password): acepta un usuario y contraseña para hacer el


logeo
function login( $username, $password )
{
if( $username === ADMIN_USER && $password === ADMIN_PASS )
{
$_SESSION[ 'user' ] = ADMIN_USER;
return true;
}
return false;
}
c) Logout(): COMPRUEBA EL DESLOGEO DE LA SESIÓN

function logout()
{

unset( $_SESSION[ 'user' ] );


redirect_to( '[Link]' );
session_destroy();  se destruye la sesión para liberar memoria
}

- Luego en el init (al último) comprobamos que exsita el deslogeo.

if( isset( $_GET[ 'logout' ] ) )  comprobamos que existe


{
logout(); llamamos a la función para deslogar
}

 Si queremos cambiar de usuario, debemos crear nuevas constantes en el config:


define( 'ADMIN_USER', 'sammy' );
define( 'ADMIN_PASS', 'caca' );

 Por último, en la parte del menú del header podemos poner una condición para
mostrar en el menú login si no está logado y logout si está logado:
<?php if( is_logged_in() ): ?>
<li><a href="?logout=true">Logout</a></li>
<?php else: ?>
<li><a href="[Link]">Login</a></li>
<?php endif; ?>
Controlador frontal (administración)

 Creamos la sección de administración (carpeta admin) solo para usuarios que


hayan hecho login. Acá vamos a listar los posts, crearlos y borrarlos.

 Creamos el fichero [Link] donde será la zona de administración principal.

- En el header, creamos un nuevo enlace. Idealmente dentro del if que muestra los
enlaces para el admin y para el usuario.

<li><a href="<?php echo SITE_URL; ?>/admin">Administración</a></li>

- Antes de requerir cualquier fichero, en el init se debe colocar la súper constante


__DIR__ que no solo busca en su propia carpeta, sino que también en las demás.

if ( ! file_exists( __DIR__ .'/[Link]' ) ) {


die( 'ERROR:No existe [Link]' );
}

- En el index del admin requerimos el init y comprobamos el login

require '../[Link]';

if( ! is_logged_in() )
{

redirect_to( '[Link]' );

}
- En el fichero de admin creamos la sección con los links para eliminar y crear un
post, le agregamos los action para luego llamarlos y poner toda la lógica que
necesitemos.

<!--LISTADO DE ADMINISTRACIÓN-->
<?php require __DIR__.'/../../templates/[Link]'; ?> tiene la ruta de dos
carpetas porque lo copié así (cuando estaba todo listo). Para que funcione en este punto
debe haber ruta de solo una carpeta. PERO OJO CUANDO CREEMOS LA CARPETA
TEMPLATES HAY QUE MODIFICARLO COMO ESTÁ ACÁ.
<h2>Administración</h2>
<ul>
<li><a href="?action=list-posts">Listado de posts</a></li>
<li><a href="?action=new-post">Nuevo post</a></li>
</ul>
<?php require __DIR__.'/../../templates/[Link]'; ?>

- Cargamos la cabecera y el footer y para los estilos, con la constante SITE_URL


define( 'SITE_URL', '[Link]
7/02-login-con-sesiones/01-inicio/' );
Luego en la cabecera modificamos el link de los estilos, se puede hacer lo mismo
con los otros link, pero no es necesario porque funcionaría igual.
<link rel="stylesheet" href="<?php echo SITE_URL; ?>/assets/[Link]"></head>

- En el index del admin comprobamos la existencia del action y lo guardamos en una


variable

$action = ' ';  por defecto tiene que ser una cadena vacía
if( isset( $_GET[ 'action' ] ) )
{

$action = $_GET[ 'action' ];

}
- Esa variable la agregamos a un switch para colocar la lógica en caso de que el
admin vaya a list-post o new-post

Switch( $action )
{
Case ‘list-post’:
{
Break;
}

Case ‘new-post’:
{
Break;
}

Default:
{
require 'templates/[Link]';  por defecto mostramos la pantalla
principal del administrador
}
}

 Ahora debemos crear dentro de la carpeta admin una nueva carpeta templates,
donde tendremos los ficheros de list-post y new-post.

 En el fichero list-post tendremos el html de los posts mostrados en una lista y con
el link del borrado.
<?php require __DIR__. '/../../templates/[Link]'; ?>  el enlace va así porque
ahora es otra carpeta la que tenemos que recorrer
<?php if ( isset( $_GET[ 'success' ] ) ): ?>
<div class="success">
El post ha sido creado
</div>
<?php endif;?>
<table>
<?php foreach( $all_post as $post ): ?>
<tr>
<td> <?php echo $post[ 'title' ]; ?></td>
<td><a href="<?php echo SITE_URL. '/admin?
action=list-posts&delete-post='. $post[ 'id' ]?>&hash=<?php echo generate_hash( 'delete-
post-' . $post['id'] ); ?>">Eliminar post</a></td>
</tr>
<?php endforeach;?>
</table>
<?php require __DIR__. '/../../templates/[Link]'; ?>

- Ahora en el switch ponemos toda la lógica referente a list-post

switch ( $action )
{
case 'new-post':{
require 'templates/[Link]';
break;
}
case 'list-posts':
{
if ( isset( $_GET['delete-post'] ) ) {
$id = $_GET['delete-post'];
if ( ! check_hash( 'delete-post-' . $id, $_GET['hash'] ) ) {
die( 'Hackeando, no?' );
}
delete_post( $id );
redirect_to( 'admin?action=list-posts' );
die();
}
$all_post = get_all_posts();  debemos guardar la función que busca y
devuelve toda la lista de posts.
require 'templates/[Link]';  Al final del case se debe requerir el
fichero con el html
break;
}
default:
{
require 'templates/[Link]';
}
}

-------OJO PORQUE EN EL INDEX PRINCIPAL DEBEMOS MOVER AL CASE DE LIST-


POST TODO LO RELACIONADO CON DELETE-POST, BORRAR EL SUCCESS, EL ENLACE
QUE BORRA LOS POSTS Y EL ENLACE NUEVA ENTRADA EN EL HEADER-------

 En el fichero new-post pondremos el html del formulario de ingreso de posts


<?php require __DIR__. '/../../templates/[Link]'; ?>
<h2>Crear nuevo post</h2>

<?php if ( $error ): ?>


<div class="error">
Error en el formulario.
</div>
<?php endif; ?>

<form action="" method="post">


<label for="title">Título (requerido)</label>
<input type="text" name="title" id="title" value="<?php echo
htmlspecialchars( $title, ENT_QUOTES ); ?>">

<label for="excerpt">Extracto</label>
<input type="text" name="excerpt" id="excerpt" value="<?php echo
htmlspecialchars( $excerpt, ENT_QUOTES ); ?>">

<label for="content">Contenido (Requerido)</label>


<textarea name="content" id="content" cols="30" rows="30"><?php echo
htmlspecialchars( $content, ENT_QUOTES ); ?></textarea>

<p>
<input type="submit" name="submit-new-post" value="Nuevo
post">
</p>
</form>
<?php require __DIR__. '/../../templates/[Link]';
- Luego en el switch ponemos la lógica del formulario

switch ( $action )
{
case 'new-post':{

$error = false;
$title = '';
$excerpt = '';
$content = '';

if ( isset( $_POST['submit-new-post'] ) ) {
// Se ha enviado el formulario
$title = filter_input( INPUT_POST, 'title', FILTER_SANITIZE_STRING );
$excerpt = filter_input( INPUT_POST, 'excerpt', FILTER_SANITIZE_STRING );
$content = strip_tags( $_POST['content'], '<br><p><a><img><div>' );

if ( empty( $title ) || empty( $content ) ) {


$error = true;
}
else {
insert_post( $title, $excerpt, $content );
// Redirigir al blog
redirect_to( 'admin?action=list-posts&success=true' );
}
}
require 'templates/[Link]';
break;
}

case 'list-posts':
{
}
default:
{
require 'templates/[Link]';
}
}

-----TENEMOS QUE BORRAR EL FICHERO NEW POST QUE HABÍA EN EL INDEX DEL
USUARIO-----

También podría gustarte