Guía Básica de PHP para Principiantes
Guía Básica de PHP para Principiantes
php y un servidor.
SINTAXIS DE PHP
/* muchas
Líneas*/
$nombre = “Ignacio”.
- Las variables son sensibles a mayúsculas y minúsculas, por lo tanto, hay que tener
ojo al momento de declararlas.
- 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”>
</div>
Las funciones son trozos de código que ejecutan acciones, pero primero debemos
llamarlas:
}
- Existen funciones que no tienen parámetros:
function QueDiaEsHoy () {
- Para llamar las funciones en php se debe hacer después del código php pero antes
del html:
<?php
¿>
<!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;
function prueba () {
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;
}
?>
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]:
- 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
En php existen los arrays asociativos: son arreglos que tienen elementos con
valores asignados.
- Para acceder a los elementos de este array no es necesario poner la posición, solo
el elemento.
$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.
- While
- Do-while
- For
}
- Foreach (el más usado):
echo $post["title"];
echo "</br>";
}
FECHAS
Ejemplo: echo date ( ‘d/m/y’ ); //12/03/2020 (saca la hora actual del servidor)
- 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:
- 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' );
¿>
<span class="post-date">
Publicada en:
</span>
Por último, debemos establecer qué hora (según zona horaria) queremos para
nuestra página web:
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.
$_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).
- Operadores de asignación:
$z = 50;
$x = $z:
var_dump ( $x );
//suma y asigna
//resta y asigna
//multiplica y asigna
//divide y asigna
$y = 10;
var_dump ( “ $x === $Y ” );
var_dump ( $x === $Y );
- Operadores de cadenas:
$cadena2 .= $cadena1;
var_dump ( $cadena2 );
- Operadores lógicos
a) && (and):
var_dump ( $x && $Y );
b) || (or):
var_dump ( $x || $Y );
c) ! (not):
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
}
}
<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>
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();
- 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.
- 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 ( $post_found ) {
- 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.
- 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' ] ) ) {
- 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.
$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.
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>
<label for="excerpt">Extracto</label>
<input type="text" name="excerpt" id="excerpt" value="<?php echo
$excerpt; ?>">
<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';
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:
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):
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:
<?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:
<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>
- 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 ) );
}
}
- 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.
- 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).
if( ! file_exists( '[Link]' ) ) comprobamos si el fichero existe arriba del todo del
fichero init
{
die( 'ERROR 20015' );
}
require '[Link]'; llamamos al fichero
Como en el contenido nos conviene que aparezca algo de html, debemos colocar
otra función:
-strip_tags:
- 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.
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).
- Para poder sanear esto, debemos ir a la función que inserta los posts y poner:
- 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:
}
- 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;
}
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]';
function logout()
{
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)
- En el header, creamos un nuevo enlace. Idealmente dentro del if que muestra los
enlaces para el admin y para el usuario.
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]'; ?>
$action = ' '; por defecto tiene que ser una cadena vacía
if( isset( $_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]'; ?>
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]';
}
}
<label for="excerpt">Extracto</label>
<input type="text" name="excerpt" id="excerpt" value="<?php echo
htmlspecialchars( $excerpt, ENT_QUOTES ); ?>">
<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>' );
case 'list-posts':
{
}
default:
{
require 'templates/[Link]';
}
}
-----TENEMOS QUE BORRAR EL FICHERO NEW POST QUE HABÍA EN EL INDEX DEL
USUARIO-----