Skip to main content.

Ejemplos

Para probar los ejemplos entrar al siguiente enlace.

HTML

base.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" />
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="es" lang="es">
	<head>
		<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
		<link rel="shortcut icon" href="favicon.png" />
		<link rel="stylesheet" type="text/css" href="css.css" media="screen"/>
		<script type="text/javascript" src="js.js"></script>
		<title>Título de la página</title>
	</head>
	<body>
		<div id="page">
		</div>
	</body>
</html>

CSS

index.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" />
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="es" lang="es">
	<head>
		<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
		<link rel="stylesheet" type="text/css" href="style.css" media="screen"/>
		<title>Ejemplo de Layout</title>
	</head>
	<body>
		<!-- div principal que incluye al resto -->
		<div id="page">
			<div id="header">
				Ejemplo de Layout
			</div>
			<div id="nav">
				<a href="http://www.google.cl" title="Ir a Google">Google</a>
				<a href="http://www.unab.cl" title="Ir a UNAB">UNAB</a>
				<a href="http://delaf.cl" title="Ir a DeLaF">DeLaF</a>
				<a href="http://unab.delaf.cl" title="Ir a UNAB by DeLaF">UNAB by DeLaF</a>
				<a href="#titulo" title="Mover al título">Título</a>
				<a href="#subtitulo" title="Mover al subtítulo">Subtítulo</a>
			</div>
			<div id="content">
				<h1 id="titulo">Título de la página</h1>
				<p>Parrafo principal de la página.</p>
				<h2 id="subtitulo">Subtítulo</h2>
				<p>Este es el contenido en un parrafo del subtítulo.</p>
				<p>Otro parrafo del subtítulo.</p>
			</div>
			<div class="clear"></div>
			<div id="footer">
				&copy; DeLaF
			</div>
		</div>
	</body>
</html>
style.css
body {
	background: #eee;
	font-size: 14px;
	font-family: monospace;
}

/* el estilo de #page pondrá la página centrada con tamaño fijo */
#page {
	width: 950px;
	margin: 0 auto;
}

#header, #nav, #content, #footer {
	border: 1px solid black;
	margin-bottom: 10px;
	background: white;
}

#header {
	padding: 20px;
	font-size: 3em;
	text-align: center;
	text-shadow: #333 5px -5px 5px;
}

#nav {
	width: 200px;
	float: left;
}

#content {
	width: 715px;
	float: right;
	padding: 10px;
}

#footer {
	padding: 5px;
	text-align: center;
	font-size: 0.8em;
}

#nav > a {
	display: block;
	text-decoration: none;
	color: black;
	background: #ccc;
	padding: 5px;
}

#nav > a:hover {
	text-decoration: underline;
	background: #eee;
}

#content > h1 {
	border-bottom: 2px groove gray;
}

#content > p {
	text-align: justify;
}

.clear {
	clear: both;
}

Javascript (jQuery)

index.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" />
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="es" lang="es">
	<head>
		<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
		<link rel="stylesheet" type="text/css" href="style.css" media="screen"/>
		<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js"></script>
		<script type="text/javascript" src="js.js"></script>
		<title>Ejemplo de Javascript (Jquery)</title>
	</head>
	<body>
		<div id="page">
			<div id="header">
				Ejemplo de Javascript (Jquery)
			</div>
			<div id="nav">
				<a href="#" onclick="getText('titulo')">Texto del título</a>
				<a href="#" onclick="changeColor('subtitulo', 'red')">Subtítulo rojo</a>
				<a href="#" onclick="changeColor('subtitulo', 'black')">Subtítulo negro</a>
				<a href="#" onclick="hide('content')">Ocultar #content</a>
				<a href="#" onclick="show('content')">Mostrar #content</a>
				<a href="#" onclick="addP()">Agregar párrafo</a>
				<a href="#" onclick="replaceContent()">Reemplazar #content</a>
			</div>
			<div id="content">
				<h1 id="titulo">Título de la página</h1>
				<p>Parrafo principal de la página.</p>
				<h2 id="subtitulo">Subtítulo</h2>
				<p>Este es el contenido en un parrafo del subtítulo.</p>
				<p>Otro parrafo del subtítulo.</p>
			</div>
			<div class="clear"></div>
			<div id="footer">
				&copy; DeLaF
			</div>
		</div>
	</body>
</html>
js.js
$(function() {
	// el contenido de esta función se ejecutará al cargar la página
});

function getText (id) {
	alert($('#'+id).text());
}

function changeColor(id, color) {
	$('#'+id).css('color', color);
}

function hide (id) {
	$('#'+id).fadeOut(400);
}

function show (id) {
	$('#'+id).fadeIn(400);
}

function addP () {
	$('#content').append('<p>Nuevo párrafo!!</p>');
}

function replaceContent () {
	$('#content').html('<h1>Nuevo título!!</h1><p>Nuevo párrafo del nuevo #content</p>');
}
style.css
body {
	background: #eee;
	font-size: 14px;
	font-family: monospace;
}

#page {
	width: 950px;
	margin: 0 auto;
}

#header, #nav, #content, #footer {
	border: 1px solid black;
	margin-bottom: 10px;
	background: white;
}

#header {
	padding: 20px;
	font-size: 3em;
	text-align: center;
	text-shadow: #333 5px -5px 5px;
}

#nav {
	width: 200px;
	float: left;
}

#content {
	width: 715px;
	float: right;
	padding: 10px;
}

#footer {
	padding: 5px;
	text-align: center;
	font-size: 0.8em;
}

#nav > a {
	display: block;
	text-decoration: none;
	color: black;
	background: #ccc;
	padding: 5px;
}

#nav > a:hover {
	text-decoration: underline;
	background: #eee;
}

#content > h1 {
	border-bottom: 2px groove gray;
}

#content > p {
	text-align: justify;
}

.clear {
	clear: both;
}

PHP

01_hola_mundo.php
<?php echo 'Hola Mundo!'; ?>
02_variables.php
<?php

// estas son variables
$variable = 'soy un string';
echo $variable,'<br />';

$variable = 10;
echo $variable,'<br />';

$variable = array(1,2,3,4,5);
echo $variable,'<br />';
print_r($variable); echo '<br />';

// esto es una constante
define('CONSTANTE', 'VALOR');
echo CONSTANTE, '<br />';

// operadores para variables
// +, -, /, *, %
// || (or)
// && (and)
// ! (negación)
03_arreglos.php
<?php

// Funciona en PHP 5.4
//$arreglo = [1,2,3];
//array_show($arreglo);

$arreglo = array(1,2,3);
array_show($arreglo);

$arreglo = array();
$arreglo[] = 1;
$arreglo[] = 2;
$arreglo[] = 3;
array_show($arreglo);

$arreglo = array();
array_push($arreglo, 1);
array_push($arreglo, 2);
array_push($arreglo, 3);
array_show($arreglo);

array_show(array(
	1,
	'hola',
	array(1, 2 , 3),
	array(1, 2, 3),
	array('hola', 'mundo'),
	'clave'=>'valor',
	'otroarreglo'=>array(
		'masclaves'=>array(
			array('a', 'b', 'c')
		)
	)
));

function array_show ($arreglo = array()) {
	echo '<pre>';
	print_r($arreglo);
	echo '</pre>';
}
04_funciones.php
<?php

function funcion1 () {
	echo 'Funcion sin parametros', '<br />';
}

function funcion2 () {
	return 'Funcion que retorna'.'<br />';
}

function funcion3 ($par1, $par2) {
	echo 'Parametro 1 ',$par1,' y parametro 2 ',$par2, '<br />';
}

function funcion4 ($par1, $par2) {
	return 'Parametro 1 '.$par1.' y parametro 2 '.$par2.' retornados'.'<br />';
}

function funcion5() {
	return array('variable1'=>'valor1', 'variable2'=>'valor2');
}

funcion1();
echo funcion2();
funcion3('valor1', 'valor2');
echo funcion4('valor1', 'valor2');
print_r(funcion5()); echo '<br />';
05_polimorfismo.php
<?php

function sin_polimorfismo ($var1, $var2) {
	echo $var1,' y ',$var2,'<br />';	
}

// ¿polimorfismo?
function con_polimorfismo ($var1 = 'var1', $var2 = 'var2') {
	echo $var1,' y ',$var2,'<br />';	
}

sin_polimorfismo('variable1', 'variable2');
con_polimorfismo();
con_polimorfismo('var 1', 'var 2');

// y si tengo varios parámetros y solo quiero especificar el último
// function f($a=1, $b = true, $c = false);
// f(1, true, true);
// (nos damos cuenta que en realidad no hay polimorfismo)

function varios_parametros ($params = array()) {
	// valores por defecto
	$params = array_merge(array(
		'var1' => 'variable1',
		'var2' => 'variable2',
	), $params);
	// imprimir valores
	echo '<pre>';
	print_r($params);
	echo '</pre>';
}

varios_parametros();
varios_parametros(array('var2'=>'variable 2 con truco'));
06_get.php
<a href="?variable">Variable declarada pero no inicializada</a><br />
<a href="?variable=valor">Variable declarada e inicializada</a><br />
<a href="?var1=valor1&amp;var2=valor2">Multiples variables</a>

<?php

echo '<pre>';
print_r($_GET);
echo '</pre>';
07_condicionales.php
<a href="?var=1">Enviar 1</a><br />
<a href="?var=2">Enviar 2</a><br />
<a href="?var">Enviar vacia</a><br />
<a href="?var=3">Confundir</a><br />

<?php

// con if
if(isset($_GET['var'])) {
	if($_GET['var']==1) {
		echo '<p>Enviado un 1</p>';
	}
	else if($_GET['var']==2) {
		echo '<p>Enviado un 2</p>';
	} else if($_GET['var']=='') {
		echo '<p>Enviada vacia</p>';
	}
	else {
		echo '<p>No se que hacer</p>';
	}
}

// con switch
if(isset($_GET['var'])) {
	switch($_GET['var']) {
		case 1:
			echo '<p>Enviado un 1 (switch)</p>';
			break;
		case 2:
			echo '<p>Enviado un 2 (switch)</p>';
			break;
		case '':
			echo '<p>Enviada vacia (switch)</p>';
			break;
		default:
			echo '<p>No se que hacer (switch)</p>';
	}
}

// con truco
if(isset($_GET['var'])) {
	echo $_GET['var']==1 ? '<p>Enviado 1 (con truco)</p>' : ( $_GET['var']==2 ? '<p>Enviado 2 (con truco)</p>' : ($_GET['var']=='' ? '<p>Enviada vacia (con truco)</p>' : '<p>No se que hacer (con truco)</p>') );
}
08_repetidores.php
<?php

// for
for ($i=0; $i<10; ++$i) {
	echo 'Contando: ', $i, '<br />'; 
}
echo '<br />';

// foreach
$arreglo = array(
	'c1' => 'v1',
	'c2' => 'v2',
	'c3' => 'v3',
);
foreach ($arreglo as $key=>&$value) {
	echo 'arreglo[',$key,'] = ', $value, '<br />';
}
echo '<br />';

// while
$i = 0;
while($i<10) {
	echo 'Contando: ', $i, '<br />'; 
	++$i;
}
echo '<br />';
unset($i);

// do while
$i = 0;
do {
	if(!isset($i)) $i = 0;
	echo 'Contando: ', $i, '<br />'; 
	++$i;
} while($i<10);
09_incluir.php
<a href="?arreglos">Ejemplo arreglos</a><br />
<a href="?repetidores">Ejemplo repetidores</a><br />
<br />

<?php

if(isset($_GET['arreglos'])) include '03_arreglos.php';
else if(isset($_GET['repetidores'])) require '08_repetidores.php';

// existe include_once y require_once, ¿para qué?
10_incluir_mal.phps
<ul>
	<li> Variable any
		<ul>
			<li><a href="?any=03_arreglos.php">Enlace legitimo: Ejemplo arregos</a></li>
			<li><a href="?any=/etc/passwd">Obtener /etc/passwd</a></li>
		</ul>
	</li>
	<li> Variable page
		<ul>
			<li><a href="?page=/etc/passwd">Obtener /etc/passwd (no funciona)</a></li>
			<li><a href="?page=../../../../../../../../../../../../../../etc/passwd">Obtener /etc/passwd</a></li>
		</ul>
	</li>
</ul>
<br />

<?php

// requiere: allow_url_include = On para URLs
if(isset($_GET['any'])) include $_GET['any'];

// solo lo del directorio "pages"
if(isset($_GET['page'])) include 'pages/'.$_GET['page'];

// ¿más?
// - buscar como LFI y/o RFI
// - inyección de %00
// - escribir en logs y luego incluir
// - etc
11_funciones_comunes.php
<?php

// enviar cabecera (en este caso el tipo de contenido)
header('Content-type: text/html');

// enviar cabecera para redireccionar a otra página
// header('location: /inicio');
// header('location: http://delaf.cl');

// imprimir tipo y valor de una variable
var_dump('texto'); echo '<br />';					// string(5) "texto" 

// cuenta la cantidad de elementos de un arreglo
echo count(array('a', 'b', 'c')),'<br />';			// 3

// separar por expresion y convertir a arreglo
print_r(explode(' ', 'esto ahora sera un arreglo')); echo '<br />';

// unir arreglo mediante una expresion y convertir a string
echo implode(';',array(1,2,3)),'<br />';

// determinar si un arreglo
var_dump(is_array(array(1,2,3))); echo '<br />';	// bool(true)

// determinar si la variable ha sido seteada (existe)
var_dump(isset($var)); echo '<br />';				// bool(false)

// determinar si la variable esta vacia
var_dump(empty($var)); echo '<br />';				// bool(true)

// largo de una cadena de caracteres
echo strlen('/var/log'),'<br />';					// 8

// extraer una parte del string
echo substr('holanda', 2),'<br />';					// landa
echo substr('holanda', 2, 2),'<br />';				// la
echo substr('holanda', -2),'<br />';				// da
echo substr('holanda', 2, -2),'<br />';				// lan

// reemplazar texto en un string
echo str_replace('X', 'Y', 'XYZ'),'<br />';			// YYZ
echo str_replace(array('X', 'Y'), array('A', 'B'), 'XYZ'),'<br />';	// ABZ

// formatear un número
echo number_format(1234567890, 2, ',', '.'), '<br />'; // 1.234.567.890,00

// codificar para usar en url
echo urlencode('Hola Mundo!'),'<br />';				// Hola+Mundo%21

// decodificar url
echo urldecode('Hola+Mundo%21'),'<br />';			// Hola Mundo!

// codificar en base64
echo base64_encode('Hola Mundo!'),'<br />';			// SG9sYSBNdW5kbyE=

// decodificar en base64
echo base64_decode('SG9sYSBNdW5kbyE='),'<br />';	// Hola Mundo!

// ejecutar un comando de la terminal
system('uname -a'); echo '<br />';					// salida de uname

// aproximar
echo round(2.5),'<br />';							// 3

// truncar
echo floor(2.5),'<br />';							// 2

// elevar al siguiente entero
echo ceil(2.2),'<br />';							// 3

// fecha y hora
date_default_timezone_set('America/Santiago');
echo date('Y-m-d H:i:s'),'<br />';					// 2012-08-22 17:52:51
12_server.php
<?php

echo '<pre>';
print_r($_SERVER);
echo '</pre>';
13_archivos.php
<?php

// directorio padre
echo dirname('/var/log'),'<br />';						// /var

// nombre del archivo o directorio si la ruta completa
echo basename('/var/log'),'<br />';						// log

// determinar si un archivo existe
var_dump(file_exists('/etc/passwd')); echo '<br />';	// bool(true)

// determinar si un archivo es un directorio
var_dump(is_dir('/holanda')); echo '<br />';		// bool(false)

// archivos y directorios de la raiz (incluyendo ocultos)
print_r(scandir('/')); echo '<br />';

// leer archivo
echo '<textarea cols="30" rows="6">';
echo file_get_contents('12_server.php');
echo '</textarea>';

// escribir archivo
//file_put_contents('archivo.txt', $contenido);

// Otras funciones útiles:
// is_readable
// is_writable
// is_executable
// unlink
// rmdir
// mkdir
// touch
// fileperms
// filesize
14_email.php
<?php

// se requiere PHP Pear y las clases Mail, Mail_Mime y Net_SMTP
// instalar con:
//  # pear install Mail
//  # pear install Mail_Mime
//  # pear install Net_SMTP
require 'Mail.php';
require 'Mail/mime.php';

// configuración
// Se debe completar:
//  - usuario y clave para el servidor
//  - quien envia el correo
//  - a quien se envia el correo
$config = array(
	'host'		=> 'ssl://smtp.gmail.com',
	'port'		=> 465,
	'auth'		=> true,
	'username'	=> '',
	'password'	=> '',
	'debug'		=> false
);
$from = array('name'=>'', 'email'=>'');
$replyTo = $from['email'];
$to = '';
$subject = 'Asunto del correo';
$text = 'Correo en texto plano';
$html = '<strong>Correo en html</strong>';

// Crear correo
$mailer = Mail::factory('smtp', $config);
$mail = new Mail_mime();

// codificacion
$mail->_build_params['text_encoding'] = '8bit';
$mail->_build_params['text_charset'] = 'UTF-8';
$mail->_build_params['html_charset'] = 'UTF-8';
$mail->_build_params['head_charset'] = 'UTF-8';
$mail->_build_params['head_encoding'] = '8bit';

// Asignar mensaje
$mail->setTXTBody($text);
$mail->setHTMLBody($html);

// cuerpo y cabecera
$body = $mail->get(); // debe llamarse antes de headers
$headers = $mail->headers(array(
	'From' => "{$from['name']} <{$from['email']}>",
	'To' => $to,
	'Reply-To' => $replyTo,
	'Return-Path' => $replyTo,
	'Subject' => $subject,
));

// Enviar correo al destinatario
$mailer->send($mail->encodeRecipients($to), $headers, $body);

Formularios

01_formulario.php
<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
	<div>
		<div class="label"><label for="text">text</label></div>
		<div class="field"><input type="text" name="text" id="text" /></div>
	</div>
	<div>
		<div class="label"><label for="textarea">textarea</label></div>
		<div class="field"><textarea name="textarea" id="textarea"></textarea></div>
	</div>
	<div>
		<div class="label"><label for="select">select</label></div>
		<div class="field"><select name="select" id="select">
			<option value="o1">Opcion 1</option>
			<option value="o2">Opcion 2</option>
			<option value="o3">Opcion 3</option>
		</select></div>
	</div>
	<div>
		<div class="label"><label for="radio">radio</label></div>
		<div class="field">
			<input type="radio" name="radio" value="r1" id="radio" /> Radio 1
			<input type="radio" name="radio" value="r2" /> Radio 2
			<input type="radio" name="radio" value="r3" /> Radio 3
		</div>
	</div>
	<div>
		<div class="label"><label for="checkbox">checkbox</label></div>
		<div class="field"><input type="checkbox" name="checkbox" id="checkbox" /> Checkbox</div>
	</div>
	<div>
		<div class="label"><label for="checkboxes">checkboxes</label></div>
		<div class="field">
			<input type="checkbox" name="checkboxes[]" value="c1" id="checkboxes" /> Checkbox 1
			<input type="checkbox" name="checkboxes[]" value="c2" /> Checkbox 2
			<input type="checkbox" name="checkboxes[]" value="c3" /> Checkbox 3
		</div>
	</div>
	<div>
		<div class="field"><input type="submit" name="submit" value="Enviar" /></div>
	</div>
</form>

<?php

echo '<pre>';
print_r($_POST);
echo '</pre>';
02_semaforo.php
<p>Ingresar valor entre 1 y 100:</p>
<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
	<input type="text" name="val" />
	<input type="submit" name="submit" value="Cambiar color" />
</form>

<?php
function semaforo ($val) {
	if($val<=35) return 'red';
	else if($val>35&&$val<=70) return 'yellow';
	else if($val>70) return 'green';
}
$semaforo = semaforo(!empty($_POST['val'])?$_POST['val']:100);
?>

<div style="width: 100px; height: 100px; background: <?php echo $semaforo; ?>"></div>
03_archivos.php
<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post" enctype="multipart/form-data">
	<div>
		<div class="label"><label for="file">file</label></div>
		<div class="field"><input type="file" name="file" id="file" /></div>
	</div>
	<div>
		<div class="field"><input type="submit" name="submit" value="Enviar" /></div>
	</div>
</form>

<?php

echo '<pre>';
print_r($_POST);
echo '</pre>';

echo '<pre>';
print_r($_FILES);
echo '</pre>';
04_js.js
/**
 * Verifica si un objeto esta vacio
 * @param obj Objeto que se desea verificar que sea vacio
 * @return True si el objeto pasado es vacio
 * @author http://frugalcoder.us/post/2010/02/15/js-is-empty.aspx
 * @version 2011-04-17
 */
function vacio (obj) {
	if (typeof obj == 'undefined' || obj === null || obj === '') return true;
	if (typeof obj == 'number' && isNaN(obj)) return true;
	if (obj instanceof Date && isNaN(Number(obj))) return true;
	return false;
}

/**
 * Valida que los campos de un formulario no sean vacios
 * @author DeLaF, esteban[at]delaf.cl
 * @version 2012-08-27
 */
function validarFormulario () {
	var status = true;
	$.each($('.fieldRequired'), function(key, field) {
		if(vacio(field.value)) {
			var div = $(field).parent().parent();
			var label = $(div).children('.label').text();
			alert(label.replace('*', '') + ': campo requerido');
			field.focus();
			status = false;
			return false;
		}
	});
	return status;
}
04_validar.php
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" />
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="es" lang="es">
	<head>
		<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
		<link rel="stylesheet" type="text/css" href="style.css" media="screen"/>
		<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js"></script>
		<script type="text/javascript" src="04_js.js"></script>
		<title>Validación de formularios</title>
	</head>
	<body>
		<div id="page">

<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post" onsubmit="return validarFormulario();">
	<div>
		<div class="label"><label for="text">text</label></div>
		<div class="field"><input type="text" name="text" id="text" class="fieldRequired" /></div>
	</div>
	<div>
		<div class="label"><label for="textarea">textarea</label></div>
		<div class="field"><textarea name="textarea" id="textarea" class="fieldRequired"></textarea></div>
	</div>
	<div>
		<div class="label"><label for="select">select</label></div>
		<div class="field"><select name="select" id="select" class="fieldRequired">
			<option value="">Seleccione una opcion</option>
			<option value="o1">Opcion 1</option>
			<option value="o2">Opcion 2</option>
			<option value="o3">Opcion 3</option>
		</select></div>
	</div>
	<div>
		<div class="label"><label for="radio">radio</label></div>
		<div class="field">
			<input type="radio" name="radio" value="r1" id="radio" /> Radio 1
			<input type="radio" name="radio" value="r2" /> Radio 2
			<input type="radio" name="radio" value="r3" /> Radio 3
		</div>
	</div>
	<div>
		<div class="label"><label for="checkbox">checkbox</label></div>
		<div class="field"><input type="checkbox" name="checkbox" id="checkbox" /> Checkbox</div>
	</div>
	<div>
		<div class="label"><label for="checkboxes">checkboxes</label></div>
		<div class="field">
			<input type="checkbox" name="checkboxes[]" value="c1" id="checkboxes" /> Checkbox 1
			<input type="checkbox" name="checkboxes[]" value="c2" /> Checkbox 2
			<input type="checkbox" name="checkboxes[]" value="c3" /> Checkbox 3
		</div>
	</div>
	<div>
		<div class="field"><input type="submit" name="submit" value="Enviar" /></div>
	</div>
</form>

<?php

echo '<pre>';
print_r($_POST);
echo '</pre>';

?>

		</div>
	</body>
</html>

Sesiones

01_session.php
<a href="?incrementar">Incrementar</a>
<a href="?decrementar">Decrementar</a>

<?php

// iniciar sesión
session_start();

// crear variable
if(!isset($_SESSION['contador'])) $_SESSION['contador'] = 0;

// incrementar o decrementar
if(isset($_GET['incrementar'])) ++$_SESSION['contador'];
else if(isset($_GET['decrementar'])) --$_SESSION['contador'];

// mostrar valores del arreglo
echo '<pre>';
print_r($_SESSION);
echo '</pre>';
02_login_logout.php
<?php

// datos de autenticación
define('USER', 'user');
define('PASS', 'pass');

// iniciar la sesión
session_start();

// si se quiere cerrar la sesión se hace
if(isset($_GET['logout'])) {
	$_SESSION = null;
	session_destroy();
	header('location: '.$_SERVER['PHP_SELF']);
}

// si existe un usuario válido se usa
if(!empty($_SESSION['user'])) {
	echo 'welcome: '.$_SESSION['user'],', <a href="?logout">logout</a>';
}
// si no existe usuario se muestra formulario (o procesa si se envio)
else {
	// si el formulario no fue eviado se muestra
	if(!isset($_POST['login'])) {
		echo <<< EOF
<form action="{$_SERVER['PHP_SELF']}" method="post">
	user <input type="text" name="user" />
	pass <input type="password" name="pass" />
	<input type="submit" name="login" value="login" />
</form>
EOF;
	}
	// si el formulario se envio se procesa
	else {
		// verificar que los datos enviados sean correctos
		if($_POST['user']==USER && $_POST['pass']==PASS) {
			// crear info de la sesión
			$_SESSION['user'] = $_POST['user'];
			// redireccionar
			header('location: '.$_SERVER['PHP_SELF']);
		}
		// si los datos no son correctos error
		else {
			echo 'User or pass not valid!';
		}
	}
}

Programación Orientada a Objetos

01_clases.php
<?php

class ClaseNormal {
	public $atributo = 'valor del atributo';
	public function metodo () {
		return $this->atributo;
	}
}

class ClaseEstatica {
	public static $atributo = 'valor del atributo estatico';
	public static function metodo () {
		return self::$atributo;
	}
}

class ClaseMixta {
	public static $atributo = 'valor del atributo clase mixta';
	public function metodo () {
		return self::$atributo;
	}
}

$clasenormal = new ClaseNormal();
echo $clasenormal->metodo(),'<br />';

echo ClaseEstatica::metodo(),'<br />';

$clasemixta = new ClaseMixta();
echo $clasemixta->metodo(),'<br />';
02_new_unset.php
<?php

class Clase {

	public function __construct () {
		echo 'Construyendo objeto<br />';
	}

	public function __destruct () {
		echo 'Destruyendo objeto<br />';
	}
}

$objeto = new Clase();
unset($objeto);
03_herencia.php
<?php

abstract class Persona {

	public $fechanacimiento;

	public function edad () {
		return $this->fechanacimiento;
	}

}

class Personal extends Persona {
}

final class Profesor extends Personal {
}

$profesor = new Profesor();
$profesor->fechanacimiento = '1970-01-01';
echo $profesor->edad();
04_acceso.php
<?php

class Base {
	public $publico = 'atributo publico';
	protected $protegido = 'atributo protegido';
	private $privado = 'atributo privado';
	public function privado() {
		return $this->privado;
	}
}

class Clase extends Base {
	public function protegido() {
		return $this->protegido;
	}
}

$base = new Base();
$clase = new Clase();

echo $base->privado(),'<br />';
echo $clase->publico,'<br />';
echo $clase->protegido(),'<br />';
05_interfaces.php
<?php

// http://php.net/manual/es/language.oop5.interfaces.php

/**
 * Interfaz que define métodos que se deberán implementar en la clase
 * que utilice esta interfaz
 */
interface Interfaz {
	public function metodo1 ();
	public function metodo2 ($parametro1);
	public function metodo3 ($parametro1, $parametro2);
}

/**
 * Clase que implementa la interfaz, deberá declarar los mismos métodos
 * que la interfaz o bien ser declarada como abstracta.
 */
abstract class Abstracta implements Interfaz {
	
}

/**
 * Clase que extiende la abstracta (que implementa interfaz) y declara
 * los métodos
 */
class Objeto extends Abstracta {
	public function metodo1() {}
	public function metodo2($parametro1) {}
	public function metodo3($parametro1, $parametro2) {}
}

/**
 * Clase que implementa la interfaz y directamente declara los métodos
 */
class Objeto2 implements Interfaz {
	public function metodo1() {}
	public function metodo2($parametro1) {}
	public function metodo3($parametro1, $parametro2) {}
}
06_Html.php
<?php

/**
 * Clase utilizada como Helper para escribir código HTML
 */
class Html {

	/**
	 * Método para escribir un enlace
	 * @param link Enlace que al que se desea linkear
	 * @param name Nombre del enlace
	 */
	public static function link ($link, $name = '') {
		if($name=='') $name = $link;
		return '<a href="'.$link.'">'.$name.'</a>';
	}
	
	/**
	 * Método para incluir código javascript
	 * @param uri Ubicación del archivo .js
	 */
	public static function js ($uri) {
		return '<script type="text/javascript" src="'.$uri.'"></script>';
	}
	
	/**
	 * Método para incluir código CSS
	 * @param uri Ubicación del archivo .css
	 */
	public static function css ($uri, $media = 'screen') {
		return '<link rel="stylesheet" type="text/css" href="'.$uri.'" media="'.$media.'"/>';
	}
	
}

// casos de uso
echo Html::link('http://unab.delaf.cl');
echo Html::link('http://unab.delaf.cl', 'UNAB by DeLaF');
07_Form.php
<?php

/**
 * Clase utilizada como Helper para escribir código de formularios
 */
class Form {

	/**
	 * Método para escribir un input de tipo texto
	 * 
	 * El parámetro name puede ser un string o bien un arreglo con los
	 * parámetros necesarios, indices: name, label y value.
	 * @param name Nombre del cuadro de texto
	 * @param label Etiqueta para ser usada junto al cuadro de texto
	 */
	public static function input ($name, $label = '') {
		if(is_array($name)) {
			$arreglo = $name;
			$name = isset($arreglo['name']) ? $arreglo['name'] : '';
			$label = isset($arreglo['label']) ? $arreglo['label'] : '';
			$value = isset($arreglo['value']) ? $arreglo['value'] : '';
		}
		if($label == '') $label = $name;
		$id = $name.'Field';
		return <<< EOF
<div>
	<div class="label"><label for="$id">$label</label></div>
	<div class="field"><input type="text" name="$name" value="$value" id="$id" /></div>
</div>
EOF;
	}
	
}

// casos de uso
echo Form::input('nombre');
echo Form::input('nombre', 'Nombre');
echo Form::input(array('name'=>'nombre', 'value'=>'Esteban'));

Acceso a base de datos

01_conexion.php
<?php

// configuración para la conexión a la base de datos
$config = array(
	'host' => 'localhost',
	'port' => '5432',
	'name' => '',
	'user' => '',
	'pass' => '',
	'char' => 'utf8',
);

// realizar conexión
$connectionId = pg_connect(
	'host='.$config['host'].
	' port='.$config['port'].
	' user='.$config['user'].
	' password='.$config['pass'].
	' dbname='.$config['name'].
	' options=\'--client_encoding='.$config['char'].'\''
) or die('Connection to PostgreSQL failed!');

// dump del id (solo se llega aquí si se hizo la conexión)
var_dump($connectionId);

// cerrar conexión
pg_close($connectionId);
02_consulta.php
<?php

// configuración para la conexión a la base de datos
$config = array(
	'host' => 'localhost',
	'port' => '5432',
	'name' => '',
	'user' => '',
	'pass' => '',
	'char' => 'utf8',
);

// realizar conexión
$connectionId = pg_connect(
	'host='.$config['host'].
	' port='.$config['port'].
	' user='.$config['user'].
	' password='.$config['pass'].
	' dbname='.$config['name'].
	' options=\'--client_encoding='.$config['char'].'\''
) or die('Connection to PostgreSQL failed!');

// realizar consulta
$queryId = pg_query($connectionId, 'SELECT * FROM parametro');

// mostrar datos de la consulta
while($row = pg_fetch_array($queryId, null, PGSQL_ASSOC)) {
	print_r($row); echo '<br />';
}

// liberar datos de la consulta
pg_free_result($queryId);

// cerrar conexión
pg_close($connectionId);
03_usando_poo.php
<?php

// forzar el mostrar errores
ini_set('display_errors', true);

// incluir clase para base de datos
require 'Database.php';

// función para debug
function debug($var) {
	echo '<pre>';
	print_r($var);
	echo '</pre>';
}

// opciones
$config = array(
	'type' => 'PostgreSQL',
	'name' => '',
	'user' => '',
	'pass' => '',
);

// casos de uso
$db = &Database::get('default', $config);
//debug($db->getTableWithColsNames('SELECT * FROM parametro'));
//debug($db->getTable('SELECT * FROM parametro'));
//debug($db->getRow('SELECT * FROM parametro LIMIT 1'));
//debug($db->getCol('SELECT valor FROM parametro'));
//debug($db->getValue('SELECT valor FROM parametro LIMIT 1'));
//$db->toCSV('SELECT * FROM parametro', 'parametros', 'parametro');
//debug($db->exec('edad', '1986-01-02'));
//debug($db->getValueFromSP('edad', '1990-06-27'));
//debug($db->getTableFromSP('getParametros'));
//debug($db->getRowFromSP('getParametros'));
//debug($db->getColFromSP('getParametros'));
//debug($db->getInfoFromTable('parametro'));

// cerrar conexión a la base de datos
Database::close();
03_usando_poo.sql
BEGIN;

-- Parámetros de la aplicación
DROP TABLE IF EXISTS parametro CASCADE;
CREATE TABLE parametro (
  modulo character varying(60) NOT NULL,
  nombre character varying(20) NOT NULL,
  valor character varying(200) NOT NULL DEFAULT ''::character varying,
  audit_programa character varying(20) DEFAULT 'miframework'::character varying NOT NULL,
  audit_usuario character varying(20) DEFAULT 'miframework'::character varying NOT NULL,
  audit_creado timestamp without time zone NOT NULL DEFAULT now(),
  audit_modificado timestamp without time zone NOT NULL DEFAULT now(),
  CONSTRAINT parametro_pkey PRIMARY KEY (modulo, nombre)
);
COMMENT ON TABLE parametro IS 'Parámetros de la aplicación y sus módulos';

-- Procedimiento para agregar un nuevo parametro
CREATE OR REPLACE FUNCTION parametro_agregar (v_modulo character varying, v_nombre character varying, v_valor character varying)
RETURNS boolean AS
$BODY$
BEGIN
  -- Agregar parametro
  INSERT INTO parametro (modulo, nombre, valor) VALUES
    (v_modulo, v_nombre, v_valor);
  -- Retornar que todo ha ido ok
  RETURN true;
END;
$BODY$
LANGUAGE plpgsql;

-- Procedimiento para calcular la edad de "algo" a partir de su fecha
CREATE OR REPLACE FUNCTION edad(v_fecha date)
RETURNS integer AS
$BODY$
BEGIN
  RETURN FLOOR(((DATE_PART('YEAR',CURRENT_DATE)-DATE_PART('YEAR',v_fecha))* 372 + (DATE_PART('MONTH',CURRENT_DATE) - DATE_PART('MONTH',v_fecha))*31 + (DATE_PART('DAY',CURRENT_DATE)-DATE_PART('DAY',v_fecha)))/372);
END
$BODY$
LANGUAGE plpgsql;

-- procedimiento para obtener los parámetros
CREATE OR REPLACE FUNCTION getParametros(c_result refcursor)
RETURNS SETOF refcursor
AS $BODY$
BEGIN
	OPEN c_result FOR SELECT * FROM parametro;
	RETURN NEXT c_result;
END;
$BODY$
LANGUAGE plpgsql;

COMMIT;
Database.php
<?php

/**
 * MiPaGiNa (MP)
 * Copyright (C) 2012 Esteban De La Fuente Rubio (esteban[at]delaf.cl)
 * 
 * Este programa es software libre: usted puede redistribuirlo y/o
 * modificarlo bajo los términos de la Licencia Pública General GNU
 * publicada por la Fundación para el Software Libre, ya sea la versión
 * 3 de la Licencia, o (a su elección) cualquier versión posterior de la
 * misma.
 * 
 * Este programa se distribuye con la esperanza de que sea útil, pero
 * SIN GARANTÍA ALGUNA; ni siquiera la garantía implícita
 * MERCANTIL o de APTITUD PARA UN PROPÓSITO DETERMINADO.
 * Consulte los detalles de la Licencia Pública General GNU para obtener
 * una información más detallada.
 * 
 * Debería haber recibido una copia de la Licencia Pública General GNU
 * junto a este programa.
 * En caso contrario, consulte <http://www.gnu.org/licenses/gpl.html>.
 */

/**
 * Interfaz para las bases de datos
 * 
 * Define métodos públicos que deberán ser implementados
 * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
 * @version 2012-09-09
 */
interface DatabaseInterface {
	// constructor y destructor
	public function __construct($config);
	public function __destruct();
	// obtener atributos de la clase
	public function getConfig();
	public function getId();
	// métodos para hacer consultas "normales"
	public function query($sql);
	public function getTable($sql);
	public function getRow($sql);
	public function getCol($sql);
	public function getValue($sql);
	public function sanitize($string, $trim);
	// métodos para transacciones
	public function transaction();
	public function commit();
	public function rollback();
	// consultas especiales
	public function getTableWithColsNames($sql);
	public function toCSV($sql, $file, $cols);
	// ejecutar procedimientos almacenados
	public function exec($procedure);
	public function getTableFromSP($procedure);
	public function getRowFromSP($procedure);
	public function getColFromSP($procedure);
	public function getValueFromSP($procedure);
	// modificaciones para consultas
	public function setLimit($sql, $records, $offset);
	public function like($col, $value);
	public function concat($par1, $par2);
	// obtener información de la base de datos y tabla
	public function getTables();
	public function getCommentFromTable($table);
	public function getColsFromTable($table);
	public function getPksFromTable($table);
	public function getFksFromTable($table);
	public function getInfoFromTable($table);
}

/**
 * Clase para manejar bases de datos.
 * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
 * @version 2012-09-09
 */
final class Database {

	private static $_databases; ///< Arreglo con las bases de datos que se han cargado

	/**
	 * Método para cargar una base de datos
	 * 
	 * Si la base de datos ya ha sido cargada solo se devolverá. Además
	 * para cargar la base de datos se permite que se pase el nombre de
	 * la base de datos, lo cual la buscará en la lista de base de datos
	 * cargadas o bien un arreglo con la configuración de la base de
	 * datos la cual será utilizada para cargar la base de datos por
	 * primera vez.
	 * @param database La base de datos que se desea cargar,
	 * @return Object Objeto con la base de datos seleccionada
	 * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
	 * @version 2012-09-09
	 */
	public static function &get ($database = 'default', $config = array()) {
		// si $database es un string entonces se asume que se está
		// solicitando una base de datos que ya ha sido cargada, por lo
		// cual se revisa si existe dicho indice, si existe se retorna
		if(is_string($database) && isset($this->_databases[$database])) {
			return $this->_databases[$database];
		}
		// si es un arreglo lo que se paso como $database, es la
		// configuración que se debe utilizar en la configuración
		// si no existe se busca si hay configuración para la base de datos
		else if (is_array($database)) $config = $database;
		// si no se paso configuración se trata de cargar con Configure
		if(!is_array($config) || !isset($config['name'])) {
			// si la clase Configure existe se carga la configuración
			if(is_string($database) && class_exists('Configure')) {
				// se carga
				$config = Configure::read('database.'.$database);
				// si Configure no encontro la configuración se retorna
				// falso
				if(!is_array($config)) return false;
			}
			// si la clase Configure no existe se retorna falso ya que
			// no se logró obtener una configuración válida para la base
			// de datos
			else return false;
		}
		// cargar la clase para la base de datos si no esta cargada
		if(!class_exists($config['type'])) {
			// si existe la clase App se utiliza para cargar la clase
			if(class_exists('App')) {
				App::uses($config['type'], 'Database');
			}
			// si no existe App, se incluye directamente con require
			else {
				require $config['type'].'.php';
			}
		}
		// crear objeto de la base de datos
		$this->_databases[$database] = new $config['type']($config);
		// si hubo algún error mostrar mensaje y terminar script
		if(!$this->_databases[$database]->getId()) {
			$config = $this->_databases[$database]->getConfig();
			echo 'Connection to '.$config['type'].' failed!',"\n",
			'Check configuration for the database ',$config['name'],
			' in server ',$config['host'],':',$config['port'],"\n";
			exit(1);
		}
		// retornar objeto creado si la conexión fue ok
		return $this->_databases[$database];
	}
	
	/**
	 * Cerrar conexiones a las bases de datos
	 * 
	 * Se puede indicar solo una base de datos para cerrar, si no se
	 * hace se cerrarán todas (en realidad se hace unset a la base de
	 * datos, se espera que el destructor de la clase de la base de
	 * datos la cierre). Si no se cierran mediante este método las bases
	 * de datos serán cerradas al finalizar el script.
	 * @param database La base de datos que se desea cerrar
	 * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
	 * @version 2012-09-09
	 */
	 public static function close ($database = '') {
		 // si se especifico una base de datos se cierra solo esa
		 if(!empty($database)) {
			$this->_databases[$database] = null;
			unset($this->_databases[$database]);
		 }
		 // si no se especifico se cierran todas
		 else {
			 $databases = array_keys($this->_databases);
			 foreach($databases as &$database) {
				 $this->_databases[$database] = null;
				 unset($this->_databases[$database]);
			 }
		 }
	 }
	
}
MySQL.php
<?php

/**
 * MiPaGiNa (MP)
 * Copyright (C) 2012 Esteban De La Fuente Rubio (esteban[at]delaf.cl)
 * 
 * Este programa es software libre: usted puede redistribuirlo y/o
 * modificarlo bajo los términos de la Licencia Pública General GNU
 * publicada por la Fundación para el Software Libre, ya sea la versión
 * 3 de la Licencia, o (a su elección) cualquier versión posterior de la
 * misma.
 * 
 * Este programa se distribuye con la esperanza de que sea útil, pero
 * SIN GARANTÍA ALGUNA; ni siquiera la garantía implícita
 * MERCANTIL o de APTITUD PARA UN PROPÓSITO DETERMINADO.
 * Consulte los detalles de la Licencia Pública General GNU para obtener
 * una información más detallada.
 * 
 * Debería haber recibido una copia de la Licencia Pública General GNU
 * junto a este programa.
 * En caso contrario, consulte <http://www.gnu.org/licenses/gpl.html>.
 */

/**
 * Clase para trabajar con una base de datos MySQL
 * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
 * @version 2012-09-09
 */
final class MySQL implements DatabaseInterface {
	
}
Oracle.php
<?php

/**
 * MiPaGiNa (MP)
 * Copyright (C) 2012 Esteban De La Fuente Rubio (esteban[at]delaf.cl)
 * 
 * Este programa es software libre: usted puede redistribuirlo y/o
 * modificarlo bajo los términos de la Licencia Pública General GNU
 * publicada por la Fundación para el Software Libre, ya sea la versión
 * 3 de la Licencia, o (a su elección) cualquier versión posterior de la
 * misma.
 * 
 * Este programa se distribuye con la esperanza de que sea útil, pero
 * SIN GARANTÍA ALGUNA; ni siquiera la garantía implícita
 * MERCANTIL o de APTITUD PARA UN PROPÓSITO DETERMINADO.
 * Consulte los detalles de la Licencia Pública General GNU para obtener
 * una información más detallada.
 * 
 * Debería haber recibido una copia de la Licencia Pública General GNU
 * junto a este programa.
 * En caso contrario, consulte <http://www.gnu.org/licenses/gpl.html>.
 */

/**
 * Clase para trabajar con una base de datos Oracle
 * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
 * @version 2012-09-09
 */
final class Oracle implements DatabaseInterface {
	
}
PostgreSQL.php
<?php

/**
 * MiPaGiNa (MP)
 * Copyright (C) 2012 Esteban De La Fuente Rubio (esteban[at]delaf.cl)
 * 
 * Este programa es software libre: usted puede redistribuirlo y/o
 * modificarlo bajo los términos de la Licencia Pública General GNU
 * publicada por la Fundación para el Software Libre, ya sea la versión
 * 3 de la Licencia, o (a su elección) cualquier versión posterior de la
 * misma.
 * 
 * Este programa se distribuye con la esperanza de que sea útil, pero
 * SIN GARANTÍA ALGUNA; ni siquiera la garantía implícita
 * MERCANTIL o de APTITUD PARA UN PROPÓSITO DETERMINADO.
 * Consulte los detalles de la Licencia Pública General GNU para obtener
 * una información más detallada.
 * 
 * Debería haber recibido una copia de la Licencia Pública General GNU
 * junto a este programa.
 * En caso contrario, consulte <http://www.gnu.org/licenses/gpl.html>.
 */

/**
 * Clase para trabajar con una base de datos PostgreSQL
 * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
 * @version 2012-09-09
 */
final class PostgreSQL implements DatabaseInterface {
	
	private $config; ///< Configuración de la base de datos
	private $id; ///< Identificador de la conexión
	
	/**
	 * Constructor de la clase
	 * 
	 * Realiza conexión a la base de datos, recibe parámetros para la
	 * conexión
	 * @param config Arreglo con los parámetros de la conexión
	 * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
	 * @version 2012-09-09
	 */
	public function __construct ($config) {
		// verificar que existe el soporte para PostgreSQL en PHP
		if (!function_exists('pg_connect')) {
			die('Unable to find the PostgreSQL extension for PHP');
		}
		// definir configuración para el acceso a la base de datos
		$this->config = array_merge(array(
			'host' => 'localhost',
			'port' => '5432',
			'char' => 'utf8',
			'sche' => 'public',
		), $config);
		// realizar conexión a la base de datos
		$this->id = @pg_connect(
			'host='.$this->config['host'].
			' port='.$this->config['port'].
			' user='.$this->config['user'].
			' password='.$this->config['pass'].
			' dbname='.$this->config['name'].
			' options=\'--client_encoding='.$this->config['char'].'\''
		);
		// definir esquema que se utilizará (solo si es diferente a public)
		if ($this->config['sche'] != 'public') {
			$this->query('SET search_path TO '.$this->config['sche']);
		}
	}

	/**
	 * Destructor de la clase
	 * 
	 * Cierra la conexión con la base de datos.
	 * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
	 * @version 2012-09-09
	 */
	public function __destruct () {
		// si el identificador es un recurso de PostgreSQL se cierra
		if(is_resource($this->id) && get_resource_type($this->id)=='pgsql link') {
			pg_close($this->id);
		}
	}
	
	/**
	 * Retorna la configuración de la conexión a la base de datos
	 * @return Array Arreglo con la configuración
	 * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
	 * @version 2012-09-09
	 */
	public function getConfig() {
		return $this->config;
	}
	
	/**
	 * Retorna el identificador de la conexión
	 * @return Resource Identificador de la conexión
	 * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
	 * @version 2012-09-09
	 */
	public function getId() {
		return $this->id;
	}
	
	/**
	 * Realizar consulta en la base de datos
	 * @param sql Consulta SQL que se desea realizar
	 * @return Resource Identificador de la consulta
	 * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
	 * @version 2012-09-09
	 */
	public function query($sql) {
		// verificar que exista una consulta
		if(empty($sql)) {
			echo 'Query can not be empty!',"\n";
			exit(1);
		}
		// realizar consulta
		$queryId = @pg_query($this->id, $sql);
		// si hubo error al realizar la consulta se muestra y termina el
		// script
		if(!$queryId) {
			echo 'SQL: ',$sql,"\n", pg_last_error($this->id), "\n";
			exit(1);
		}
		// retornar identificador de la consulta
		return $queryId;
	}
	
	/**
	 * Obtener una tabla (como arreglo) desde la base de datos
	 * @param sql Consulta SQL que se desea realizar
	 * @return Array Arreglo bidimensional con la tabla y sus datos
	 * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
	 * @version 2012-09-09
	 */
	public function getTable($sql) {
		// realizar consulta
		$queryId = $this->query($sql);
		// procesar resultado de la consulta
		$table = pg_fetch_all($queryId);
		// liberar datos de la consulta
		pg_free_result($queryId);
		// retornar tabla
		return $table;
	}
	
	/**
	 * Obtener una sola fila desde la base de datos
	 * @param sql Consulta SQL que se desea realizar
	 * @return Array Arreglo unidimensional con la fila
	 * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
	 * @version 2012-09-09
	 */
	public function getRow($sql) {
		// realizar consulta
		$queryId = $this->query($sql);
		// procesar resultado de la consulta
		//$row = pg_fetch_array($queryId, null, PGSQL_ASSOC);
		$row = pg_fetch_assoc($queryId);
		// liberar datos de la consulta
		pg_free_result($queryId);
		// retornar fila
		return $row;
	}
	
	/**
	 * Obtener una sola columna desde la base de datos
	 * @param sql Consulta SQL que se desea realizar
	 * @return Array Arreglo unidimensional con la columna
	 * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
	 * @version 2012-09-09
	 */
	public function getCol($sql) {
		// realizar consulta
		$queryId = $this->query($sql);
		// procesar resultado de la consulta
		$col = pg_fetch_all_columns($queryId);
		// liberar datos de la consulta
		pg_free_result($queryId);
		// retornar tabla
		return $col;
	}
	
	/**
	 * Obtener un solo valor desde la base de datos
	 * @param sql Consulta SQL que se desea realizar
	 * @return Mixed Valor devuelto
	 * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
	 * @version 2012-09-09
	 */
	public function getValue($sql) {
		// realizar consulta
		$queryId = $this->query($sql);
		// procesar resultado de la consulta
		$value = pg_fetch_row($queryId);
		// liberar datos de la consulta
		pg_free_result($queryId);
		// retornar tabla
		return is_array($value) ? array_pop($value) : false;
	}
	
	/**
	 * Método que limpia el string recibido para hacer la consulta en la
	 * base de datos de forma segura
	 * @param string String que se desea limpiar
	 * @param trim Indica si se deben o no quitar los espacios
	 * @return String String limpiado
	 * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
	 * @version 2012-09-09
	 */
	public function sanitize($string, $trim = true) {
		// se quitan espacios al inicio y final
		if($trim) $string = trim($string);
		// se proteje
		return pg_escape_string($this->id, $string);
	}

	/**
	 * Iniciar transacción
	 * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
	 * @version 2012-09-09
	 */
	public function transaction () {
		$this->query('BEGIN');
	}
	
	/**
	 * Confirmar transacción
	 * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
	 * @version 2012-09-09
	 */
	public function commit () {
		$this->query('COMMIT');
	}
	
	/**
	 * Cancelar transacción
	 * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
	 * @version 2012-09-09
	 */
	public function rollback () {
		$this->query('ROLLBACK');
	}
	
	/**
	 * Seleccionar una tabla con los nombres de las columnas
	 * @param sql Consulta SQL que se desea realizar
	 * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
	 * @version 2012-09-09
	 */
	public function getTableWithColsNames ($sql) {
		// variables para datos y claves
		$data = array();
		$keys = array();
		// realizar consulta
		$queryId = $this->query($sql);
		// obtener el nombre de las columnas y agregarlas a $data
		$ncolumnas = pg_num_fields($queryId);
		for($i=0; $i<$ncolumnas; ++$i)
			array_push($keys, pg_field_name($queryId, $i));
		array_push($data, $keys);
		unset($keys);
		// agregar las filas de la consulta
		while($rows = pg_fetch_array($queryId)) {
			$row = array();
			for($i=0; $i<$ncolumnas; ++$i) {
				// si es un blob se muestra solo su tipo
				if(preg_match('/blob/i', pg_field_type($queryId, $i)))
					array_push($row, '['.pg_field_type($queryId, $i).']');
				else
					array_push($row, $rows[$i]);
			}
			array_push($data, $row);
		}
		// liberar datos de la consulta
		pg_free_result($queryId);
		// retornar tabla
		return $data;
	}
	
	/**
	 * Exportar una consulta a un archivo CSV y descargar
	 *
	 * La cantidad de campos seleccionados en la query debe ser igual
	 * al largo del arreglo de columnas
	 * @param sql Consulta SQL
	 * @param file Nombre para el archivo que se descargará
	 * @param cols Arreglo con los nombres de las columnas a utilizar en la tabla
	 * @todo Utilizar nombres de columnas y eliminar el archivo generado
	 * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
	 * @version 2012-09-09
	 */
	public function toCSV ($sql, $file, $cols) {
		// definir ruta del archivo
		if(defined('TMP')) $tmp = TMP;
		else if(defined('DIR_TMP')) $tmp = DIR_TMP;
		else $tmp = sys_get_temp_dir();
		$file = $tmp.DIRECTORY_SEPARATOR.$file.'.csv';
		// si no se paso el arreglo con columnas se obtiene
		if(!is_array($cols)) {
			$colsInfo = $this->getColsFromTable($cols);
			$cols = array();
			foreach($colsInfo as &$col)
				$cols[] = $col['name'];
		}
		// realizar consulta
		$this->query("
			COPY (
				-- SELECT '".implode("', '", $cols)."'
				-- UNION
				".$sql."
			) TO '".$file."' CSV
		");
		// enviar archivo
		ob_clean();
		header ('Content-Disposition: attachment; filename='.basename($file));
		header ('Content-Type: text/csv');
		header ('Content-Length: '.filesize($file));
		readfile($file);
		// eliminar archivo (se debe eliminar desde el motor de la base de datos)
		// ?
	}
	
	/**
	 * Ejecutar un procedimiento almacenado
	 * @param procedure Procedimiento almacenado que se quiere ejecutar
	 * @return Mixed Valor que retorna el procedimeinto almacenado
	 * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
	 * @version 2012-09-09
	 */
	public function exec ($procedure) {
		$parameters = func_get_args();
		$procedure = $this->sanitize(array_shift($parameters));
		foreach($parameters as &$parameter) $parameter = $this->sanitize($parameter);
		$parameters = count($parameters) ? "'".implode("', '", $parameters)."'" : '';
		return $this->getValue("SELECT $procedure($parameters)");
	}
	
	/**
	 * Obtener una tabla mediante un procedimiento almacenado
	 * @param procedure Procedimiento almacenado que se desea ejecutar
	 * @return Array Arreglo bidimensional con la tabla y sus datos
	 * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
	 * @version 2012-09-09
	 */
	public function getTableFromSP ($procedure) {
		// recuperar parámetros pasados y extraer procedimiento
		$parameters = func_get_args();
		$procedure = array_shift($parameters);
		// limpiar parametros pasados
		foreach($parameters as &$parameter) $parameter = $this->sanitize($parameter);
		// agregar parámetro para el cursor que se usa para el resultado
		array_unshift($parameters, 'c_result');
		// preparar parámetros
		$parameters = "'".implode("', '", $parameters)."'";
		// realizar consulta
		$queryId = $this->query("BEGIN; SELECT * FROM $procedure($parameters); FETCH ALL FROM c_result;");
		$table = pg_fetch_all($queryId);
		$this->query("END;");
		// liberar datos de la consulta
		pg_free_result($queryId);
		// retornar tabla
		return $table;
	}

	/**
	 * Obtener una sola fila mediante un procedimiento almacenado
	 * @param procedure Procedimiento almacenado que se desea ejecutar
	 * @return Array Arreglo unidimensional con la fila
	 * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
	 * @version 2012-09-09
	 */
	public function getRowFromSP($procedure) {
		// recuperar parámetros pasados y extraer procedimiento
		$parameters = func_get_args();
		$procedure = array_shift($parameters);
		// limpiar parametros pasados
		foreach($parameters as &$parameter) $parameter = $this->sanitize($parameter);
		// agregar parámetro para el cursor que se usa para el resultado
		array_unshift($parameters, 'c_result');
		// preparar parámetros
		$parameters = "'".implode("', '", $parameters)."'";
		// realizar consulta
		$queryId = $this->query("BEGIN; SELECT * FROM $procedure($parameters); FETCH ALL FROM c_result;");
		$row = pg_fetch_assoc($queryId);
		$this->query("END;");
		// liberar datos de la consulta
		pg_free_result($queryId);
		// retornar tabla
		return $row;
	}
	
	/**
	 * Obtener una sola columna mediante un procedimiento almacenado
	 * @param procedure Procedimiento almacenado que se desea ejecutar
	 * @return Array Arreglo unidimensional con la columna
	 * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
	 * @version 2012-09-09
	 */
	public function getColFromSP($procedure) {
		// recuperar parámetros pasados y extraer procedimiento
		$parameters = func_get_args();
		$procedure = array_shift($parameters);
		// limpiar parametros pasados
		foreach($parameters as &$parameter) $parameter = $this->sanitize($parameter);
		// agregar parámetro para el cursor que se usa para el resultado
		array_unshift($parameters, 'c_result');
		// preparar parámetros
		$parameters = "'".implode("', '", $parameters)."'";
		// realizar consulta
		$queryId = $this->query("BEGIN; SELECT * FROM $procedure($parameters); FETCH ALL FROM c_result;");
		$col = pg_fetch_all_columns($queryId);
		$this->query("END;");
		// liberar datos de la consulta
		pg_free_result($queryId);
		// retornar tabla
		return $col;
	}
	
	/**
	 * Obtener un solo valor mediante un procedimiento almacenado
	 * @param procedure Procedimiento almacenado que se desea ejecutar
	 * @return Mixed Valor devuelto por el procedimiento
	 * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
	 * @version 2012-09-09
	 */
	public function getValueFromSP($procedure) {
		return call_user_func_array(array($this, 'exec'), func_get_args());
	}

	/**
	 * Asigna un límite para la obtención de filas en la consulta SQL
	 * @param sql Consulta SQL a la que se le agrega el límite
	 * @return String Consulta con el límite agregado
	 * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
	 * @version 2012-09-09
	 */
	public function setLimit ($sql, $records, $offset = 0) {
		return $sql.' LIMIT '.(integer)$this->sanitize($records).' OFFSET '.(integer)$this->sanitize($offset);
	}

	/**
	 * Genera filtro para utilizar like en la consulta SQL
	 * @param col Columna por la que se filtrará
	 * @param value Valor a buscar mediante like
	 * @return String Filtro utilizando like
	 * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
	 * @version 2012-09-09
	 */
	public function like ($col, $value) {
		return "$col ILIKE '%".$this->sanitize($value)."%'";
	}

	/**
	 * Concatena los parámetros pasados al método
	 * 
	 * El método acepta n parámetros, pero dos como mínimo deben ser
	 * pasados.
	 * @param par1 Parámetro 1 que se quiere concatenar
	 * @param par2 Parámetro 2 que se quiere concatenar
	 * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
	 * @version 2012-09-09
	 */
	public function concat ($par1, $par2) {
		$separators = array(' ', ',', ', ', '-', ' - ', '|');
		$concat = array();
		$parameters = func_get_args();
		foreach($parameters as &$parameter) {
			if(in_array($parameter, $separators))
				$parameter = "'".$parameter."'";
			array_push($concat, $parameter);
		}
		return implode(' || ', $concat);
	}
	
	/**
	 * Listado de tablas de la base de datos
	 * @return Array Arreglo con las tablas (nombre y comentario)
	 * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
	 * @version 2012-09-09
	 */
	public function getTables() {
		// obtener solo tablas del esquema public de la base de datos
		$tables = $this->getTable("
			SELECT t.table_name AS name
			FROM information_schema.tables AS t
			WHERE
				t.table_catalog = '".$this->config['name']."'
				AND t.table_schema = '".$this->config['sche']."'
				AND t.table_type = 'BASE TABLE'
			ORDER BY t.table_name
		");
		// buscar comentarios de las tablas
		foreach($tables as &$table) {
			$table['comment'] = $this->getCommentFromTable($table['name']);
		}
		// retornar tablas
		return $tables;
	}

	/**
	 * Obtener comentario de una tabla
	 * @param table Nombre de la tabla
	 * @return String Comentario de la tabla
	 * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
	 * @version 2012-09-09
	 */
	public function getCommentFromTable ($table) {
		return $this->getValue("
			SELECT d.description
			FROM information_schema.tables AS t, pg_catalog.pg_description AS d, pg_catalog.pg_class AS c
			WHERE
				t.table_catalog = '".$this->config['name']."'
				AND c.relname = '".$table."'
				AND d.objoid = c.oid
				AND d.objsubid = 0
		");
	}
	
	/**
	 * Listado de columnas de una tabla (nombre, tipo, largo máximo, si
	 * puede tener un valor nulo y su valor por defecto)
	 * @param table Tabla a la que se quiere buscar las columnas
	 * @return Array Arreglo con la información de las columnas
	 * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
	 * @version 2012-09-09
	 */
	public function getColsFromTable ($table) {
		// buscar columnas
		$cols = $this->getTable("
			SELECT
				c.column_name AS name
				, data_type as type
				, (CASE (SELECT c.character_maximum_length is null)
					WHEN true THEN c.numeric_precision
					ELSE c.character_maximum_length
				END) AS length
				, c.is_nullable AS null
				, c.column_default AS default
			FROM
				information_schema.columns as c
				, pg_class as t
			WHERE
				c.table_catalog = '".$this->config['name']."'
				AND c.table_name = '".$table."'
				AND t.relname = '".$table."'
			ORDER BY c.ordinal_position ASC
		");
		// buscar comentarios para las columnas
		foreach($cols as &$col) {
			$col['comment'] = $this->getValue("
				SELECT
					d.description
				FROM
					information_schema.columns as c
					, pg_description as d
					, pg_class as t
				WHERE
					c.table_catalog = '".$this->config['name']."'
					AND c.table_name = '".$table."'
					AND c.column_name = '".$col['name']."'
					AND t.relname = '".$table."'
					AND d.objoid = t.oid
					AND d.objsubid = c.ordinal_position
			");
		}
		// retornar columnas
		return $cols;
	}
	
	/**
	 * Listado de claves primarias de una tabla
	 * @param table Tabla a buscar su o sus claves primarias
	 * @return Arreglo con la o las claves primarias
	 * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
	 * @version 2012-09-09
	 */
	public function getPksFromTable ($table) {
		return $this->getCol("
			SELECT column_name
			FROM information_schema.constraint_column_usage
			WHERE constraint_name = (
				SELECT relname
				FROM pg_class
				WHERE oid = (
					SELECT indexrelid
					FROM pg_index, pg_class
					WHERE
						pg_class.relname='".$table."'
						AND pg_class.oid = pg_index.indrelid
						AND indisprimary = 't'
				)
			) AND table_catalog = '".$this->config['name']."' AND table_name = '".$table."'
		");
	}
	
	/**
	 * Listado de claves foráneas de una tabla
	 * @param table Tabla a buscar su o sus claves foráneas
	 * @return Arreglo con la o las claves foráneas
	 * @todo Claves foráneas de múltiples columnas dan problemas
	 * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
	 * @version 2012-09-09
	 */
	public function getFksFromTable ($table) {
		$fks = $this->getTable("
			SELECT
				kcu.column_name AS name
				, ccu.table_name AS table
				, ccu.column_name AS column
			FROM information_schema.constraint_column_usage as ccu, information_schema.key_column_usage as kcu
			WHERE
				ccu.table_catalog = '".$this->config['name']."'
				AND ccu.constraint_name = kcu.constraint_name
				AND ccu.constraint_name IN (
					SELECT constraint_name
					FROM information_schema.table_constraints
					WHERE table_name = '".$table."' AND constraint_type = 'FOREIGN KEY'
				)
		");
		return is_array($fks) ? $fks : array();
	}

	/**
	 * Entrega información de una tabla (nombre, comentario, columnas,
	 * pks y fks)
	 * @param table Tabla a buscar sus datos
	 * @return Arreglo con los datos de la tabla
	 * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
	 * @version 2012-09-09
	 */
	public function getInfoFromTable ($tablename) {
		// nombre de la tabla
		$table['name'] = $tablename;
		// obtener comentario de la tabla
		$table['comment'] = $this->getCommentFromTable($table['name']);
		// obtener pks de la tabla
		$table['pk'] = $this->getPksFromTable($table['name']);
		// obtener fks de la tabla
		$fkAux = $this->getFksFromTable($table['name']);
		$fk = array();
		foreach($fkAux as &$aux) {
			$fk[array_shift($aux)] = $aux;
		}
		unset($fkAux);
		// obtener columnas de la tabla
		$columns = $this->getColsFromTable($table['name']);
		// recorrer columnas para definir pk, fk, auto, null/not null, default, comentario
		foreach($columns as &$column) {
			// definir null o not null
			$column['null'] = $column['null']=='YES' ? true : false;
			// definir si es auto_increment
			$column['auto'] = substr($column['default'], 0, 7)=='nextval' ? true : false;
			// limpiar default, quitar lo que viene despues de ::
			if(!$column['auto']) {
				$aux = explode('::', $column['default']);
				$column['default'] = trim(array_shift($aux), '\'');
				if($column['default']=='NULL') $column['default'] = null;
			}
			// definir fk
			$column['fk'] = array_key_exists($column['name'], $fk) ? $fk[$column['name']] : null;
		}
		$table['columns'] = $columns;
		return $table;	
	}

}
Última modificación de esta página fue el Miércoles 1 de Octubre del 2014 a las 12:36